Add post-quantum address selector to desktop wallet

This commit is contained in:
Capri 2026-09-01 17:57:42 +00:00
commit 31e4f44475
Signed by: VextaProject
SSH key fingerprint: SHA256:739BZv8LvIDY2tR7lXLy/IQ6MaGTQtYcG9GNvCjmpVM
6 changed files with 92 additions and 34 deletions

View file

@ -195,28 +195,25 @@
</widget>
</item>
<item>
<widget class="QCheckBox" name="useBech32">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>1000</width>
<height>16777215</height>
</size>
</property>
<property name="focusPolicy">
<enum>Qt::StrongFocus</enum>
</property>
<widget class="QComboBox" name="addressType">
<property name="toolTip">
<string>Native segwit addresses (aka Bech32 or BIP-173) reduce your transaction fees later on and offer better protection against typos, but old wallets don't support them. When unchecked, an address compatible with older wallets will be created instead.</string>
</property>
<property name="text">
<string>Generate native segwit (Bech32) address</string>
<string>Select the type of receiving address to generate.</string>
</property>
<item>
<property name="text">
<string>Standard (vtx1q...)</string>
</property>
</item>
<item>
<property name="text">
<string>ML-DSA (vtx1z...)</string>
</property>
</item>
<item>
<property name="text">
<string>SLH-DSA (vtx1r...)</string>
</property>
</item>
</widget>
</item>
<item>
@ -366,7 +363,7 @@
<tabstops>
<tabstop>reqLabel</tabstop>
<tabstop>reqAmount</tabstop>
<tabstop>useBech32</tabstop>
<tabstop>addressType</tabstop>
<tabstop>reqMessage</tabstop>
<tabstop>receiveButton</tabstop>
<tabstop>clearButton</tabstop>

View file

@ -9,6 +9,7 @@
#include <qt/forms/ui_receivecoinsdialog.h>
#include <qt/addresstablemodel.h>
#include <qt/clientmodel.h>
#include <qt/guiutil.h>
#include <qt/optionsmodel.h>
#include <qt/platformstyle.h>
@ -21,6 +22,7 @@
#include <QMessageBox>
#include <QScrollBar>
#include <QSettings>
#include <QStandardItemModel>
#include <QTextDocument>
ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
@ -88,11 +90,15 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
&QItemSelectionModel::selectionChanged, this,
&ReceiveCoinsDialog::recentRequestsView_selectionChanged);
if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
ui->useBech32->setCheckState(Qt::Checked);
} else {
ui->useBech32->setCheckState(Qt::Unchecked);
}
// Standard SegWit is the default receiving address type.
ui->addressType->setCurrentIndex(0);
updateAddressTypeAvailability();
connect(&model->clientModel(), &ClientModel::numBlocksChanged,
this,
[this](int, const QDateTime&, double, bool, SynchronizationState) {
updateAddressTypeAvailability();
});
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
ui->receiveButton->setEnabled(model->wallet().canGetAddresses());
@ -137,6 +143,35 @@ void ReceiveCoinsDialog::updateDisplayUnit()
}
}
void ReceiveCoinsDialog::updateAddressTypeAvailability()
{
if (!model) {
return;
}
const bool pq_active = model->wallet().isPostQuantumActive();
auto* item_model = qobject_cast<QStandardItemModel*>(ui->addressType->model());
if (!item_model) {
return;
}
for (int row : {1, 2}) {
if (auto* item = item_model->item(row)) {
item->setEnabled(pq_active);
}
}
if (!pq_active && ui->addressType->currentIndex() != 0) {
ui->addressType->setCurrentIndex(0);
}
ui->addressType->setToolTip(
pq_active
? tr("Select the type of receiving address to generate.")
: tr("Quantum-resistant address types become available when PQR activates at block 6000."));
}
void ReceiveCoinsDialog::on_receiveButton_clicked()
{
if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
@ -145,14 +180,31 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
QString address;
QString label = ui->reqLabel->text();
/* Generate new receiving address */
OutputType address_type;
if (ui->useBech32->isChecked()) {
const int address_type_index = ui->addressType->currentIndex();
if ((address_type_index == 1 || address_type_index == 2) &&
!model->wallet().isPostQuantumActive()) {
QMessageBox::warning(
this,
windowTitle(),
tr("Quantum-resistant addresses will become available when PQR activates at block 6000."),
QMessageBox::Ok,
QMessageBox::Ok);
return;
}
OutputType address_type = OutputType::BECH32;
switch (address_type_index) {
case 1:
address_type = OutputType::MLDSA;
break;
case 2:
address_type = OutputType::SLHDSA;
break;
case 0:
default:
address_type = OutputType::BECH32;
} else {
address_type = model->wallet().getDefaultAddressType();
if (address_type == OutputType::BECH32) {
address_type = OutputType::P2SH_SEGWIT;
}
break;
}
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);

View file

@ -51,6 +51,8 @@ public Q_SLOTS:
void accept() override;
private:
void updateAddressTypeAvailability();
Ui::ReceiveCoinsDialog *ui;
WalletModel *model;
QMenu *contextMenu;