Changeset View
Changeset View
Standalone View
Standalone View
src/qt/paymentserver.cpp
Show First 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | #endif | ||||
// Issues to consider: | // Issues to consider: | ||||
// performance (start a thread to fetch in background?) | // performance (start a thread to fetch in background?) | ||||
// privacy (fetch through tor/proxy so IP address isn't revealed) | // privacy (fetch through tor/proxy so IP address isn't revealed) | ||||
// would it be easier to just use a compiled-in blacklist? | // would it be easier to just use a compiled-in blacklist? | ||||
// or use Qt's blacklist? | // or use Qt's blacklist? | ||||
// "certificate stapling" with server-side caching is more efficient | // "certificate stapling" with server-side caching is more efficient | ||||
} | } | ||||
static bool ipcParseURI(const QString &arg) { | |||||
deadalnix: remove | |||||
std::vector<std::string> networks = {CBaseChainParams::MAIN, | |||||
CBaseChainParams::TESTNET, | |||||
CBaseChainParams::REGTEST}; | |||||
for (std::string net : networks) { | |||||
const QString scheme = | |||||
QString::fromStdString(Params(net).CashAddrPrefix()); | |||||
deadalnixAuthorUnsubmitted Not Done Inline ActionsYou have created an helper function to do this. deadalnix: You have created an helper function to do this. | |||||
dagurvalUnsubmitted Not Done Inline ActionsThe helper function requires a config object, which we don't have. The alternative is to create a dummy config object. dagurval: The helper function requires a config object, which we don't have. The alternative is to create… | |||||
if (arg.startsWith(scheme + ":", Qt::CaseInsensitive)) { | |||||
savedPaymentRequests.append(arg); | |||||
SelectParams(net); | |||||
return true; | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
// | // | ||||
// Sending to the server is done synchronously, at startup. | // Sending to the server is done synchronously, at startup. | ||||
// If the server isn't already running, startup continues, and the items in | // If the server isn't already running, startup continues, and the items in | ||||
// savedPaymentRequest will be handled when uiReady() is called. | // savedPaymentRequest will be handled when uiReady() is called. | ||||
// | // | ||||
// Warning: ipcSendCommandLine() is called early in init, so don't use "Q_EMIT | // Warning: ipcSendCommandLine() is called early in init, so don't use "Q_EMIT | ||||
// message()", but "QMessageBox::"! | // message()", but "QMessageBox::"! | ||||
// | // | ||||
void PaymentServer::ipcParseCommandLine(int argc, char *argv[]) { | void PaymentServer::ipcParseCommandLine(int argc, char *argv[]) { | ||||
for (int i = 1; i < argc; i++) { | for (int i = 1; i < argc; i++) { | ||||
QString arg(argv[i]); | QString arg(argv[i]); | ||||
if (arg.startsWith("-")) continue; | if (arg.startsWith("-")) continue; | ||||
// If the bitcoincash: URI contains a payment request, we are not able | if (ipcParseURI(arg)) { | ||||
deadalnixAuthorUnsubmitted Not Done Inline ActionsThis is not. deadalnix: This is not. | |||||
// to detect the network as that would require fetching and parsing the | continue; | ||||
// 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 + ":", | |||||
Qt::CaseInsensitive)) // bitcoincash: URI | |||||
{ | |||||
savedPaymentRequests.append(arg); | |||||
SendCoinsRecipient r; | |||||
if (GUIUtil::parseBitcoinURI(arg, &r) && !r.address.isEmpty()) { | |||||
if (IsValidDestinationString(r.address.toStdString(), | |||||
deadalnixAuthorUnsubmitted Not Done Inline ActionsThis is validating that it is a valid destination. deadalnix: This is validating that it is a valid destination. | |||||
dagurvalUnsubmitted Not Done Inline ActionsMy interpretation of this code is that it's a hack to check if it's a mainnet address or a testnet address. Validation is a side effect of that. We can do that now by looking at the URI scheme. Validation is done in handleURIOrFile. I can add validation though before using the chain params. dagurval: My interpretation of this code is that it's a hack to check if it's a mainnet address or a… | |||||
Params(CBaseChainParams::MAIN))) { | |||||
SelectParams(CBaseChainParams::MAIN); | |||||
} else if (IsValidDestinationString( | |||||
r.address.toStdString(), | |||||
Params(CBaseChainParams::TESTNET))) { | |||||
SelectParams(CBaseChainParams::TESTNET); | |||||
} | |||||
} | } | ||||
} else if (QFile::exists(arg)) { | |||||
if (QFile::exists(arg)) { | |||||
// Filename | // Filename | ||||
savedPaymentRequests.append(arg); | savedPaymentRequests.append(arg); | ||||
PaymentRequestPlus request; | PaymentRequestPlus request; | ||||
if (readPaymentRequestFromFile(arg, request)) { | if (readPaymentRequestFromFile(arg, request)) { | ||||
if (request.getDetails().network() == "main") { | if (request.getDetails().network() == "main") { | ||||
SelectParams(CBaseChainParams::MAIN); | SelectParams(CBaseChainParams::MAIN); | ||||
} else if (request.getDetails().network() == "test") { | } else if (request.getDetails().network() == "test") { | ||||
▲ Show 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | PaymentServer::PaymentServer(QObject *parent, bool startLocalServer) | ||||
if (startLocalServer) { | if (startLocalServer) { | ||||
uriServer = new QLocalServer(this); | uriServer = new QLocalServer(this); | ||||
if (!uriServer->listen(name)) { | if (!uriServer->listen(name)) { | ||||
// constructor is called early in init, so don't use "Q_EMIT | // constructor is called early in init, so don't use "Q_EMIT | ||||
// message()" here | // message()" here | ||||
QMessageBox::critical(0, tr("Payment request error"), | QMessageBox::critical(0, tr("Payment request error"), | ||||
tr("Cannot start %1: click-to-pay handler") | tr("Cannot start click-to-pay handler")); | ||||
.arg(GUIUtil::URI_SCHEME)); | |||||
} else { | } else { | ||||
connect(uriServer, SIGNAL(newConnection()), this, | connect(uriServer, SIGNAL(newConnection()), this, | ||||
SLOT(handleURIConnection())); | SLOT(handleURIConnection())); | ||||
connect(this, SIGNAL(receivedPaymentACK(QString)), this, | connect(this, SIGNAL(receivedPaymentACK(QString)), this, | ||||
SLOT(handlePaymentACK(QString))); | SLOT(handlePaymentACK(QString))); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
void PaymentServer::handleURIOrFile(const QString &s) { | void PaymentServer::handleURIOrFile(const QString &s) { | ||||
if (saveURIs) { | if (saveURIs) { | ||||
savedPaymentRequests.append(s); | savedPaymentRequests.append(s); | ||||
return; | return; | ||||
} | } | ||||
// bitcoincash: URI | // URI | ||||
if (s.startsWith(GUIUtil::URI_SCHEME + ":", Qt::CaseInsensitive)) { | const QString uriScheme = QString::fromStdString(Params().CashAddrPrefix()); | ||||
deadalnixAuthorUnsubmitted Not Done Inline ActionsYou have an helper function for this one as well. deadalnix: You have an helper function for this one as well. | |||||
dagurvalUnsubmitted Not Done Inline ActionsHard to tell if the GetConfig() object is ready here (or will be after some change in the future). dagurval: Hard to tell if the GetConfig() object is ready here (or will be after some change in the… | |||||
if (s.startsWith(uriScheme + ":", Qt::CaseInsensitive)) { | |||||
#if QT_VERSION < 0x050000 | #if QT_VERSION < 0x050000 | ||||
QUrl uri(s); | QUrl uri(s); | ||||
#else | #else | ||||
QUrlQuery uri((QUrl(s))); | QUrlQuery uri((QUrl(s))); | ||||
#endif | #endif | ||||
if (uri.hasQueryItem("r")) { | if (uri.hasQueryItem("r")) { | ||||
// payment request URI | // payment request URI | ||||
QByteArray temp; | QByteArray temp; | ||||
Show All 13 Lines | #endif | ||||
.arg(fetchUrl.toString()), | .arg(fetchUrl.toString()), | ||||
CClientUIInterface::ICON_WARNING); | CClientUIInterface::ICON_WARNING); | ||||
} | } | ||||
return; | return; | ||||
} else { | } else { | ||||
// normal URI | // normal URI | ||||
SendCoinsRecipient recipient; | SendCoinsRecipient recipient; | ||||
if (GUIUtil::parseBitcoinURI(s, &recipient)) { | if (GUIUtil::parseBitcoinURI(uriScheme, s, &recipient)) { | ||||
if (!IsValidDestinationString( | if (!IsValidDestinationString( | ||||
recipient.address.toStdString())) { | recipient.address.toStdString())) { | ||||
Q_EMIT message( | Q_EMIT message( | ||||
tr("URI handling"), | tr("URI handling"), | ||||
tr("Invalid payment address %1").arg(recipient.address), | tr("Invalid payment address %1").arg(recipient.address), | ||||
CClientUIInterface::MSG_ERROR); | CClientUIInterface::MSG_ERROR); | ||||
} else | } else | ||||
Q_EMIT receivedPaymentRequest(recipient); | Q_EMIT receivedPaymentRequest(recipient); | ||||
▲ Show 20 Lines • Show All 387 Lines • Show Last 20 Lines |
remove