diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -285,7 +285,7 @@ tr("&Receive"), this); receiveCoinsAction->setStatusTip( tr("Request payments (generates QR codes and %1: URIs)") - .arg(GUIUtil::URI_SCHEME)); + .arg(GUIUtil::bitcoinURIScheme(*cfg))); receiveCoinsAction->setToolTip(receiveCoinsAction->statusTip()); receiveCoinsAction->setCheckable(true); receiveCoinsAction->setShortcut(QKeySequence(Qt::ALT + Qt::Key_3)); @@ -410,8 +410,8 @@ openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this); - openAction->setStatusTip( - tr("Open a %1: URI or payment request").arg(GUIUtil::URI_SCHEME)); + openAction->setStatusTip(tr("Open a %1: URI or payment request") + .arg(GUIUtil::bitcoinURIScheme(*cfg))); showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), diff --git a/src/qt/guiutil.h b/src/qt/guiutil.h --- a/src/qt/guiutil.h +++ b/src/qt/guiutil.h @@ -35,7 +35,6 @@ /** Utility functions used by the Bitcoin Qt UI. */ namespace GUIUtil { -extern const QString URI_SCHEME; // Create human-readable string from date QString dateTimeStr(const QDateTime &datetime); @@ -51,6 +50,8 @@ void setupAddressWidget(QValidatedLineEdit *widget, QWidget *parent); void setupAmountWidget(QLineEdit *widget, QWidget *parent); +QString bitcoinURIScheme(const CChainParams &, bool useCashAddr); +QString bitcoinURIScheme(const Config &); // Parse "bitcoincash:" URI into recipient object, return true on successful // parsing bool parseBitcoinURI(const QString &scheme, const QUrl &uri, diff --git a/src/qt/guiutil.cpp b/src/qt/guiutil.cpp --- a/src/qt/guiutil.cpp +++ b/src/qt/guiutil.cpp @@ -91,7 +91,6 @@ #endif namespace GUIUtil { -const QString URI_SCHEME("bitcoincash"); QString dateTimeStr(const QDateTime &date) { return date.date().toString(Qt::SystemLocaleShortDate) + QString(" ") + @@ -166,6 +165,17 @@ widget->setAlignment(Qt::AlignRight | Qt::AlignVCenter); } +QString bitcoinURIScheme(const CChainParams ¶ms, bool useCashAddr) { + if (!useCashAddr) { + return "bitcoincash"; + } + return QString::fromStdString(params.CashAddrPrefix()); +} + +QString bitcoinURIScheme(const Config &cfg) { + return bitcoinURIScheme(cfg.GetChainParams(), cfg.UseCashAddrEncoding()); +} + static bool IsCashAddrEncoded(const QUrl &uri) { const std::string addr = (uri.scheme() + ":" + uri.path()).toStdString(); auto decoded = cashaddr::Decode(addr); @@ -250,7 +260,7 @@ QString ret = info.address; if (!cfg.UseCashAddrEncoding()) { // prefix address with uri scheme for base58 encoded addresses. - ret = (URI_SCHEME + ":%1").arg(ret); + ret = (bitcoinURIScheme(cfg) + ":%1").arg(ret); } int paramCount = 0; diff --git a/src/qt/openuridialog.cpp b/src/qt/openuridialog.cpp --- a/src/qt/openuridialog.cpp +++ b/src/qt/openuridialog.cpp @@ -14,7 +14,7 @@ : QDialog(parent), ui(new Ui::OpenURIDialog), cfg(cfg) { ui->setupUi(this); #if QT_VERSION >= 0x040700 - ui->uriEdit->setPlaceholderText(GUIUtil::URI_SCHEME + ":"); + ui->uriEdit->setPlaceholderText(GUIUtil::bitcoinURIScheme(*cfg) + ":"); #endif } @@ -28,7 +28,8 @@ void OpenURIDialog::accept() { SendCoinsRecipient rcp; - if (GUIUtil::parseBitcoinURI(GUIUtil::URI_SCHEME, getURI(), &rcp)) { + QString uriScheme = GUIUtil::bitcoinURIScheme(*cfg); + if (GUIUtil::parseBitcoinURI(uriScheme, getURI(), &rcp)) { /* Only accept value URIs */ QDialog::accept(); } else { @@ -41,6 +42,6 @@ this, tr("Select payment request file to open"), "", "", nullptr); if (filename.isEmpty()) return; QUrl fileUri = QUrl::fromLocalFile(filename); - ui->uriEdit->setText(GUIUtil::URI_SCHEME + ":?r=" + + ui->uriEdit->setText(GUIUtil::bitcoinURIScheme(*cfg) + ":?r=" + QUrl::toPercentEncoding(fileUri.toString())); } diff --git a/src/qt/paymentserver.cpp b/src/qt/paymentserver.cpp --- a/src/qt/paymentserver.cpp +++ b/src/qt/paymentserver.cpp @@ -9,6 +9,7 @@ #include "optionsmodel.h" #include "chainparams.h" +#include "config.h" #include "dstencode.h" #include "policy/policy.h" #include "ui_interface.h" @@ -211,18 +212,19 @@ QString arg(argv[i]); if (arg.startsWith("-")) continue; + QString scheme = GUIUtil::bitcoinURIScheme(Params(), false); // If the bitcoincash: URI contains a payment request, we are not able // to detect the network as that would require fetching and parsing the // payment request. That means clicking such an URI which contains a // testnet payment request will start a mainnet instance and throw a // "wrong network" error. - if (arg.startsWith(GUIUtil::URI_SCHEME + ":", + if (arg.startsWith(scheme + ":", Qt::CaseInsensitive)) // bitcoincash: URI { savedPaymentRequests.append(arg); SendCoinsRecipient r; - if (GUIUtil::parseBitcoinURI(GUIUtil::URI_SCHEME, arg, &r) && + if (GUIUtil::parseBitcoinURI(scheme, arg, &r) && !r.address.isEmpty()) { if (IsValidDestinationString(r.address.toStdString(), Params(CBaseChainParams::MAIN))) { @@ -314,8 +316,7 @@ // constructor is called early in init, so don't use "Q_EMIT // message()" here QMessageBox::critical(0, tr("Payment request error"), - tr("Cannot start %1: click-to-pay handler") - .arg(GUIUtil::URI_SCHEME)); + tr("Cannot start click-to-pay handler")); } else { connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection())); @@ -391,7 +392,8 @@ } // bitcoincash: URI - if (s.startsWith(GUIUtil::URI_SCHEME + ":", Qt::CaseInsensitive)) { + QString scheme = GUIUtil::bitcoinURIScheme(Params(), false); + if (s.startsWith(scheme + ":", Qt::CaseInsensitive)) { #if QT_VERSION < 0x050000 QUrl uri(s); #else @@ -421,7 +423,7 @@ } else { // normal URI SendCoinsRecipient recipient; - if (GUIUtil::parseBitcoinURI(GUIUtil::URI_SCHEME, s, &recipient)) { + if (GUIUtil::parseBitcoinURI(scheme, s, &recipient)) { if (!IsValidDestinationString( recipient.address.toStdString())) { Q_EMIT message( diff --git a/src/qt/sendcoinsentry.cpp b/src/qt/sendcoinsentry.cpp --- a/src/qt/sendcoinsentry.cpp +++ b/src/qt/sendcoinsentry.cpp @@ -7,6 +7,7 @@ #include "addressbookpage.h" #include "addresstablemodel.h" +#include "config.h" #include "guiutil.h" #include "optionsmodel.h" #include "platformstyle.h" @@ -35,7 +36,7 @@ tr("A message that was attached to the %1 URI which will be" " stored with the transaction for your reference. Note: " "This message will not be sent over the Bitcoin network.") - .arg(GUIUtil::URI_SCHEME)); + .arg(GUIUtil::bitcoinURIScheme(GetConfig()))); setCurrentWidget(ui->SendCoins); diff --git a/src/qt/test/uritests.h b/src/qt/test/uritests.h --- a/src/qt/test/uritests.h +++ b/src/qt/test/uritests.h @@ -15,6 +15,7 @@ void uriTestsBase58(); void uriTestsCashAddr(); void uriTestFormatURI(); + void uriTestScheme(); }; #endif // BITCOIN_QT_TEST_URITESTS_H diff --git a/src/qt/test/uritests.cpp b/src/qt/test/uritests.cpp --- a/src/qt/test/uritests.cpp +++ b/src/qt/test/uritests.cpp @@ -173,11 +173,15 @@ namespace { class UriTestConfig : public DummyConfig { public: - UriTestConfig(bool useCashAddr) : useCashAddr(useCashAddr) {} + UriTestConfig(bool useCashAddr) + : useCashAddr(useCashAddr), net(CBaseChainParams::MAIN) {} bool UseCashAddrEncoding() const override { return useCashAddr; } + const CChainParams &GetChainParams() const override { return Params(net); } + void SetChainParams(const std::string &n) { net = n; } private: bool useCashAddr; + std::string net; }; } // anon ns @@ -203,3 +207,26 @@ "bitcoincash:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W?message=test"); } } + +void URITests::uriTestScheme() { + { + // cashaddr - scheme depends on selected chain params + UriTestConfig config(true); + config.SetChainParams(CBaseChainParams::MAIN); + QVERIFY("bitcoincash" == GUIUtil::bitcoinURIScheme(config)); + config.SetChainParams(CBaseChainParams::TESTNET); + QVERIFY("bchtest" == GUIUtil::bitcoinURIScheme(config)); + config.SetChainParams(CBaseChainParams::REGTEST); + QVERIFY("bchreg" == GUIUtil::bitcoinURIScheme(config)); + } + { + // legacy - scheme is "bitcoincash" regardless of chain params + UriTestConfig config(false); + config.SetChainParams(CBaseChainParams::MAIN); + QVERIFY("bitcoincash" == GUIUtil::bitcoinURIScheme(config)); + config.SetChainParams(CBaseChainParams::TESTNET); + QVERIFY("bitcoincash" == GUIUtil::bitcoinURIScheme(config)); + config.SetChainParams(CBaseChainParams::REGTEST); + QVERIFY("bitcoincash" == GUIUtil::bitcoinURIScheme(config)); + } +}