From 471a9ba4aeb8ad35f729b1932a91086c80e1774c Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Wed, 29 Aug 2018 17:39:04 +1200 Subject: [PATCH 1/8] Treating BitPay address like cashAddr. --- src/js/services/incomingData.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index c7677ed0a..cde485264 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -168,14 +168,21 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS } return true; // Cash URI - } else if (allParsed.isValid && allParsed.publicAddress && allParsed.publicAddress.cashAddr) { + } else if (allParsed.isValid && allParsed.publicAddress && (allParsed.publicAddress.cashAddr || allParsed.publicAddress.bitpay)) { var coin = 'bch'; - - var prefix = allParsed.testnet ? 'bchtest:' : 'bitcoincash:'; - addr = bitcoinCashJsService.readAddress(prefix + allParsed.publicAddress.cashAddr).legacy; - var message = parsed.message; - var amount = parsed.amount ? parsed.amount : ''; + var prefix = allParsed.testnet ? 'bchtest:' : 'bitcoincash:'; + var addrIn = prefix + allParsed.publicAddress.cashAddr; + + if (allParsed.publicAddress.bitpay) { + addrIn = allParsed.publicAddress.bitpay; + originalAddress = allParsed.publicAddress.bitpay; + } + + addr = bitcoinCashJsService.readAddress(addrIn).legacy; + var message = allParsed.message; + + var amount = allParsed.amount ? allParsed.amount : ''; // paypro not yet supported on cash if (allParsed.url) { From 6d48572f28d38dafd72c226c5267d6c28d935af7 Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Wed, 29 Aug 2018 18:27:58 +1200 Subject: [PATCH 2/8] Handling all cash URI addresses formats at the same time. --- src/js/services/incomingData.js | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index cde485264..4c8142681 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -168,16 +168,10 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS } return true; // Cash URI - } else if (allParsed.isValid && allParsed.publicAddress && (allParsed.publicAddress.cashAddr || allParsed.publicAddress.bitpay)) { - var coin = 'bch'; - + } else if (allParsed.isValid && allParsed.coin === 'bch' && allParsed.publicAddress) { var prefix = allParsed.testnet ? 'bchtest:' : 'bitcoincash:'; - var addrIn = prefix + allParsed.publicAddress.cashAddr; - - if (allParsed.publicAddress.bitpay) { - addrIn = allParsed.publicAddress.bitpay; - originalAddress = allParsed.publicAddress.bitpay; - } + var addrIn = allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay || prefix + allParsed.publicAddress.cashAddr; + originalAddress = allParsed.publicAddress.cashAddr ? null : allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay; addr = bitcoinCashJsService.readAddress(addrIn).legacy; var message = allParsed.message; @@ -186,17 +180,17 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS // paypro not yet supported on cash if (allParsed.url) { - payproService.getPayProDetails(allParsed.url, coin, function(err, details) { + payproService.getPayProDetails(allParsed.url, allParsed.coin, function(err, details) { if (err) { if (addr && amount) - goSend(addr, amount, message, coin, serviceId, serviceData); + goSend(addr, amount, message, allParsed.coin, serviceId, serviceData); else popupService.showAlert(gettextCatalog.getString('Error'), err); } - handlePayPro(details, coin); + handlePayPro(details, allParsed.coin); }); } else { - goSend(addr, amount, message, coin, serviceId, serviceData); + goSend(addr, amount, message, allParsed.coin, serviceId, serviceData); } return true; From 529bdf33866aea8ea5beaecfa86153016f678a2e Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Wed, 29 Aug 2018 18:28:37 +1200 Subject: [PATCH 3/8] Alert and resume scanning if data is not recognised. --- i18n/po/template.pot | 8 ++++++++ src/js/controllers/tab-scan.js | 15 +++++++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/i18n/po/template.pot b/i18n/po/template.pot index 9c0e3bdc6..c2208779b 100644 --- a/i18n/po/template.pot +++ b/i18n/po/template.pot @@ -3849,4 +3849,12 @@ msgstr "" #: src/js/services/incomingData.js:129 msgid "This invoice is no longer accepting payments" +msgstr "" + +#: src/js/controllers/tab-scan.js:120 +msgid "Scan Failed" +msgstr "" + +#: src/js/controllers/tab-scan.js:121 +msgid "Data not recognised." msgstr "" \ No newline at end of file diff --git a/src/js/controllers/tab-scan.js b/src/js/controllers/tab-scan.js index 4a654d91d..68e1e4dd0 100644 --- a/src/js/controllers/tab-scan.js +++ b/src/js/controllers/tab-scan.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('tabScanController', function($scope, $log, $timeout, scannerService, incomingData, $state, $ionicHistory, $rootScope, $ionicNavBarDelegate) { +angular.module('copayApp.controllers').controller('tabScanController', function(bitcoinUriService, gettextCatalog, popupService, $scope, $log, $timeout, scannerService, incomingData, $state, $ionicHistory, $rootScope, $ionicNavBarDelegate) { var scannerStates = { unauthorized: 'unauthorized', @@ -111,7 +111,18 @@ angular.module('copayApp.controllers').controller('tabScanController', function( // Sometimes (testing in Chrome, when reading QR Code) data is an object // that has a string data.result. contents = contents.result || contents; - incomingData.redir(contents); + + var parsed = bitcoinUriService.parse(contents); + if (parsed.isValid) { + incomingData.redir(contents); + } else { + var title = gettextCatalog.getString('Scan Failed'); + var msg = gettextCatalog.getString('Data not recognised.'); + var okText = gettextCatalog.getString('OK'); + popupService.showAlert(title, msg, function onAlertShown() { + scannerService.resumePreview(); + }, okText); + } } $rootScope.$on('incomingDataMenu.menuHidden', function() { From e6fba98af99684963f2a50966bc957cb2ecb2ce2 Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Thu, 30 Aug 2018 09:04:01 +1200 Subject: [PATCH 4/8] Not using data if it is for the testnet. --- src/js/controllers/tab-scan.js | 2 +- src/js/services/incomingData.js | 10 +++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/js/controllers/tab-scan.js b/src/js/controllers/tab-scan.js index 68e1e4dd0..e631e5b4f 100644 --- a/src/js/controllers/tab-scan.js +++ b/src/js/controllers/tab-scan.js @@ -113,7 +113,7 @@ angular.module('copayApp.controllers').controller('tabScanController', function( contents = contents.result || contents; var parsed = bitcoinUriService.parse(contents); - if (parsed.isValid) { + if (parsed.isValid && !parsed.testnet) { incomingData.redir(contents); } else { var title = gettextCatalog.getString('Scan Failed'); diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index 4c8142681..6802722ac 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -115,7 +115,7 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS }, 100); } // data extensions for Payment Protocol with non-backwards-compatible request - if (allParsed.isValid && allParsed.coin && allParsed.url) { + if (allParsed.isValid && allParsed.coin && allParsed.url && !allParsed.testnet) { var coin = allParsed.coin; data = allParsed.url; if (allParsed.coin == 'bch') { @@ -168,12 +168,16 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS } return true; // Cash URI - } else if (allParsed.isValid && allParsed.coin === 'bch' && allParsed.publicAddress) { + } else if (allParsed.isValid && allParsed.coin === 'bch' && allParsed.publicAddress && !allParsed.testnet) { var prefix = allParsed.testnet ? 'bchtest:' : 'bitcoincash:'; var addrIn = allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay || prefix + allParsed.publicAddress.cashAddr; originalAddress = allParsed.publicAddress.cashAddr ? null : allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay; - addr = bitcoinCashJsService.readAddress(addrIn).legacy; + var addresses = bitcoinCashJsService.readAddress(addrIn); + if (!addresses) { + return false; + } + addr = addresses.legacy; var message = allParsed.message; var amount = allParsed.amount ? allParsed.amount : ''; From 5747cbfb66c6e4509db5ca3f5ea84f258d0c2c8d Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Thu, 30 Aug 2018 15:49:59 +1200 Subject: [PATCH 5/8] "Testnet not supported" message when scanning a testnet address. --- i18n/po/template.pot | 8 ++++++++ src/js/controllers/tab-scan.js | 21 +++++++++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/i18n/po/template.pot b/i18n/po/template.pot index c2208779b..5483ce40b 100644 --- a/i18n/po/template.pot +++ b/i18n/po/template.pot @@ -3857,4 +3857,12 @@ msgstr "" #: src/js/controllers/tab-scan.js:121 msgid "Data not recognised." +msgstr "" + +#: src/js/controllers/tab-scan.js:121 +msgid "Unsupported" +msgstr "" + +#: src/js/controllers/tab-scan.js:121 +msgid "Testnet is not supported." msgstr "" \ No newline at end of file diff --git a/src/js/controllers/tab-scan.js b/src/js/controllers/tab-scan.js index e631e5b4f..e6f57d0d2 100644 --- a/src/js/controllers/tab-scan.js +++ b/src/js/controllers/tab-scan.js @@ -113,15 +113,24 @@ angular.module('copayApp.controllers').controller('tabScanController', function( contents = contents.result || contents; var parsed = bitcoinUriService.parse(contents); - if (parsed.isValid && !parsed.testnet) { - incomingData.redir(contents); + var title = ''; + var msg = ''; + if (parsed.isValid) { + if (parsed.testnet) { + title = gettextCatalog.getString('Unsupported'); + msg = gettextCatalog.getString('Testnet is not supported.'); + popupService.showAlert(title, msg, function onAlertShown() { + scannerService.resumePreview(); + }); + } else { + incomingData.redir(contents); + } } else { - var title = gettextCatalog.getString('Scan Failed'); - var msg = gettextCatalog.getString('Data not recognised.'); - var okText = gettextCatalog.getString('OK'); + title = gettextCatalog.getString('Scan Failed'); + msg = gettextCatalog.getString('Data not recognised.'); popupService.showAlert(title, msg, function onAlertShown() { scannerService.resumePreview(); - }, okText); + }); } } From 5ad9c7bf493ef8f2d3592bc7622c37bf0192b948 Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Thu, 30 Aug 2018 15:55:29 +1200 Subject: [PATCH 6/8] "Testnet not supported" message when pasting. --- src/js/services/incomingData.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index 6802722ac..1fbdbf71a 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -13,6 +13,14 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS var noPrefixInAddress = 0; var allParsed = bitcoinUriService.parse(data); + if (allParsed.isValid && allParsed.testnet) { + popupService.showAlert( + gettextCatalog.getString('Unsupported'), + gettextCatalog.getString('Testnet is not supported.') + ); + return false; + } + if (data.toLowerCase().indexOf('bitcoin') < 0) { noPrefixInAddress = 1; } From 9877e133905b137e143d9812a0c345a3cef5252d Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Thu, 30 Aug 2018 16:34:21 +1200 Subject: [PATCH 7/8] Corrected the addres for display in the Review screen cashAddr. --- src/js/services/incomingData.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/js/services/incomingData.js b/src/js/services/incomingData.js index 1fbdbf71a..b2e125e48 100644 --- a/src/js/services/incomingData.js +++ b/src/js/services/incomingData.js @@ -179,7 +179,7 @@ angular.module('copayApp.services').factory('incomingData', function(bitcoinUriS } else if (allParsed.isValid && allParsed.coin === 'bch' && allParsed.publicAddress && !allParsed.testnet) { var prefix = allParsed.testnet ? 'bchtest:' : 'bitcoincash:'; var addrIn = allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay || prefix + allParsed.publicAddress.cashAddr; - originalAddress = allParsed.publicAddress.cashAddr ? null : allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay; + originalAddress = allParsed.publicAddress.cashAddr || allParsed.publicAddress.legacy || allParsed.publicAddress.bitpay; var addresses = bitcoinCashJsService.readAddress(addrIn); if (!addresses) { From 986f85e7aaa576f78849e318c16da666175bf06f Mon Sep 17 00:00:00 2001 From: Brendon Duncan Date: Thu, 30 Aug 2018 17:18:26 +1200 Subject: [PATCH 8/8] The send tab paste button now recognises a wider variety of Bitcoin Cash prefixes. --- src/js/controllers/tab-send.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/js/controllers/tab-send.js b/src/js/controllers/tab-send.js index 9ac6c35cb..eba744560 100644 --- a/src/js/controllers/tab-send.js +++ b/src/js/controllers/tab-send.js @@ -1,6 +1,6 @@ 'use strict'; -angular.module('copayApp.controllers').controller('tabSendController', function($scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, sendFlowService, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) { +angular.module('copayApp.controllers').controller('tabSendController', function(bitcoinUriService, $scope, $rootScope, $log, $timeout, $ionicScrollDelegate, $ionicLoading, addressbookService, profileService, lodash, $state, walletService, incomingData, popupService, platformInfo, sendFlowService, bwcError, gettextCatalog, scannerService, configService, bitcoinCashJsService, $ionicPopup, $ionicNavBarDelegate, clipboardService) { var clipboardHasAddress = false; var clipboardHasContent = false; var originalList; @@ -39,7 +39,9 @@ angular.module('copayApp.controllers').controller('tabSendController', function( $scope.clipboardHasAddress = false; $scope.clipboardHasContent = false; - if ((text.indexOf('bitcoincash:') === 0 || text[0] === 'C' || text[0] === 'H' || text[0] === 'p' || text[0] === 'q') && text.replace('bitcoincash:', '').length === 42) { // CashAddr + var parsed = bitcoinUriService.parse(text); + console.log('parsed', parsed); + if (parsed.isValid && parsed.publicAddress && parsed.coin === 'bch' && !parsed.testnet) { // CashAddr $scope.clipboardHasAddress = true; } else if ((text[0] === "1" || text[0] === "3" || text.substring(0, 3) === "bc1") && text.length >= 26 && text.length <= 35) { // Legacy Addresses $scope.clipboardHasAddress = true;