QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type) { std::string strLabel = label.toStdString(); std::string strAddress = address.toStdString(); editStatus = OK; if(type == Send) { if(!walletModel->validateAddress(address)) { editStatus = INVALID_ADDRESS; return QString(); } // Check for duplicate addresses { LOCK(wallet->cs_wallet); if(wallet->mapAddressBook.count(DecodeDestination(strAddress))) { editStatus = DUPLICATE_ADDRESS; return QString(); } } } else if(type == Receive) { // Generate a new address to associate with given label CPubKey newKey; if(!wallet->GetKeyFromPool(newKey)) { WalletModel::UnlockContext ctx(walletModel->requestUnlock()); if(!ctx.isValid()) { // Unlock wallet failed or was cancelled editStatus = WALLET_UNLOCK_FAILURE; return QString(); } if(!wallet->GetKeyFromPool(newKey)) { editStatus = KEY_GENERATION_FAILURE; return QString(); } } wallet->LearnRelatedScripts(newKey, address_type); strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type)); } else { return QString(); } // Add entry { LOCK(wallet->cs_wallet); wallet->SetAddressBook(DecodeDestination(strAddress), strLabel, (type == Send ? "send" : "receive")); } return QString::fromStdString(strAddress); }
QString AddressTableModel::addRow(const QString &type, const QString &label, const QString &address, const OutputType address_type) { std::string strLabel = label.toStdString(); std::string strAddress = address.toStdString(); editStatus = OK; if(type == Send) { if(!walletModel->validateAddress(address)) { editStatus = INVALID_ADDRESS; return QString(); } // Check for duplicate addresses { if (walletModel->wallet().getAddress( DecodeDestination(strAddress), /* name= */ nullptr, /* is_mine= */ nullptr, /* purpose= */ nullptr)) { editStatus = DUPLICATE_ADDRESS; return QString(); } } } else if(type == Receive) { // Generate a new address to associate with given label CPubKey newKey; if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey)) { WalletModel::UnlockContext ctx(walletModel->requestUnlock()); if(!ctx.isValid()) { // Unlock wallet failed or was cancelled editStatus = WALLET_UNLOCK_FAILURE; return QString(); } if(!walletModel->wallet().getKeyFromPool(false /* internal */, newKey)) { editStatus = KEY_GENERATION_FAILURE; return QString(); } } walletModel->wallet().learnRelatedScripts(newKey, address_type); CPubKey blinding_pubkey = walletModel->wallet().getBlindingPubKey(GetScriptForDestination(GetDestinationForKey(newKey, address_type))); strAddress = EncodeDestination(GetDestinationForKey(newKey, address_type, blinding_pubkey)); } else { return QString(); } // Add entry walletModel->wallet().setAddressBook(DecodeDestination(strAddress), strLabel, (type == Send ? "send" : "receive")); return QString::fromStdString(strAddress); }
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"; } }