Merge pull request #560 from rnicoll/1.7.2-dev-payment
Re-enable payment protocol
This commit is contained in:
commit
e3eeb47d1d
|
@ -173,7 +173,7 @@ public:
|
|||
|
||||
#ifdef ENABLE_WALLET
|
||||
/// Create payment server
|
||||
// void createPaymentServer();
|
||||
void createPaymentServer();
|
||||
#endif
|
||||
/// Create options model
|
||||
void createOptionsModel();
|
||||
|
@ -212,7 +212,7 @@ private:
|
|||
BitcoinGUI *window;
|
||||
QTimer *pollShutdownTimer;
|
||||
#ifdef ENABLE_WALLET
|
||||
// PaymentServer* paymentServer;
|
||||
PaymentServer* paymentServer;
|
||||
WalletModel *walletModel;
|
||||
#endif
|
||||
int returnValue;
|
||||
|
@ -279,7 +279,7 @@ BitcoinApplication::BitcoinApplication(int &argc, char **argv):
|
|||
window(0),
|
||||
pollShutdownTimer(0),
|
||||
#ifdef ENABLE_WALLET
|
||||
// paymentServer(0),
|
||||
paymentServer(0),
|
||||
walletModel(0),
|
||||
#endif
|
||||
returnValue(0)
|
||||
|
@ -298,20 +298,18 @@ BitcoinApplication::~BitcoinApplication()
|
|||
delete window;
|
||||
window = 0;
|
||||
#ifdef ENABLE_WALLET
|
||||
// delete paymentServer;
|
||||
// paymentServer = 0;
|
||||
delete paymentServer;
|
||||
paymentServer = 0;
|
||||
#endif
|
||||
delete optionsModel;
|
||||
optionsModel = 0;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
/*
|
||||
void BitcoinApplication::createPaymentServer()
|
||||
{
|
||||
paymentServer = new PaymentServer(this);
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
|
||||
void BitcoinApplication::createOptionsModel()
|
||||
|
@ -394,12 +392,10 @@ void BitcoinApplication::initializeResult(int retval)
|
|||
returnValue = retval ? 0 : 1;
|
||||
if(retval)
|
||||
{
|
||||
/*
|
||||
#ifdef ENABLE_WALLET
|
||||
PaymentServer::LoadRootCAs();
|
||||
paymentServer->setOptionsModel(optionsModel);
|
||||
#endif
|
||||
*/
|
||||
|
||||
emit splashFinished(window);
|
||||
|
||||
|
@ -414,10 +410,8 @@ void BitcoinApplication::initializeResult(int retval)
|
|||
window->addWallet("~Default", walletModel);
|
||||
window->setCurrentWallet("~Default");
|
||||
|
||||
/*
|
||||
connect(walletModel, SIGNAL(coinsSent(CWallet*,SendCoinsRecipient,QByteArray)),
|
||||
paymentServer, SLOT(fetchPaymentACK(CWallet*,const SendCoinsRecipient&,QByteArray)));
|
||||
*/
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -431,11 +425,8 @@ void BitcoinApplication::initializeResult(int retval)
|
|||
window->show();
|
||||
}
|
||||
#ifdef ENABLE_WALLET
|
||||
// Payment server disabled pending future work on specifications
|
||||
|
||||
// Now that initialization/startup is done, process any command-line
|
||||
// dogecoin: URIs or payment requests:
|
||||
/*
|
||||
connect(paymentServer, SIGNAL(receivedPaymentRequest(SendCoinsRecipient)),
|
||||
window, SLOT(handlePaymentRequest(SendCoinsRecipient)));
|
||||
connect(window, SIGNAL(receivedURI(QString)),
|
||||
|
@ -443,7 +434,6 @@ void BitcoinApplication::initializeResult(int retval)
|
|||
connect(paymentServer, SIGNAL(message(QString,QString,unsigned int)),
|
||||
window, SLOT(message(QString,QString,unsigned int)));
|
||||
QTimer::singleShot(100, paymentServer, SLOT(uiReady()));
|
||||
*/
|
||||
#endif
|
||||
} else {
|
||||
quit(); // Exit main loop
|
||||
|
@ -578,7 +568,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
// Start up the payment server early, too, so impatient users that click on
|
||||
// dogecoin: links repeatedly have their payment requests routed to this process:
|
||||
// app.createPaymentServer();
|
||||
app.createPaymentServer();
|
||||
#endif
|
||||
|
||||
/// 9. Main GUI initialization
|
||||
|
|
|
@ -1,22 +1,23 @@
|
|||
//
|
||||
// Simple Bitcoin Payment Protocol messages
|
||||
// Simple Dogecoin Payment Protocol messages
|
||||
// Derived fromthe Bitcoin Payment Protocol
|
||||
//
|
||||
// Use fields 100+ for extensions;
|
||||
// to avoid conflicts, register extensions at:
|
||||
// https://en.bitcoin.it/wiki/Payment_Request
|
||||
// to avoid conflicts, register extensions via pull-req at:
|
||||
// https://github.com/dogecoin/dips
|
||||
//
|
||||
|
||||
package payments;
|
||||
option java_package = "org.bitcoin.protocols.payments";
|
||||
option java_package = "com.dogecoin.protocols.payments";
|
||||
option java_outer_classname = "Protos";
|
||||
|
||||
// Generalized form of "send payment to this/these bitcoin addresses"
|
||||
// Generalized form of "send payment to this/these dogecoin addresses"
|
||||
message Output {
|
||||
optional uint64 amount = 1 [default = 0]; // amount is integer-number-of-satoshis
|
||||
required bytes script = 2; // usually one of the standard Script forms
|
||||
optional uint64 amount = 1 [default = 0]; // amount is integer-number-of-satoshis
|
||||
required bytes script = 2; // usually one of the standard Script forms
|
||||
}
|
||||
message PaymentDetails {
|
||||
optional string network = 1 [default = "main"]; // "main" or "test"
|
||||
optional string genesis = 1 [default = "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691"]; // Hash of the network genesis block
|
||||
repeated Output outputs = 2; // Where payment should be sent
|
||||
required uint64 time = 3; // Timestamp; when payment request created
|
||||
optional uint64 expires = 4; // Timestamp; when this request should be considered invalid
|
||||
|
|
|
@ -178,6 +178,9 @@ void PaymentServer::LoadRootCAs(X509_STORE* _store)
|
|||
// and the items in savedPaymentRequest will be handled
|
||||
// when uiReady() is called.
|
||||
//
|
||||
// Warning: ipcSendCommandLine() is called early in init,
|
||||
// so don't use "emit message()", but "QMessageBox::"!
|
||||
//
|
||||
bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
||||
{
|
||||
for (int i = 1; i < argc; i++)
|
||||
|
@ -205,14 +208,19 @@ bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
|
|||
else if (QFile::exists(arg)) // Filename
|
||||
{
|
||||
savedPaymentRequests.append(arg);
|
||||
|
||||
|
||||
PaymentRequestPlus request;
|
||||
|
||||
if (readPaymentRequest(arg, request))
|
||||
{
|
||||
if (request.getDetails().network() == "main")
|
||||
if (request.getDetails().genesis() == "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691")
|
||||
{
|
||||
SelectParams(CChainParams::MAIN);
|
||||
else
|
||||
}
|
||||
else if (request.getDetails().genesis() == "bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e")
|
||||
{
|
||||
SelectParams(CChainParams::TESTNET);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -411,7 +419,15 @@ void PaymentServer::handleURIOrFile(const QString& s)
|
|||
{
|
||||
SendCoinsRecipient recipient;
|
||||
if (GUIUtil::parseBitcoinURI(s, &recipient))
|
||||
emit receivedPaymentRequest(recipient);
|
||||
{
|
||||
CBitcoinAddress address(recipient.address.toStdString());
|
||||
if (!address.IsValid()) {
|
||||
emit message(tr("URI handling"), tr("Invalid payment address %1").arg(recipient.address),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
}
|
||||
else
|
||||
emit receivedPaymentRequest(recipient);
|
||||
}
|
||||
else
|
||||
emit message(tr("URI handling"),
|
||||
tr("URI can not be parsed! This can be caused by an invalid Dogecoin address or malformed URI parameters."),
|
||||
|
@ -425,12 +441,14 @@ void PaymentServer::handleURIOrFile(const QString& s)
|
|||
{
|
||||
PaymentRequestPlus request;
|
||||
SendCoinsRecipient recipient;
|
||||
if (readPaymentRequest(s, request) && processPaymentRequest(request, recipient))
|
||||
emit receivedPaymentRequest(recipient);
|
||||
else
|
||||
if (!readPaymentRequest(s, request))
|
||||
{
|
||||
emit message(tr("Payment request file handling"),
|
||||
tr("Payment request file can not be read or processed! This can be caused by an invalid payment request file."),
|
||||
tr("Payment request file can not be read! This can be caused by an invalid payment request file."),
|
||||
CClientUIInterface::ICON_WARNING);
|
||||
}
|
||||
else if (processPaymentRequest(request, recipient))
|
||||
emit receivedPaymentRequest(recipient);
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -482,6 +500,35 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
|||
if (!optionsModel)
|
||||
return false;
|
||||
|
||||
if (request.IsInitialized()) {
|
||||
const payments::PaymentDetails& details = request.getDetails();
|
||||
|
||||
// Payment request network matches client network?
|
||||
if ((details.genesis() == "1a91e3dace36e2be3bf030a65679fe821aa1d6ef92e7c9902eb318182c355691" && TestNet()) ||
|
||||
(details.genesis() == "bb0a78264637406b6360aad926284d544d7049f45189db5664f3c4d07350559e" && !TestNet()))
|
||||
{
|
||||
emit message(tr("Payment request rejected"), tr("Payment request network doesn't match client network."),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Expired payment request?
|
||||
if (details.has_expires() && (int64_t)details.expires() < GetTime())
|
||||
{
|
||||
emit message(tr("Payment request rejected"), tr("Payment request has expired."),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
emit message(tr("Payment request error"), tr("Payment request is not initialized."),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
recipient.paymentRequest = request;
|
||||
recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
|
||||
|
||||
|
@ -497,11 +544,11 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
|||
// Append destination address
|
||||
addresses.append(QString::fromStdString(CBitcoinAddress(dest).ToString()));
|
||||
}
|
||||
else if (!recipient.authenticatedMerchant.isEmpty()){
|
||||
else if (!recipient.authenticatedMerchant.isEmpty()) {
|
||||
// Insecure payments to custom bitcoin addresses are not supported
|
||||
// (there is no good way to tell the user where they are paying in a way
|
||||
// they'd have a chance of understanding).
|
||||
emit message(tr("Payment request error"),
|
||||
emit message(tr("Payment request rejected"),
|
||||
tr("Unverified payment requests to custom payment scripts are unsupported."),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
return false;
|
||||
|
@ -510,11 +557,10 @@ bool PaymentServer::processPaymentRequest(PaymentRequestPlus& request, SendCoins
|
|||
// Extract and check amounts
|
||||
CTxOut txOut(sendingTo.second, sendingTo.first);
|
||||
if (txOut.IsDust(CTransaction::nMinRelayTxFee)) {
|
||||
QString msg = tr("Requested payment amount of %1 is too small (considered dust).")
|
||||
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second));
|
||||
emit message(tr("Payment request error"), tr("Requested payment amount of %1 is too small (considered dust).")
|
||||
.arg(BitcoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second)),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
|
||||
qDebug() << "PaymentServer::processPaymentRequest : " << msg;
|
||||
emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -581,8 +627,8 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
|
|||
refund_to->set_script(&s[0], s.size());
|
||||
}
|
||||
else {
|
||||
// This should never happen, because sending coins should have just unlocked the wallet
|
||||
// and refilled the keypool
|
||||
// This should never happen, because sending coins should have
|
||||
// just unlocked the wallet and refilled the keypool.
|
||||
qDebug() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
|
||||
}
|
||||
}
|
||||
|
@ -594,7 +640,7 @@ void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipien
|
|||
netManager->post(netRequest, serData);
|
||||
}
|
||||
else {
|
||||
// This should never happen, either:
|
||||
// This should never happen, either.
|
||||
qDebug() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
|
||||
}
|
||||
}
|
||||
|
@ -620,17 +666,15 @@ void PaymentServer::netRequestFinished(QNetworkReply* reply)
|
|||
{
|
||||
PaymentRequestPlus request;
|
||||
SendCoinsRecipient recipient;
|
||||
if (request.parse(data) && processPaymentRequest(request, recipient))
|
||||
if (!request.parse(data))
|
||||
{
|
||||
emit receivedPaymentRequest(recipient);
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "PaymentServer::netRequestFinished : Error processing payment request";
|
||||
qDebug() << "PaymentServer::netRequestFinished : Error parsing payment request";
|
||||
emit message(tr("Payment request error"),
|
||||
tr("Payment request can not be parsed or processed!"),
|
||||
tr("Payment request can not be parsed!"),
|
||||
CClientUIInterface::MSG_ERROR);
|
||||
}
|
||||
else if (processPaymentRequest(request, recipient))
|
||||
emit receivedPaymentRequest(recipient);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -377,26 +377,8 @@ void SendCoinsDialog::pasteEntry(const SendCoinsRecipient &rv)
|
|||
|
||||
bool SendCoinsDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
|
||||
{
|
||||
QString strSendCoins = tr("Send Coins");
|
||||
if (rv.paymentRequest.IsInitialized()) {
|
||||
// Expired payment request?
|
||||
const payments::PaymentDetails& details = rv.paymentRequest.getDetails();
|
||||
if (details.has_expires() && (int64_t)details.expires() < GetTime())
|
||||
{
|
||||
emit message(strSendCoins, tr("Payment request expired"),
|
||||
CClientUIInterface::MSG_WARNING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
CBitcoinAddress address(rv.address.toStdString());
|
||||
if (!address.IsValid()) {
|
||||
emit message(strSendCoins, tr("Invalid payment address %1").arg(rv.address),
|
||||
CClientUIInterface::MSG_WARNING);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Just paste the entry, all pre-checks
|
||||
// are done in paymentserver.cpp.
|
||||
pasteEntry(rv);
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue