diff --git a/configure.ac b/configure.ac
index 53d1a89..00e51fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
AC_PREREQ([2.69])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 2)
-define(_CLIENT_VERSION_BUILD, 0)
+define(_CLIENT_VERSION_BUILD, 1)
define(_CLIENT_VERSION_RC, 1)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2026)
diff --git a/src/interfaces/wallet.h b/src/interfaces/wallet.h
index f507047..16743e6 100644
--- a/src/interfaces/wallet.h
+++ b/src/interfaces/wallet.h
@@ -262,6 +262,9 @@ public:
// Get default address type.
virtual OutputType getDefaultAddressType() = 0;
+ //! Return whether post-quantum consensus rules are active.
+ virtual bool isPostQuantumActive() = 0;
+
//! Get max tx fee.
virtual CAmount getDefaultMaxTxFee() = 0;
diff --git a/src/qt/forms/receivecoinsdialog.ui b/src/qt/forms/receivecoinsdialog.ui
index 671f399..7eae10a 100644
--- a/src/qt/forms/receivecoinsdialog.ui
+++ b/src/qt/forms/receivecoinsdialog.ui
@@ -195,28 +195,25 @@
-
-
-
-
- 0
- 0
-
-
-
-
- 1000
- 16777215
-
-
-
- Qt::StrongFocus
-
+
- 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.
-
-
- Generate native segwit (Bech32) address
+ Select the type of receiving address to generate.
+
-
+
+ Standard (vtx1q...)
+
+
+ -
+
+ ML-DSA (vtx1z...)
+
+
+ -
+
+ SLH-DSA (vtx1r...)
+
+
-
@@ -366,7 +363,7 @@
reqLabel
reqAmount
- useBech32
+ addressType
reqMessage
receiveButton
clearButton
diff --git a/src/qt/receivecoinsdialog.cpp b/src/qt/receivecoinsdialog.cpp
index c55136c..be65143 100644
--- a/src/qt/receivecoinsdialog.cpp
+++ b/src/qt/receivecoinsdialog.cpp
@@ -9,6 +9,7 @@
#include
#include
+#include
#include
#include
#include
@@ -21,6 +22,7 @@
#include
#include
#include
+#include
#include
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(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);
diff --git a/src/qt/receivecoinsdialog.h b/src/qt/receivecoinsdialog.h
index 8f90893..6786ed6 100644
--- a/src/qt/receivecoinsdialog.h
+++ b/src/qt/receivecoinsdialog.h
@@ -51,6 +51,8 @@ public Q_SLOTS:
void accept() override;
private:
+ void updateAddressTypeAvailability();
+
Ui::ReceiveCoinsDialog *ui;
WalletModel *model;
QMenu *contextMenu;
diff --git a/src/wallet/interfaces.cpp b/src/wallet/interfaces.cpp
index 497912d..19292d5 100644
--- a/src/wallet/interfaces.cpp
+++ b/src/wallet/interfaces.cpp
@@ -454,6 +454,10 @@ public:
bool hasExternalSigner() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER); }
bool privateKeysDisabled() override { return m_wallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS); }
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; }
void remove() override
{