Anoncoin  0.9.4
P2P Digital Currency
paymentserver.cpp
Go to the documentation of this file.
1 // Copyright (c) 2011-2013 The Bitcoin developers
2 // Copyright (c) 2013-2014 The Anoncoin Core developers
3 // Distributed under the MIT/X11 software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include "paymentserver.h"
7 
8 #include "anoncoinunits.h"
9 #include "guiconstants.h"
10 #include "guiutil.h"
11 #include "optionsmodel.h"
12 
13 #include "base58.h"
14 #include "ui_interface.h"
15 #include "wallet.h"
16 
17 #include <cstdlib>
18 
19 #include <openssl/x509.h>
20 #include <openssl/x509_vfy.h>
21 #include <QApplication>
22 #include <QByteArray>
23 #include <QDataStream>
24 #include <QDateTime>
25 #include <QDebug>
26 #include <QFile>
27 #include <QFileOpenEvent>
28 #include <QHash>
29 #include <QList>
30 #include <QLocalServer>
31 #include <QLocalSocket>
32 #include <QNetworkAccessManager>
33 #include <QNetworkProxy>
34 #include <QNetworkReply>
35 #include <QNetworkRequest>
36 #include <QSslCertificate>
37 #include <QSslError>
38 #include <QSslSocket>
39 #include <QStringList>
40 #include <QTextDocument>
41 
42 #if QT_VERSION < 0x050000
43 #include <QUrl>
44 #else
45 #include <QUrlQuery>
46 #endif
47 
48 using namespace boost;
49 
50 const int ANONCOIN_IPC_CONNECT_TIMEOUT = 1000; // milliseconds
51 const QString ANONCOIN_IPC_PREFIX("anoncoin:");
52 const char* ANONCOIN_REQUEST_MIMETYPE = "application/anoncoin-paymentrequest";
53 const char* ANONCOIN_PAYMENTACK_MIMETYPE = "application/anoncoin-paymentack";
54 const char* ANONCOIN_PAYMENTACK_CONTENTTYPE = "application/anoncoin-payment";
55 
56 X509_STORE* PaymentServer::certStore = NULL;
58 {
59  if (PaymentServer::certStore != NULL)
60  {
61  X509_STORE_free(PaymentServer::certStore);
63  }
64 }
65 
66 //
67 // Create a name that is unique for:
68 // testnet / non-testnet
69 // data directory
70 //
71 static QString ipcServerName()
72 {
73  QString name("AnoncoinQt");
74 
75  // Append a simple hash of the datadir
76  // Note that GetDataDir(true) returns a different path
77  // for -testnet versus main net
78  QString ddir(QString::fromStdString(GetDataDir(true).string()));
79  name.append(QString::number(qHash(ddir)));
80 
81  return name;
82 }
83 
84 //
85 // We store payment URIs and requests received before
86 // the main GUI window is up and ready to ask the user
87 // to send payment.
88 
89 static QList<QString> savedPaymentRequests;
90 
91 static void ReportInvalidCertificate(const QSslCertificate& cert)
92 {
93  qDebug() << "ReportInvalidCertificate : Payment server found an invalid certificate: " << cert.subjectInfo(QSslCertificate::CommonName);
94 }
95 
96 //
97 // Load OpenSSL's list of root certificate authorities
98 //
99 void PaymentServer::LoadRootCAs(X509_STORE* _store)
100 {
101  if (PaymentServer::certStore == NULL)
103  else
104  freeCertStore();
105 
106  // Unit tests mostly use this, to pass in fake root CAs:
107  if (_store)
108  {
109  PaymentServer::certStore = _store;
110  return;
111  }
112 
113  // Normal execution, use either -rootcertificates or system certs:
114  PaymentServer::certStore = X509_STORE_new();
115 
116  // Note: use "-system-" default here so that users can pass -rootcertificates=""
117  // and get 'I don't like X.509 certificates, don't trust anybody' behavior:
118  QString certFile = QString::fromStdString(GetArg("-rootcertificates", "-system-"));
119 
120  if (certFile.isEmpty())
121  return; // Empty store
122 
123  QList<QSslCertificate> certList;
124 
125  if (certFile != "-system-")
126  {
127  certList = QSslCertificate::fromPath(certFile);
128  // Use those certificates when fetching payment requests, too:
129  QSslSocket::setDefaultCaCertificates(certList);
130  }
131  else
132  certList = QSslSocket::systemCaCertificates ();
133 
134  int nRootCerts = 0;
135  const QDateTime currentTime = QDateTime::currentDateTime();
136  foreach (const QSslCertificate& cert, certList)
137  {
138  if (currentTime < cert.effectiveDate() || currentTime > cert.expiryDate()) {
139  ReportInvalidCertificate(cert);
140  continue;
141  }
142 #if QT_VERSION >= 0x050000
143  if (cert.isBlacklisted()) {
144  ReportInvalidCertificate(cert);
145  continue;
146  }
147 #endif
148  QByteArray certData = cert.toDer();
149  const unsigned char *data = (const unsigned char *)certData.data();
150 
151  X509* x509 = d2i_X509(0, &data, certData.size());
152  if (x509 && X509_STORE_add_cert(PaymentServer::certStore, x509))
153  {
154  // Note: X509_STORE_free will free the X509* objects when
155  // the PaymentServer is destroyed
156  ++nRootCerts;
157  }
158  else
159  {
160  ReportInvalidCertificate(cert);
161  continue;
162  }
163  }
164  qDebug() << "PaymentServer::LoadRootCAs : Loaded " << nRootCerts << " root certificates";
165 
166  // Project for another day:
167  // Fetch certificate revocation lists, and add them to certStore.
168  // Issues to consider:
169  // performance (start a thread to fetch in background?)
170  // privacy (fetch through tor/proxy so IP address isn't revealed)
171  // would it be easier to just use a compiled-in blacklist?
172  // or use Qt's blacklist?
173  // "certificate stapling" with server-side caching is more efficient
174 }
175 
176 //
177 // Sending to the server is done synchronously, at startup.
178 // If the server isn't already running, startup continues,
179 // and the items in savedPaymentRequest will be handled
180 // when uiReady() is called.
181 //
182 bool PaymentServer::ipcParseCommandLine(int argc, char* argv[])
183 {
184  for (int i = 1; i < argc; i++)
185  {
186  QString arg(argv[i]);
187  if (arg.startsWith("-"))
188  continue;
189 
190  if (arg.startsWith(ANONCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // anoncoin: URI
191  {
192  savedPaymentRequests.append(arg);
193 
195  if (GUIUtil::parseAnoncoinURI(arg, &r) && !r.address.isEmpty())
196  {
197  CAnoncoinAddress address(r.address.toStdString());
198 
200  if (!address.IsValid())
201  {
203  }
204  }
205  }
206  else if (QFile::exists(arg)) // Filename
207  {
208  savedPaymentRequests.append(arg);
209 
210  PaymentRequestPlus request;
211  if (readPaymentRequest(arg, request))
212  {
213  if (request.getDetails().network() == "main")
215  else
217  }
218  }
219  else
220  {
221  // Printing to debug.log is about the best we can do here, the
222  // GUI hasn't started yet so we can't pop up a message box.
223  qDebug() << "PaymentServer::ipcSendCommandLine : Payment request file does not exist: " << arg;
224  }
225  }
226  return true;
227 }
228 
229 //
230 // Sending to the server is done synchronously, at startup.
231 // If the server isn't already running, startup continues,
232 // and the items in savedPaymentRequest will be handled
233 // when uiReady() is called.
234 //
236 {
237  bool fResult = false;
238  foreach (const QString& r, savedPaymentRequests)
239  {
240  QLocalSocket* socket = new QLocalSocket();
241  socket->connectToServer(ipcServerName(), QIODevice::WriteOnly);
242  if (!socket->waitForConnected(ANONCOIN_IPC_CONNECT_TIMEOUT))
243  {
244  delete socket;
245  return false;
246  }
247 
248  QByteArray block;
249  QDataStream out(&block, QIODevice::WriteOnly);
250  out.setVersion(QDataStream::Qt_4_0);
251  out << r;
252  out.device()->seek(0);
253  socket->write(block);
254  socket->flush();
255 
256  socket->waitForBytesWritten(ANONCOIN_IPC_CONNECT_TIMEOUT);
257  socket->disconnectFromServer();
258  delete socket;
259  fResult = true;
260  }
261 
262  return fResult;
263 }
264 
265 PaymentServer::PaymentServer(QObject* parent, bool startLocalServer) :
266  QObject(parent),
267  saveURIs(true),
268  uriServer(0),
269  netManager(0),
270  optionsModel(0)
271 {
272  // Verify that the version of the library that we linked against is
273  // compatible with the version of the headers we compiled against.
274  GOOGLE_PROTOBUF_VERIFY_VERSION;
275 
276  // Install global event filter to catch QFileOpenEvents
277  // on Mac: sent when you click anoncoin: links
278  // other OSes: helpful when dealing with payment request files (in the future)
279  if (parent)
280  parent->installEventFilter(this);
281 
282  QString name = ipcServerName();
283 
284  // Clean up old socket leftover from a crash:
285  QLocalServer::removeServer(name);
286 
287  if (startLocalServer)
288  {
289  uriServer = new QLocalServer(this);
290 
291  if (!uriServer->listen(name)) {
292  // constructor is called early in init, so don't use "emit message()" here
293  QMessageBox::critical(0, tr("Payment request error"),
294  tr("Cannot start anoncoin: click-to-pay handler"));
295  }
296  else {
297  connect(uriServer, SIGNAL(newConnection()), this, SLOT(handleURIConnection()));
298  connect(this, SIGNAL(receivedPaymentACK(QString)), this, SLOT(handlePaymentACK(QString)));
299  }
300  }
301 }
302 
304 {
305  google::protobuf::ShutdownProtobufLibrary();
306 }
307 
308 //
309 // OSX-specific way of handling anoncoin: URIs and
310 // PaymentRequest mime types
311 //
312 bool PaymentServer::eventFilter(QObject *object, QEvent *event)
313 {
314  // clicking on anoncoin: URIs creates FileOpen events on the Mac
315  if (event->type() == QEvent::FileOpen)
316  {
317  QFileOpenEvent *fileEvent = static_cast<QFileOpenEvent*>(event);
318  if (!fileEvent->file().isEmpty())
319  handleURIOrFile(fileEvent->file());
320  else if (!fileEvent->url().isEmpty())
321  handleURIOrFile(fileEvent->url().toString());
322 
323  return true;
324  }
325 
326  return QObject::eventFilter(object, event);
327 }
328 
330 {
331  if (!optionsModel)
332  return;
333  if (netManager != NULL)
334  delete netManager;
335 
336  // netManager is used to fetch paymentrequests given in anoncoin: URIs
337  netManager = new QNetworkAccessManager(this);
338 
339  QNetworkProxy proxy;
340 
341  // Query active SOCKS5 proxy
342  if (optionsModel->getProxySettings(proxy)) {
343  netManager->setProxy(proxy);
344 
345  qDebug() << "PaymentServer::initNetManager : Using SOCKS5 proxy" << proxy.hostName() << ":" << proxy.port();
346  }
347  else
348  qDebug() << "PaymentServer::initNetManager : No active proxy server found.";
349 
350  connect(netManager, SIGNAL(finished(QNetworkReply*)),
351  this, SLOT(netRequestFinished(QNetworkReply*)));
352  connect(netManager, SIGNAL(sslErrors(QNetworkReply*, const QList<QSslError> &)),
353  this, SLOT(reportSslErrors(QNetworkReply*, const QList<QSslError> &)));
354 }
355 
357 {
358  initNetManager();
359 
360  saveURIs = false;
361  foreach (const QString& s, savedPaymentRequests)
362  {
363  handleURIOrFile(s);
364  }
365  savedPaymentRequests.clear();
366 }
367 
368 void PaymentServer::handleURIOrFile(const QString& s)
369 {
370  if (saveURIs)
371  {
372  savedPaymentRequests.append(s);
373  return;
374  }
375 
376  if (s.startsWith(ANONCOIN_IPC_PREFIX, Qt::CaseInsensitive)) // anoncoin: URI
377  {
378 #if QT_VERSION < 0x050000
379  QUrl uri(s);
380 #else
381  QUrlQuery uri((QUrl(s)));
382 #endif
383  if (uri.hasQueryItem("r")) // payment request URI
384  {
385  QByteArray temp;
386  temp.append(uri.queryItemValue("r"));
387  QString decoded = QUrl::fromPercentEncoding(temp);
388  QUrl fetchUrl(decoded, QUrl::StrictMode);
389 
390  if (fetchUrl.isValid())
391  {
392  qDebug() << "PaymentServer::handleURIOrFile : fetchRequest(" << fetchUrl << ")";
393  fetchRequest(fetchUrl);
394  }
395  else
396  {
397  qDebug() << "PaymentServer::handleURIOrFile : Invalid URL: " << fetchUrl;
398  emit message(tr("URI handling"),
399  tr("Payment request fetch URL is invalid: %1").arg(fetchUrl.toString()),
401  }
402 
403  return;
404  }
405  else // normal URI
406  {
407  SendCoinsRecipient recipient;
408  if (GUIUtil::parseAnoncoinURI(s, &recipient))
409  emit receivedPaymentRequest(recipient);
410  else
411  emit message(tr("URI handling"),
412  tr("URI cannot be parsed! This can be caused by an invalid Anoncoin address or malformed URI parameters."),
414 
415  return;
416  }
417  }
418 
419  if (QFile::exists(s)) // payment request file
420  {
421  PaymentRequestPlus request;
422  SendCoinsRecipient recipient;
423  if (readPaymentRequest(s, request) && processPaymentRequest(request, recipient))
424  emit receivedPaymentRequest(recipient);
425  else
426  emit message(tr("Payment request file handling"),
427  tr("Payment request file cannot be read! This can be caused by an invalid payment request file."),
429 
430  return;
431  }
432 }
433 
435 {
436  QLocalSocket *clientConnection = uriServer->nextPendingConnection();
437 
438  while (clientConnection->bytesAvailable() < (int)sizeof(quint32))
439  clientConnection->waitForReadyRead();
440 
441  connect(clientConnection, SIGNAL(disconnected()),
442  clientConnection, SLOT(deleteLater()));
443 
444  QDataStream in(clientConnection);
445  in.setVersion(QDataStream::Qt_4_0);
446  if (clientConnection->bytesAvailable() < (int)sizeof(quint16)) {
447  return;
448  }
449  QString msg;
450  in >> msg;
451 
452  handleURIOrFile(msg);
453 }
454 
455 bool PaymentServer::readPaymentRequest(const QString& filename, PaymentRequestPlus& request)
456 {
457  QFile f(filename);
458  if (!f.open(QIODevice::ReadOnly))
459  {
460  qDebug() << "PaymentServer::readPaymentRequest : Failed to open " << filename;
461  return false;
462  }
463 
464  if (f.size() > MAX_PAYMENT_REQUEST_SIZE)
465  {
466  qDebug() << "PaymentServer::readPaymentRequest : " << filename << " too large";
467  return false;
468  }
469 
470  QByteArray data = f.readAll();
471 
472  return request.parse(data);
473 }
474 
476 {
477  if (!optionsModel)
478  return false;
479 
480  recipient.paymentRequest = request;
481  recipient.message = GUIUtil::HtmlEscape(request.getDetails().memo());
482 
484 
485  QList<std::pair<CScript, qint64> > sendingTos = request.getPayTo();
486  QStringList addresses;
487 
488  foreach(const PAIRTYPE(CScript, qint64)& sendingTo, sendingTos) {
489  // Extract and check destination addresses
490  CTxDestination dest;
491  if (ExtractDestination(sendingTo.first, dest)) {
492  // Append destination address
493  addresses.append(QString::fromStdString(CAnoncoinAddress(dest).ToString()));
494  }
495  else if (!recipient.authenticatedMerchant.isEmpty()){
496  // Insecure payments to custom anoncoin addresses are not supported
497  // (there is no good way to tell the user where they are paying in a way
498  // they'd have a chance of understanding).
499  emit message(tr("Payment request error"),
500  tr("Unverified payment requests to custom payment scripts are unsupported."),
502  return false;
503  }
504 
505  // Extract and check amounts
506  CTxOut txOut(sendingTo.second, sendingTo.first);
508  QString msg = tr("Requested payment amount of %1 is too small (considered dust).")
509  .arg(AnoncoinUnits::formatWithUnit(optionsModel->getDisplayUnit(), sendingTo.second));
510 
511  qDebug() << "PaymentServer::processPaymentRequest : " << msg;
512  emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
513  return false;
514  }
515 
516  recipient.amount += sendingTo.second;
517  }
518  // Store addresses and format them to fit nicely into the GUI
519  recipient.address = addresses.join("<br />");
520 
521  if (!recipient.authenticatedMerchant.isEmpty()) {
522  qDebug() << "PaymentServer::processPaymentRequest : Secure payment request from " << recipient.authenticatedMerchant;
523  }
524  else {
525  qDebug() << "PaymentServer::processPaymentRequest : Insecure payment request to " << addresses.join(", ");
526  }
527 
528  return true;
529 }
530 
532 {
533  QNetworkRequest netRequest;
534  netRequest.setAttribute(QNetworkRequest::User, "PaymentRequest");
535  netRequest.setUrl(url);
536  netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
537  netRequest.setRawHeader("Accept", ANONCOIN_REQUEST_MIMETYPE);
538  netManager->get(netRequest);
539 }
540 
541 void PaymentServer::fetchPaymentACK(CWallet* wallet, SendCoinsRecipient recipient, QByteArray transaction)
542 {
543  const payments::PaymentDetails& details = recipient.paymentRequest.getDetails();
544  if (!details.has_payment_url())
545  return;
546 
547  QNetworkRequest netRequest;
548  netRequest.setAttribute(QNetworkRequest::User, "PaymentACK");
549  netRequest.setUrl(QString::fromStdString(details.payment_url()));
550  netRequest.setHeader(QNetworkRequest::ContentTypeHeader, ANONCOIN_PAYMENTACK_CONTENTTYPE);
551  netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str());
552  netRequest.setRawHeader("Accept", ANONCOIN_PAYMENTACK_MIMETYPE);
553 
554  payments::Payment payment;
555  payment.set_merchant_data(details.merchant_data());
556  payment.add_transactions(transaction.data(), transaction.size());
557 
558  // Create a new refund address, or re-use:
559  QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant);
560  std::string strAccount = account.toStdString();
561  set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount);
562  if (!refundAddresses.empty()) {
563  CScript s; s.SetDestination(*refundAddresses.begin());
564  payments::Output* refund_to = payment.add_refund_to();
565  refund_to->set_script(&s[0], s.size());
566  }
567  else {
568  CPubKey newKey;
569  if (wallet->GetKeyFromPool(newKey)) {
570  LOCK(wallet->cs_wallet); // SetAddressBook
571  CKeyID keyID = newKey.GetID();
572  wallet->SetAddressBook(keyID, strAccount, "refund");
573 
574  CScript s; s.SetDestination(keyID);
575  payments::Output* refund_to = payment.add_refund_to();
576  refund_to->set_script(&s[0], s.size());
577  }
578  else {
579  // This should never happen, because sending coins should have just unlocked the wallet
580  // and refilled the keypool
581  qDebug() << "PaymentServer::fetchPaymentACK : Error getting refund key, refund_to not set";
582  }
583  }
584 
585  int length = payment.ByteSize();
586  netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length);
587  QByteArray serData(length, '\0');
588  if (payment.SerializeToArray(serData.data(), length)) {
589  netManager->post(netRequest, serData);
590  }
591  else {
592  // This should never happen, either:
593  qDebug() << "PaymentServer::fetchPaymentACK : Error serializing payment message";
594  }
595 }
596 
597 void PaymentServer::netRequestFinished(QNetworkReply* reply)
598 {
599  reply->deleteLater();
600  if (reply->error() != QNetworkReply::NoError)
601  {
602  QString msg = tr("Error communicating with %1: %2")
603  .arg(reply->request().url().toString())
604  .arg(reply->errorString());
605 
606  qDebug() << "PaymentServer::netRequestFinished : " << msg;
607  emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
608  return;
609  }
610 
611  QByteArray data = reply->readAll();
612 
613  QString requestType = reply->request().attribute(QNetworkRequest::User).toString();
614  if (requestType == "PaymentRequest")
615  {
616  PaymentRequestPlus request;
617  SendCoinsRecipient recipient;
618  if (request.parse(data) && processPaymentRequest(request, recipient))
619  {
620  emit receivedPaymentRequest(recipient);
621  }
622  else
623  {
624  qDebug() << "PaymentServer::netRequestFinished : Error processing payment request";
625  emit message(tr("Payment request error"),
626  tr("Payment request cannot be parsed!"),
628  }
629 
630  return;
631  }
632  else if (requestType == "PaymentACK")
633  {
634  payments::PaymentACK paymentACK;
635  if (!paymentACK.ParseFromArray(data.data(), data.size()))
636  {
637  QString msg = tr("Bad response from server %1")
638  .arg(reply->request().url().toString());
639 
640  qDebug() << "PaymentServer::netRequestFinished : " << msg;
641  emit message(tr("Payment request error"), msg, CClientUIInterface::MSG_ERROR);
642  }
643  else
644  {
645  emit receivedPaymentACK(GUIUtil::HtmlEscape(paymentACK.memo()));
646  }
647  }
648 }
649 
650 void PaymentServer::reportSslErrors(QNetworkReply* reply, const QList<QSslError> &errs)
651 {
652  Q_UNUSED(reply);
653 
654  QString errString;
655  foreach (const QSslError& err, errs) {
656  qDebug() << "PaymentServer::reportSslErrors : " << err;
657  errString += err.errorString() + "\n";
658  }
659  emit message(tr("Network request error"), errString, CClientUIInterface::MSG_ERROR);
660 }
661 
663 {
664  this->optionsModel = optionsModel;
665 }
666 
667 void PaymentServer::handlePaymentACK(const QString& paymentACKMsg)
668 {
669  // currently we don't futher process or store the paymentACK message
670  emit message(tr("Payment acknowledged"), paymentACKMsg, CClientUIInterface::ICON_INFORMATION | CClientUIInterface::MODAL);
671 }
const boost::filesystem::path & GetDataDir(bool fNetSpecific)
Definition: util.cpp:968
bool IsDust(int64_t nMinRelayTxFee) const
Definition: core.h:153
bool SetAddressBook(const CTxDestination &address, const std::string &strName, const std::string &purpose)
Definition: wallet.cpp:1638
PaymentRequestPlus paymentRequest
Definition: walletmodel.h:56
void message(const QString &title, const QString &message, unsigned int style)
const char * ANONCOIN_PAYMENTACK_CONTENTTYPE
static bool readPaymentRequest(const QString &filename, PaymentRequestPlus &request)
Definition: init.h:14
void set_script(const ::std::string &value)
void setOptionsModel(OptionsModel *optionsModel)
#define PAIRTYPE(t1, t2)
Definition: util.h:49
const char * ANONCOIN_REQUEST_MIMETYPE
CCriticalSection cs_wallet
Main wallet lock.
Definition: wallet.h:133
static QString formatWithUnit(int unit, qint64 amount, bool plussign=false)
Format as string (with unit)
bool eventFilter(QObject *object, QEvent *event)
void handlePaymentACK(const QString &paymentACKMsg)
bool getMerchant(X509_STORE *certStore, QString &merchant) const
void receivedPaymentACK(const QString &paymentACKMsg)
bool parseAnoncoinURI(const QUrl &uri, SendCoinsRecipient *out)
Definition: guiutil.cpp:117
void set_merchant_data(const ::std::string &value)
void receivedPaymentRequest(SendCoinsRecipient)
QString HtmlEscape(const QString &str, bool fMultiLine)
Definition: guiutil.cpp:228
inline::std::string * add_transactions()
QLocalServer * uriServer
static X509_STORE * certStore
void handleURIOrFile(const QString &s)
static bool ipcParseCommandLine(int argc, char *argv[])
static void freeCertStore()
Force blocking, modal message box dialog (not just OS notification)
Definition: ui_interface.h:70
const ::std::string & payment_url() const
void SetDestination(const CTxDestination &address)
Definition: script.cpp:1945
static bool ipcSendCommandLine()
const char * url
Definition: rpcconsole.cpp:51
void netRequestFinished(QNetworkReply *)
const ::std::string & memo() const
void SelectParams(CChainParams::Network network)
Sets the params returned by Params() to those for the given network.
#define LOCK(cs)
Definition: sync.h:157
void fetchRequest(const QUrl &url)
bool getProxySettings(QNetworkProxy &proxy) const
An encapsulated public key.
Definition: key.h:43
base58-encoded Anoncoin addresses.
Definition: base58.h:102
const int ANONCOIN_IPC_CONNECT_TIMEOUT
const ::std::string & network() const
const payments::PaymentDetails & getDetails() const
An output of a transaction.
Definition: core.h:121
PaymentServer(QObject *parent, bool startLocalServer=true)
const QString ANONCOIN_IPC_PREFIX("anoncoin:")
int getDisplayUnit()
Definition: optionsmodel.h:87
QNetworkAccessManager * netManager
const std::string CLIENT_NAME
std::set< CTxDestination > GetAccountAddresses(std::string strAccount) const
Definition: wallet.cpp:1979
bool parse(const QByteArray &data)
boost::variant< CNoDestination, CKeyID, CScriptID > CTxDestination
A txout script template with a specific destination.
Definition: keystore.h:17
void reportSslErrors(QNetworkReply *, const QList< QSslError > &)
void fetchPaymentACK(CWallet *wallet, SendCoinsRecipient recipient, QByteArray transaction)
Interface from Qt to configuration data structure for Anoncoin client.
Definition: optionsmodel.h:27
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:413
const char * ANONCOIN_PAYMENTACK_MIMETYPE
A reference to a CKey: the Hash160 of its serialized public key.
Definition: key.h:27
bool ExtractDestination(const CScript &scriptPubKey, CTxDestination &addressRet)
Definition: script.cpp:1513
A CWallet is an extension of a keystore, which also maintains a set of transactions and balances...
Definition: wallet.h:101
void handleURIConnection()
static int64_t nMinRelayTxFee
Fees smaller than this (in satoshi) are considered zero fee (for relaying and mining) ...
Definition: core.h:183
inline::payments::Output * add_refund_to()
bool processPaymentRequest(PaymentRequestPlus &request, SendCoinsRecipient &recipient)
const ::std::string & memo() const
OptionsModel * optionsModel
std::string GetArg(const std::string &strArg, const std::string &strDefault)
Return string argument or default value.
Definition: util.cpp:506
bool GetKeyFromPool(CPubKey &key)
Definition: wallet.cpp:1816
CKeyID GetID() const
Definition: key.h:132
static void LoadRootCAs(X509_STORE *store=NULL)
const ::std::string & merchant_data() const
QString authenticatedMerchant
Definition: walletmodel.h:58
QList< std::pair< CScript, qint64 > > getPayTo() const