void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& recipient, QByteArray transaction) { const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); if (!details.has_payment_url()) return; QNetworkRequest netRequest; netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK); netRequest.setUrl(QString::fromStdString(details.payment_url())); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT); netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK); payments::Payment payment; payment.set_merchant_data(details.merchant_data()); payment.add_transactions(transaction.data(), transaction.size()); // Create a new refund address, or re-use: QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); std::string strAccount = account.toStdString(); std::set<CTxDestination> refundAddresses = wallet->GetAccountAddresses(strAccount); if (!refundAddresses.empty()) { CScript s = GetScriptForDestination(*refundAddresses.begin()); payments::Output* refund_to = payment.add_refund_to(); refund_to->set_script(&s[0], s.size()); } else { CPubKey newKey; if (wallet->GetKeyFromPool(newKey)) { CKeyID keyID = newKey.GetID(); wallet->SetAddressBook(keyID, strAccount, "refund"); CScript s = GetScriptForDestination(keyID); payments::Output* refund_to = payment.add_refund_to(); 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. qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set"; } } int length = payment.ByteSize(); netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length); QByteArray serData(length, '\0'); if (payment.SerializeToArray(serData.data(), length)) { netManager->post(netRequest, serData); } else { // This should never happen, either. qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message"; } }
void PaymentServer::fetchPaymentACK(CWallet* wallet, const SendCoinsRecipient& recipient, QByteArray transaction) { const payments::PaymentDetails& details = recipient.paymentRequest.getDetails(); if (!details.has_payment_url()) return; QNetworkRequest netRequest; netRequest.setAttribute(QNetworkRequest::User, BIP70_MESSAGE_PAYMENTACK); netRequest.setUrl(QString::fromStdString(details.payment_url())); netRequest.setHeader(QNetworkRequest::ContentTypeHeader, BIP71_MIMETYPE_PAYMENT); netRequest.setRawHeader("User-Agent", CLIENT_NAME.c_str()); netRequest.setRawHeader("Accept", BIP71_MIMETYPE_PAYMENTACK); payments::Payment payment; payment.set_merchant_data(details.merchant_data()); payment.add_transactions(transaction.data(), transaction.size()); // Create a new refund address, or re-use: QString account = tr("Refund from %1").arg(recipient.authenticatedMerchant); std::string strAccount = account.toStdString(); CPubKey newKey; if (wallet->GetKeyFromPool(newKey)) { // BIP70 requests encode the scriptPubKey directly, so we are not restricted to address // types supported by the receiver. As a result, we choose the address format we also // use for change. Despite an actual payment and not change, this is a close match: // it's the output type we use subject to privacy issues, but not restricted by what // other software supports. wallet->LearnRelatedScripts(newKey, g_change_type); CTxDestination dest = GetDestinationForKey(newKey, g_change_type); wallet->SetAddressBook(dest, strAccount, "refund"); CScript s = GetScriptForDestination(dest); payments::Output* refund_to = payment.add_refund_to(); 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. qWarning() << "PaymentServer::fetchPaymentACK: Error getting refund key, refund_to not set"; } int length = payment.ByteSize(); netRequest.setHeader(QNetworkRequest::ContentLengthHeader, length); QByteArray serData(length, '\0'); if (payment.SerializeToArray(serData.data(), length)) { netManager->post(netRequest, serData); } else { // This should never happen, either. qWarning() << "PaymentServer::fetchPaymentACK: Error serializing payment message"; } }
void serString(const char *str, char *prefsBlob, long *pCurrBlobSize) { int len = StrLen(str)+1; serInt(len, prefsBlob, pCurrBlobSize); serData(str, len, prefsBlob, pCurrBlobSize); }
// Create a blob containing serialized preferences. // Devnote: caller needs to free memory returned. // TODO: move ser* (serData etc.) functions from common.c to here // after changing prefs in all apps to use PrefsStore static void* SerializeItems(PrefItem *items, int itemsCount, long *pBlobSize) { Assert(items); Assert(itemsCount>=0); Assert(pBlobSize); char * prefsBlob = NULL; long blobSize, blobSizePhaseOne; /* phase one: calculate the size of the blob */ /* phase two: create the blob */ for(int phase=1; phase<=2; phase++) { blobSize = 0; Assert( 4 == StrLen(PREFS_STORE_RECORD_ID) ); serData( (char*)PREFS_STORE_RECORD_ID, StrLen(PREFS_STORE_RECORD_ID), prefsBlob, &blobSize ); for(int item=0; item<itemsCount; item++) { Assert( items[item].uniqueId >= 0 ); serInt( items[item].uniqueId, prefsBlob, &blobSize); serInt( (int)items[item].type, prefsBlob, &blobSize); switch( items[item].type ) { case pitBool: serBool(items[item].value.boolVal, prefsBlob, &blobSize); break; case pitInt: serInt(items[item].value.intVal, prefsBlob, &blobSize); break; case pitLong: serLong(items[item].value.longVal, prefsBlob, &blobSize); break; case pitUInt16: serUInt16(items[item].value.uint16Val, prefsBlob, &blobSize); break; case pitUInt32: serUInt32(items[item].value.uint32Val, prefsBlob, &blobSize); break; case pitStr: serString(items[item].value.strVal, prefsBlob, &blobSize); break; default: Assert(0); break; } } if ( 1 == phase ) { Assert( blobSize > 0 ); blobSizePhaseOne = blobSize; prefsBlob = (char*)new_malloc( blobSize ); if (NULL == prefsBlob) return NULL; } } Assert( blobSize == blobSizePhaseOne ); Assert( blobSize >= 4 ); *pBlobSize = blobSize; Assert( prefsBlob ); return prefsBlob; }
static void serUInt32(UInt32 val, char *prefsBlob, long *pCurrBlobSize) { Assert(sizeof(val)==4); serData( (char*) &val, sizeof(val), prefsBlob, pCurrBlobSize); }