Esempio n. 1
0
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";
    }
}
Esempio n. 2
0
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";
    }
}
Esempio n. 3
0
void serString(const char *str, char *prefsBlob, long *pCurrBlobSize)
{
    int len = StrLen(str)+1;
    serInt(len, prefsBlob, pCurrBlobSize);
    serData(str, len, prefsBlob, pCurrBlobSize);
}
Esempio n. 4
0
// 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;
}
Esempio n. 5
0
static void serUInt32(UInt32 val, char *prefsBlob, long *pCurrBlobSize)
{
    Assert(sizeof(val)==4);
    serData( (char*) &val, sizeof(val), prefsBlob, pCurrBlobSize);
}