From d2c1033d8a84a3aa4056f1584b3b5273b64f5497 Mon Sep 17 00:00:00 2001 From: Krystie Date: Sat, 27 Jun 2026 19:25:06 -0700 Subject: [PATCH] feat: I2P status panel in Qt wallet UI Add .b32.i2p address display alongside existing Tor .onion address in the wallet status bar. Purple [I2P] indicator shows router state: - Purple: I2P active with valid destination - Yellow: router running, building tunnels - Hidden: I2P not active Updates every 5s via timer, parallel to updateOnionAddress(). --- src/qt/trianglesgui.cpp | 50 +++++++++++++++++++++++++++++++++++++++++ src/qt/trianglesgui.h | 3 +++ 2 files changed, 53 insertions(+) diff --git a/src/qt/trianglesgui.cpp b/src/qt/trianglesgui.cpp index c29051c..c966987 100644 --- a/src/qt/trianglesgui.cpp +++ b/src/qt/trianglesgui.cpp @@ -43,6 +43,7 @@ #include "wallet.h" #include "tor/tor_embedded.h" #include "tor/onion_v3.h" +#include "i2p/i2p_embedded.h" #ifdef Q_OS_MAC #include "macdockiconhandler.h" @@ -357,6 +358,25 @@ TrianglesGUI::TrianglesGUI(bool fIsTestnet, QWidget *parent): timerOnion->start(5000); updateOnionAddress(); + // I2P address in status bar (hidden until populated) + labelI2PAddress = new QLabel(this); + labelI2PAddress->setObjectName("label_i2p"); + labelI2PAddress->setStyleSheet("color: #6a4cff; padding-left: 4px;"); + labelI2PAddress->setVisible(false); + labelI2PAddress->setCursor(Qt::PointingHandCursor); + statusBar()->addPermanentWidget(labelI2PAddress); + + labelI2PIcon = new QLabel(this); + labelI2PIcon->setObjectName("label_i2p_icon"); + labelI2PIcon->setText("[I2P]"); + labelI2PIcon->setVisible(false); + statusBar()->addPermanentWidget(labelI2PIcon); + + QTimer *timerI2P = new QTimer(this); + connect(timerI2P, SIGNAL(timeout()), this, SLOT(updateI2PAddress())); + timerI2P->start(5000); + updateI2PAddress(); + QTimer *timerShutdown = new QTimer(this); connect(timerShutdown, SIGNAL(timeout()), this, SLOT(detectShutdown())); timerShutdown->start(200); @@ -1803,6 +1823,36 @@ void TrianglesGUI::updateOnionAddress() labelOnionAddress->setVisible(true); } +void TrianglesGUI::updateI2PAddress() +{ + std::string i2pAddress = CI2PEmbedded::GetInstance()->GetI2PAddress(); + bool hasI2P = CI2PEmbedded::GetInstance()->IsRunning() && !i2pAddress.empty(); + + // I2P indicator + if (hasI2P) { + labelI2PIcon->setStyleSheet("color: #6a4cff; font-weight: bold;"); + labelI2PIcon->setToolTip(tr("I2P router active")); + labelI2PIcon->setVisible(true); + } else if (CI2PEmbedded::GetInstance()->IsRunning()) { + labelI2PIcon->setStyleSheet("color: #aaaa00; font-weight: bold;"); + labelI2PIcon->setToolTip(tr("I2P router running (building tunnels...)")); + labelI2PIcon->setVisible(true); + } else { + labelI2PIcon->setStyleSheet("color: #555555; font-weight: bold;"); + labelI2PIcon->setToolTip(tr("I2P not active")); + labelI2PIcon->setVisible(false); + } + + if (!hasI2P) { + labelI2PAddress->setVisible(false); + return; + } + + labelI2PAddress->setText(QString::fromStdString(i2pAddress)); + labelI2PAddress->setToolTip(tr("This node's I2P .b32.i2p address. Selectable — right-click to copy.")); + labelI2PAddress->setVisible(true); +} + void TrianglesGUI::on_bHelp_clicked() { diff --git a/src/qt/trianglesgui.h b/src/qt/trianglesgui.h index 8f61e0e..ff50d1f 100644 --- a/src/qt/trianglesgui.h +++ b/src/qt/trianglesgui.h @@ -111,6 +111,8 @@ private: QLabel *labelBlocksIcon; QLabel *labelOnionAddress; QLabel *labelV3Icon; + QLabel *labelI2PAddress; + QLabel *labelI2PIcon; QLabel *progressBarLabel; QProgressBar *progressBar; @@ -178,6 +180,7 @@ public slots: void setWalletTransactionSyncState(bool syncing); void setWalletTransactionSyncProgress(bool syncing, int pendingNotifications); void updateOnionAddress(); + void updateI2PAddress(); /** Notify the user of an error in the network or transaction handling code. */ void error(const QString &title, const QString &message, bool modal);