Add post-quantum address selector to desktop wallet
This commit is contained in:
parent
2cf5c796dc
commit
31e4f44475
6 changed files with 92 additions and 34 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
AC_PREREQ([2.69])
|
AC_PREREQ([2.69])
|
||||||
define(_CLIENT_VERSION_MAJOR, 0)
|
define(_CLIENT_VERSION_MAJOR, 0)
|
||||||
define(_CLIENT_VERSION_MINOR, 2)
|
define(_CLIENT_VERSION_MINOR, 2)
|
||||||
define(_CLIENT_VERSION_BUILD, 0)
|
define(_CLIENT_VERSION_BUILD, 1)
|
||||||
define(_CLIENT_VERSION_RC, 1)
|
define(_CLIENT_VERSION_RC, 1)
|
||||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||||
define(_COPYRIGHT_YEAR, 2026)
|
define(_COPYRIGHT_YEAR, 2026)
|
||||||
|
|
|
||||||
|
|
@ -262,6 +262,9 @@ public:
|
||||||
// Get default address type.
|
// Get default address type.
|
||||||
virtual OutputType getDefaultAddressType() = 0;
|
virtual OutputType getDefaultAddressType() = 0;
|
||||||
|
|
||||||
|
//! Return whether post-quantum consensus rules are active.
|
||||||
|
virtual bool isPostQuantumActive() = 0;
|
||||||
|
|
||||||
//! Get max tx fee.
|
//! Get max tx fee.
|
||||||
virtual CAmount getDefaultMaxTxFee() = 0;
|
virtual CAmount getDefaultMaxTxFee() = 0;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -195,28 +195,25 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QCheckBox" name="useBech32">
|
<widget class="QComboBox" name="addressType">
|
||||||
<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>
|
|
||||||
<property name="toolTip">
|
<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>
|
<string>Select the type of receiving address to generate.</string>
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>Generate native segwit (Bech32) address</string>
|
|
||||||
</property>
|
</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>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
|
@ -366,7 +363,7 @@
|
||||||
<tabstops>
|
<tabstops>
|
||||||
<tabstop>reqLabel</tabstop>
|
<tabstop>reqLabel</tabstop>
|
||||||
<tabstop>reqAmount</tabstop>
|
<tabstop>reqAmount</tabstop>
|
||||||
<tabstop>useBech32</tabstop>
|
<tabstop>addressType</tabstop>
|
||||||
<tabstop>reqMessage</tabstop>
|
<tabstop>reqMessage</tabstop>
|
||||||
<tabstop>receiveButton</tabstop>
|
<tabstop>receiveButton</tabstop>
|
||||||
<tabstop>clearButton</tabstop>
|
<tabstop>clearButton</tabstop>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
#include <qt/forms/ui_receivecoinsdialog.h>
|
#include <qt/forms/ui_receivecoinsdialog.h>
|
||||||
|
|
||||||
#include <qt/addresstablemodel.h>
|
#include <qt/addresstablemodel.h>
|
||||||
|
#include <qt/clientmodel.h>
|
||||||
#include <qt/guiutil.h>
|
#include <qt/guiutil.h>
|
||||||
#include <qt/optionsmodel.h>
|
#include <qt/optionsmodel.h>
|
||||||
#include <qt/platformstyle.h>
|
#include <qt/platformstyle.h>
|
||||||
|
|
@ -21,6 +22,7 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QScrollBar>
|
#include <QScrollBar>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
|
#include <QStandardItemModel>
|
||||||
#include <QTextDocument>
|
#include <QTextDocument>
|
||||||
|
|
||||||
ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
|
ReceiveCoinsDialog::ReceiveCoinsDialog(const PlatformStyle *_platformStyle, QWidget *parent) :
|
||||||
|
|
@ -88,11 +90,15 @@ void ReceiveCoinsDialog::setModel(WalletModel *_model)
|
||||||
&QItemSelectionModel::selectionChanged, this,
|
&QItemSelectionModel::selectionChanged, this,
|
||||||
&ReceiveCoinsDialog::recentRequestsView_selectionChanged);
|
&ReceiveCoinsDialog::recentRequestsView_selectionChanged);
|
||||||
|
|
||||||
if (model->wallet().getDefaultAddressType() == OutputType::BECH32) {
|
// Standard SegWit is the default receiving address type.
|
||||||
ui->useBech32->setCheckState(Qt::Checked);
|
ui->addressType->setCurrentIndex(0);
|
||||||
} else {
|
updateAddressTypeAvailability();
|
||||||
ui->useBech32->setCheckState(Qt::Unchecked);
|
|
||||||
}
|
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.
|
// Set the button to be enabled or disabled based on whether the wallet can give out new addresses.
|
||||||
ui->receiveButton->setEnabled(model->wallet().canGetAddresses());
|
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()
|
void ReceiveCoinsDialog::on_receiveButton_clicked()
|
||||||
{
|
{
|
||||||
if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
|
if(!model || !model->getOptionsModel() || !model->getAddressTableModel() || !model->getRecentRequestsTableModel())
|
||||||
|
|
@ -145,14 +180,31 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
|
||||||
QString address;
|
QString address;
|
||||||
QString label = ui->reqLabel->text();
|
QString label = ui->reqLabel->text();
|
||||||
/* Generate new receiving address */
|
/* Generate new receiving address */
|
||||||
OutputType address_type;
|
const int address_type_index = ui->addressType->currentIndex();
|
||||||
if (ui->useBech32->isChecked()) {
|
|
||||||
|
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;
|
address_type = OutputType::BECH32;
|
||||||
} else {
|
break;
|
||||||
address_type = model->wallet().getDefaultAddressType();
|
|
||||||
if (address_type == OutputType::BECH32) {
|
|
||||||
address_type = OutputType::P2SH_SEGWIT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
|
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "", address_type);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,8 @@ public Q_SLOTS:
|
||||||
void accept() override;
|
void accept() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void updateAddressTypeAvailability();
|
||||||
|
|
||||||
Ui::ReceiveCoinsDialog *ui;
|
Ui::ReceiveCoinsDialog *ui;
|
||||||
WalletModel *model;
|
WalletModel *model;
|
||||||
QMenu *contextMenu;
|
QMenu *contextMenu;
|
||||||
|
|
|
||||||
|
|
@ -454,6 +454,10 @@ public:
|
||||||
bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); }
|
bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); }
|
||||||
bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); }
|
bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); }
|
||||||
OutputType getDefaultAddressType() override { return m_wallet->m_default_address_type; }
|
OutputType getDefaultAddressType() override { return m_wallet->m_default_address_type; }
|
||||||
|
bool isPostQuantumActive() override
|
||||||
|
{
|
||||||
|
return m_wallet->chain().isDeploymentActive(Consensus::DEPLOYMENT_PQR);
|
||||||
|
}
|
||||||
CAmount getDefaultMaxTxFee() override { return m_wallet->m_default_max_tx_fee; }
|
CAmount getDefaultMaxTxFee() override { return m_wallet->m_default_max_tx_fee; }
|
||||||
void remove() override
|
void remove() override
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue