Send TX and messages to .onion addresses
Build All Platforms / test-linux-unit (push) Failing after 40s
Build All Platforms / build-linux-qt (push) Failing after 40s
Build All Platforms / build-linux-daemon (push) Failing after 40s
Build All Platforms / build-windows-qt (push) Has been cancelled
Build All Platforms / build-windows-daemon (push) Has been cancelled
Build All Platforms / build-macos (push) Has been cancelled
Build All Platforms / release (push) Has been cancelled
Build All Platforms / Trigger TRI-PI ARM64 Build (push) Has been cancelled
Build All Platforms / test-linux-unit (push) Failing after 40s
Build All Platforms / build-linux-qt (push) Failing after 40s
Build All Platforms / build-linux-daemon (push) Failing after 40s
Build All Platforms / build-windows-qt (push) Has been cancelled
Build All Platforms / build-windows-daemon (push) Has been cancelled
Build All Platforms / build-macos (push) Has been cancelled
Build All Platforms / release (push) Has been cancelled
Build All Platforms / Trigger TRI-PI ARM64 Build (push) Has been cancelled
- Address validator accepts V3 .onion format (62 chars, base32 + .onion) - WalletModel::validateAddress() recognizes .onion via ValidateOnionAddress() - Send coins/messages dialogs resolve .onion to TRI before sending - Auto-request getwalletaddr from onion peers after version handshake - Placeholder text updated to "Enter a TRI address or .onion address" - Shows info dialog if resolution is pending (async connect + resolve) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4064,6 +4064,17 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
|
||||
pfrom->fSuccessfullyConnected = true;
|
||||
|
||||
// If this is an onion peer and we have a pending resolve, request their wallet address
|
||||
{
|
||||
std::string peerAddr = pfrom->addr.ToStringIP();
|
||||
if (peerAddr.find(".onion") != std::string::npos)
|
||||
{
|
||||
CTorV3Manager* torMgr = CTorV3Manager::GetInstance();
|
||||
if (torMgr)
|
||||
torMgr->RequestWalletAddress(pfrom);
|
||||
}
|
||||
}
|
||||
|
||||
printf("receive version message: version %d, blocks=%d, us=%s, them=%s, peer=%s\n", pfrom->nVersion, pfrom->nStartingHeight, addrMe.ToString().c_str(), addrFrom.ToString().c_str(), pfrom->addr.ToString().c_str());
|
||||
|
||||
cPeerBlockCounts.input(pfrom->nStartingHeight);
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
|
||||
#include "coincontrol.h"
|
||||
#include "coincontroldialog.h"
|
||||
#include "tor/onion_v3.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QLocale>
|
||||
#include <QApplication>
|
||||
#include <QTextDocument>
|
||||
#include <QScrollBar>
|
||||
#include <QClipboard>
|
||||
@@ -145,6 +147,37 @@ void SendCoinsDialog::on_sendButton_clicked()
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve any .onion addresses to TRI addresses
|
||||
CTorV3Manager* torMgr = CTorV3Manager::GetInstance();
|
||||
for(int i = 0; i < recipients.size(); ++i)
|
||||
{
|
||||
std::string addr = recipients[i].address.toStdString();
|
||||
if (addr.size() == 62 && addr.substr(addr.size() - 6) == ".onion")
|
||||
{
|
||||
std::string triAddr;
|
||||
if (torMgr && torMgr->LookupCachedOnionAddress(addr, triAddr))
|
||||
{
|
||||
// Found in cache — substitute
|
||||
recipients[i].address = QString::fromStdString(triAddr);
|
||||
if (recipients[i].label.isEmpty())
|
||||
recipients[i].label = QString::fromStdString(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not cached — initiate async resolution and tell user to wait
|
||||
if (torMgr)
|
||||
torMgr->ResolveOnionAddress(addr, triAddr);
|
||||
|
||||
QMessageBox::information(this, tr("Resolving .onion Address"),
|
||||
tr("Connecting to %1 to resolve their TRI address.\n\n"
|
||||
"Please wait a moment and try again.")
|
||||
.arg(recipients[i].address));
|
||||
fNewRecipientAllowed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format confirmation message
|
||||
QStringList formatted;
|
||||
foreach(const SendCoinsRecipient &rcp, recipients)
|
||||
|
||||
@@ -23,7 +23,7 @@ SendCoinsEntry::SendCoinsEntry(QWidget *parent) :
|
||||
#if QT_VERSION >= 0x040700
|
||||
/* Do not move this to the XML file, Qt before 4.7 will choke on it */
|
||||
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
|
||||
ui->payTo->setPlaceholderText(tr("Enter a TRI address (e.g. TXc7mPCNFFpinDonuSH5PNVY9S8nBcvGQm)"));
|
||||
ui->payTo->setPlaceholderText(tr("Enter a TRI address or .onion address"));
|
||||
ui->narration->setPlaceholderText(tr("Enter a short note to send with payment. This feature will be enabled later."));
|
||||
ui->narration->setEnabled(false);
|
||||
ui->narration->setVisible(false);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "sendmessagesentry.h"
|
||||
#include "dialog_move_handler.h"
|
||||
#include "guiutil.h"
|
||||
#include "tor/onion_v3.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QLocale>
|
||||
@@ -155,6 +156,35 @@ void SendMessagesDialog::on_sendButton_clicked()
|
||||
if(!valid || recipients.isEmpty())
|
||||
return;
|
||||
|
||||
// Resolve any .onion addresses to TRI addresses
|
||||
CTorV3Manager* torMgr = CTorV3Manager::GetInstance();
|
||||
for(int i = 0; i < recipients.size(); ++i)
|
||||
{
|
||||
std::string addr = recipients[i].address.toStdString();
|
||||
if (addr.size() == 62 && addr.substr(addr.size() - 6) == ".onion")
|
||||
{
|
||||
std::string triAddr;
|
||||
if (torMgr && torMgr->LookupCachedOnionAddress(addr, triAddr))
|
||||
{
|
||||
recipients[i].address = QString::fromStdString(triAddr);
|
||||
if (recipients[i].label.isEmpty())
|
||||
recipients[i].label = QString::fromStdString(addr);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (torMgr)
|
||||
torMgr->ResolveOnionAddress(addr, triAddr);
|
||||
|
||||
QMessageBox::information(this, tr("Resolving .onion Address"),
|
||||
tr("Connecting to %1 to resolve their TRI address.\n\n"
|
||||
"Please wait a moment and try again.")
|
||||
.arg(recipients[i].address));
|
||||
fNewRecipientAllowed = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format confirmation message
|
||||
QStringList formatted;
|
||||
foreach(const SendMessagesRecipient &rcp, recipients)
|
||||
|
||||
@@ -25,7 +25,7 @@ SendMessagesEntry::SendMessagesEntry(QWidget *parent) :
|
||||
#if QT_VERSION >= 0x040700
|
||||
/* Do not move this to the XML file, Qt before 4.7 will choke on it */
|
||||
ui->addAsLabel->setPlaceholderText(tr("Enter a label for this address to add it to your address book"));
|
||||
ui->sendTo->setPlaceholderText(tr("Enter a TRI address (e.g. TXc7mPCNFFpinDonuSH5PNVY9S8nBcvGQm)"));
|
||||
ui->sendTo->setPlaceholderText(tr("Enter a TRI address or .onion address"));
|
||||
ui->publicKey->setPlaceholderText(tr("Enter the public key for the address above, it is not in the blockchain"));
|
||||
ui->messageText->setErrorText(tr("You cannot send a blank message!"));
|
||||
#endif
|
||||
|
||||
@@ -50,11 +50,27 @@ QValidator::State TrianglesAddressValidator::validate(QString &input, int &pos)
|
||||
|
||||
// Validation
|
||||
QValidator::State state = QValidator::Acceptable;
|
||||
|
||||
// Allow .onion addresses (base32 lowercase + digits 2-7 + period)
|
||||
bool isOnion = input.endsWith(".onion");
|
||||
|
||||
for(int idx=0; idx<input.size(); ++idx)
|
||||
{
|
||||
int ch = input.at(idx).unicode();
|
||||
|
||||
if(((ch >= '0' && ch<='9') ||
|
||||
if (isOnion)
|
||||
{
|
||||
// V3 onion: base32 (a-z, 2-7) + ".onion" suffix
|
||||
if ((ch >= 'a' && ch <= 'z') || (ch >= '2' && ch <= '7') || ch == '.')
|
||||
{
|
||||
// Valid onion character
|
||||
}
|
||||
else
|
||||
{
|
||||
state = QValidator::Invalid;
|
||||
}
|
||||
}
|
||||
else if(((ch >= '0' && ch<='9') ||
|
||||
(ch >= 'a' && ch<='z') ||
|
||||
(ch >= 'A' && ch<='Z')) &&
|
||||
ch != 'l' && ch != 'I' && ch != '0' && ch != 'O')
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "walletdb.h" // for BackupWallet
|
||||
#include "base58.h"
|
||||
#include "main.h"
|
||||
#include "tor/onion_v3.h"
|
||||
|
||||
#include <QSet>
|
||||
#include <QTimer>
|
||||
@@ -281,8 +282,11 @@ void WalletModel::updateAddressBook(const QString &address, const QString &label
|
||||
bool WalletModel::validateAddress(const QString &address)
|
||||
{
|
||||
std::string sAddr = address.toStdString();
|
||||
|
||||
|
||||
|
||||
// Accept V3 .onion addresses (56-char base32 + ".onion" = 62 chars)
|
||||
if (sAddr.size() == 62 && sAddr.substr(sAddr.size() - 6) == ".onion")
|
||||
return CTorV3Service::ValidateOnionAddress(sAddr);
|
||||
|
||||
CTrianglesAddress addressParsed(sAddr);
|
||||
return addressParsed.IsValid();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user