Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

backport: bitcoin#16528, #18027, #18782, #18787, #18805, #18888, #19502, #19077, #20125, #20153, #20198, #20262, #20266, #23608, #29510 - native descriptor wallets #5579

Merged
merged 26 commits into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
b02fc0b
fix: counting calculation of internal keys for Descriptor Wallets
knst Feb 29, 2024
bdbd0b1
chore: dashification of descriptor implementation in dash
UdjinM6 Feb 28, 2024
4064334
fix: get receiving address for Descriptor Wallets
knst Mar 2, 2024
f293c04
Merge #16528: Native Descriptor Wallets using DescriptorScriptPubKeyMan
achow101 Jul 16, 2019
c1b94b6
fix: wallet should be unlocked before generating keys for Descriptor …
knst Feb 11, 2024
76e08f9
Merge #18027: "PSBT Operations" dialog
meshcollider Jun 21, 2020
baa6959
Merge #18805: tests: Add missing sync_all to wallet_importdescriptors.py
Apr 28, 2020
0949c08
Merge #18782: wallet: Make sure no DescriptorScriptPubKeyMan or Walle…
meshcollider May 5, 2020
c864582
Merge #18787: wallet: descriptor wallet release notes and cleanups
meshcollider May 22, 2020
c995e5d
Merge #20266: wallet: fix change detection of imported internal descr…
laanwj Nov 9, 2020
b18351e
Merge #20153: wallet: do not import a descriptor with hardened deriva…
laanwj Nov 9, 2020
14121ec
Merge #18888: test: Remove RPCOverloadWrapper boilerplate
May 13, 2020
fa30777
Merge #20198: Show name, format and if uses descriptors in bitcoin-wa…
Oct 21, 2020
343d4b0
fix: descriptor wallets follow-up for bitcoin#20156: Make sqlite supp…
knst Sep 28, 2023
7d55046
Merge #20125: rpc, wallet: Expose database format in getwalletinfo
meshcollider Oct 19, 2020
a340ad6
Merge #20262: tests: Skip --descriptor tests if sqlite is not compiled
meshcollider Nov 1, 2020
f6b3614
fix: descriptor wallets follow-up to merge bitcoin#20202: Make BDB su…
knst Sep 28, 2023
2439247
Merge bitcoin/bitcoin#23608: test: fix `feature_rbf.py --descriptors`…
fanquake Nov 28, 2021
c172605
Merge #19077: wallet: Add sqlite as an alternative wallet database an…
meshcollider Oct 15, 2020
2de7aec
Merge #19502: Bugfix: Wallet: Soft-fail exceptions within ListWalletD…
meshcollider Nov 11, 2020
e542cd2
fix: missing changes from bitcoin#21634
knst Feb 16, 2024
45fc8a4
fix: autobackup influences an exclusive locks made by SQLite
knst Feb 16, 2024
4ba44fa
fix: skip interface_zmq.py which is not ready to work without bdb
knst Feb 16, 2024
da8e563
fix: skip functional tests which requires BDB if no bdb (see 20267)
knst Feb 16, 2024
85fa370
refactor: use Params().ExtCoinType() for descriptor wallets
knst Feb 27, 2024
6b71f27
Merge bitcoin/bitcoin#29510: wallet: `getrawchangeaddress` and `getne…
achow101 Feb 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/build-unix.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Optional dependencies:
gmp | Optimized math routines | Arbitrary precision arithmetic library
miniupnpc | UPnP Support | Firewall-jumping support
libnatpmp | NAT-PMP Support | Firewall-jumping support
libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled)
libdb4.8 | Berkeley DB | Optional, wallet storage (only needed when wallet enabled)
qt | GUI | GUI toolkit (only needed when GUI enabled)
libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled)
libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.0.0)
Expand Down
119 changes: 119 additions & 0 deletions doc/release-notes-16528.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
Wallet
------

### Experimental Descriptor Wallets

Please note that Descriptor Wallets are still experimental and not all expected functionality
is available. Additionally there may be some bugs and current functions may change in the future.
Bugs and missing functionality can be reported to the [issue tracker](https://github.com/dashpay/dash/issues).

v21 introduces a new type of wallet - Descriptor Wallets. Descriptor Wallets store
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

v21 or v20.1?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated to 20.1 for now. I will bump later to 20.2 or 21 depends how fast 20.1 will be released.

scriptPubKey information using descriptors. This is in contrast to the Legacy Wallet
structure where keys are used to generate scriptPubKeys and addresses. Because of this
shift to being script based instead of key based, many of the confusing things that Legacy
Wallets do are not possible with Descriptor Wallets. Descriptor Wallets use a definition
of "mine" for scripts which is simpler and more intuitive than that used by Legacy Wallets.
Descriptor Wallets also uses different semantics for watch-only things and imports.

As Descriptor Wallets are a new type of wallet, their introduction does not affect existing wallets.
Users who already have a Dash Core wallet can continue to use it as they did before without
any change in behavior. Newly created Legacy Wallets (which is the default type of wallet) will
behave as they did in previous versions of Dash Core.

The differences between Descriptor Wallets and Legacy Wallets are largely limited to non user facing
things. They are intended to behave similarly except for the import/export and watchonly functionality
as described below.

#### Creating Descriptor Wallets

Descriptor Wallets are not created by default. They must be explicitly created using the
`createwallet` RPC or via the GUI. A `descriptors` option has been added to `createwallet`.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dropped workaround to make non-breaking v20.1 365feb6

Should probably mention that it's a breaking change then

Setting `descriptors` to `true` will create a Descriptor Wallet instead of a Legacy Wallet.

In the GUI, a checkbox has been added to the Create Wallet Dialog to indicate that a
Descriptor Wallet should be created.

Without those options being set, a Legacy Wallet will be created instead.

#### `IsMine` Semantics

`IsMine` refers to the function used to determine whether a script belongs to the wallet.
This is used to determine whether an output belongs to the wallet. `IsMine` in Legacy Wallets
returns true if the wallet would be able to sign an input that spends an output with that script.
Since keys can be involved in a variety of different scripts, this definition for `IsMine` can
lead to many unexpected scripts being considered part of the wallet.

With Descriptor Wallets, descriptors explicitly specify the set of scripts that are owned by
the wallet. Since descriptors are deterministic and easily enumerable, users will know exactly
what scripts the wallet will consider to belong to it. Additionally the implementation of `IsMine`
in Descriptor Wallets is far simpler than for Legacy Wallets. Notably, in Legacy Wallets, `IsMine`
allowed for users to take one type of address (e.g. P2PKH), mutate it into another address type
and the wallet would still detect outputs sending to the new address type
even without that address being requested from the wallet. Descriptor Wallets does not
allow for this and will only watch for the addresses that were explicitly requested from the wallet.

These changes to `IsMine` will make it easier to reason about what scripts the wallet will
actually be watching for in outputs. However for the vast majority of users, this change is
largely transparent and will not have noticeable effect.

#### Imports and Exports

In Legacy Wallets, raw scripts and keys could be imported to the wallet. Those imported scripts
and keys are treated separately from the keys generated by the wallet. This complicates the `IsMine`
logic as it has to distinguish between spendable and watchonly.

Descriptor Wallets handle importing scripts and keys differently. Only complete descriptors can be
imported. These descriptors are then added to the wallet as if it were a descriptor generated by
the wallet itself. This simplifies the `IsMine` logic so that it no longer has to distinguish
between spendable and watchonly. As such, the watchonly model for Descriptor Wallets is also
different and described in more detail in the next section.

To import into a Descriptor Wallet, a new `importdescriptors` RPC has been added that uses a syntax
similar to that of `importmulti`.

As Legacy Wallets and Descriptor Wallets use different mechanisms for storing and importing scripts and keys
the existing import RPCs have been disabled for descriptor wallets.
New export RPCs for Descriptor Wallets have not yet been added.

The following RPCs are disabled for Descriptor Wallets:

* importprivkey
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the following Dash-specific RPCs also be disabled for descriptor wallets?

  • importelectrumwallet (would require additional logic to transform into descriptors)
  • upgradetohd (does current HD wallet functionality play well with descriptors as a hybrid wallet?)
  • dumphdinfo (see above)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

upgradetohd (does current HD wallet functionality play well with descriptors as a hybrid wallet?)

I think that's opposite impossible to have non-hd wallet for descriptor wallet,but upgradetohd lets also to change seed, so, I guess it should be enabled.

dumphdinfo also should be available as well.

importelectrumwallet is added to a list of exception

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dumphdwallet does not work

dumphdwallet enforces the legacy wallet requirement and should be considered disabled. upgradetohd correctly describes the wallet as HD-capable so it's fine as-is.

* importpubkey
* importaddress
* importwallet
* importelectrumwallet
* dumpprivkey
* dumpwallet
* dumphdinfo
* importmulti
* addmultisigaddress

#### Watchonly Wallets

A Legacy Wallet contains both private keys and scripts that were being watched.
Those watched scripts would not contribute to your normal balance. In order to see the watchonly
balance and to use watchonly things in transactions, an `include_watchonly` option was added
to many RPCs that would allow users to do that. However it is easy to forget to include this option.

Descriptor Wallets move to a per-wallet watchonly model. Instead an entire wallet is considered to be
watchonly depending on whether it was created with private keys disabled. This eliminates the need
to distinguish between things that are watchonly and things that are not within a wallet itself.

This change does have a caveat. If a Descriptor Wallet with private keys *enabled* has
a multiple key descriptor without all of the private keys (e.g. `multi(...)` with only one private key),
then the wallet will fail to sign and broadcast transactions. Such wallets would need to use the PSBT
workflow but the typical GUI Send, `sendtoaddress`, etc. workflows would still be available, just
non-functional.

This issue is worsened if the wallet contains both single key (e.g. `pkh(...)`) descriptors and such
multiple key descriptors as some transactions could be signed and broadast and others not. This is
due to some transactions containing only single key inputs, while others would contain both single
key and multiple key inputs, depending on which are available and how the coin selection algorithm
selects inputs. However this is not considered to be a supported use case; multisigs
should be in their own wallets which do not already have descriptors. Although users cannot export
descriptors with private keys for now as explained earlier.


## RPC changes
- `createwallet` has changed list of arguments: `createwallet "wallet_name" ( disable_private_keys blank "passphrase" avoid_reuse descriptors load_on_startup )`
`load_on_startup` used to be an argument 5 but now has a number 6.
3 changes: 3 additions & 0 deletions src/interfaces/wallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ class Wallet
// Remove wallet.
virtual void remove() = 0;

//! Return whether is a legacy wallet
virtual bool isLegacy() = 0;

//! Register handler for unload message.
using UnloadFn = std::function<void()>;
virtual std::unique_ptr<Handler> handleUnload(UnloadFn fn) = 0;
Expand Down
5 changes: 5 additions & 0 deletions src/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,11 @@ struct CExtPubKey {
a.pubkey == b.pubkey;
}

friend bool operator!=(const CExtPubKey &a, const CExtPubKey &b)
{
return !(a == b);
}

void Encode(unsigned char code[BIP32_EXTKEY_SIZE]) const;
void Decode(const unsigned char code[BIP32_EXTKEY_SIZE]);
bool Derive(CExtPubKey& out, unsigned int nChild) const;
Expand Down
15 changes: 15 additions & 0 deletions src/qt/createwalletdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ CreateWalletDialog::CreateWalletDialog(QWidget* parent) :
ui->encrypt_wallet_checkbox->setChecked(false);
}
});

#ifndef USE_SQLITE
ui->descriptor_checkbox->setToolTip(tr("Compiled without sqlite support (required for descriptor wallets)"));
ui->descriptor_checkbox->setEnabled(false);
ui->descriptor_checkbox->setChecked(false);
#endif
#ifndef USE_BDB
ui->descriptor_checkbox->setEnabled(false);
ui->descriptor_checkbox->setChecked(true);
#endif
}

CreateWalletDialog::~CreateWalletDialog()
Expand All @@ -77,3 +87,8 @@ bool CreateWalletDialog::isMakeBlankWalletChecked() const
{
return ui->blank_wallet_checkbox->isChecked();
}

bool CreateWalletDialog::isDescriptorWalletChecked() const
{
return ui->descriptor_checkbox->isChecked();
}
1 change: 1 addition & 0 deletions src/qt/createwalletdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class CreateWalletDialog : public QDialog
bool isEncryptWalletChecked() const;
bool isDisablePrivateKeysChecked() const;
bool isMakeBlankWalletChecked() const;
bool isDescriptorWalletChecked() const;

private:
Ui::CreateWalletDialog *ui;
Expand Down
18 changes: 18 additions & 0 deletions src/qt/forms/createwalletdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="descriptor_checkbox">
<property name="geometry">
<rect>
<x>20</x>
<y>140</y>
<width>171</width>
<height>22</height>
</rect>
</property>
<property name="toolTip">
<string>Use descriptors for scriptPubKey management</string>
</property>
<property name="text">
<string>Descriptor Wallet</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
Expand Down
36 changes: 22 additions & 14 deletions src/qt/overviewpage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -208,21 +208,29 @@ void OverviewPage::setBalance(const interfaces::WalletBalances& balances)
{
int unit = walletModel->getOptionsModel()->getDisplayUnit();
m_balances = balances;
if (walletModel->wallet().privateKeysDisabled()) {
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
if (walletModel->wallet().isLegacy()) {
if (walletModel->wallet().privateKeysDisabled()) {
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
} else {
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.anonymized_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
}
} else {
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.anonymized_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchAvailable->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchPending->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelWatchTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.watch_only_balance + balances.unconfirmed_watch_only_balance + balances.immature_watch_only_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelBalance->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelUnconfirmed->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.unconfirmed_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelImmature->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelAnonymized->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.anonymized_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
ui->labelTotal->setText(BitcoinUnits::floorHtmlWithPrivacy(unit, balances.balance + balances.unconfirmed_balance + balances.immature_balance, BitcoinUnits::SeparatorStyle::ALWAYS, m_privacy));
}
// only show immature (newly mined) balance if it's non-zero, so as not to complicate things
// for the non-mining users
Expand Down
43 changes: 33 additions & 10 deletions src/qt/receivecoinsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,17 +137,40 @@ void ReceiveCoinsDialog::on_receiveButton_clicked()
QString label = ui->reqLabel->text();
/* Generate new receiving address */
address = model->getAddressTableModel()->addRow(AddressTableModel::Receive, label, "");
SendCoinsRecipient info(address, label,
ui->reqAmount->value(), ui->reqMessage->text());
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModel(model);
dialog->setInfo(info);
dialog->show();
clear();

/* Store request for later reference */
model->getRecentRequestsTableModel()->addNewRequest(info);
switch(model->getAddressTableModel()->getEditStatus())
{
case AddressTableModel::EditStatus::OK: {
// Success
SendCoinsRecipient info(address, label,
ui->reqAmount->value(), ui->reqMessage->text());
ReceiveRequestDialog *dialog = new ReceiveRequestDialog(this);
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setModel(model);
dialog->setInfo(info);
dialog->show();

/* Store request for later reference */
model->getRecentRequestsTableModel()->addNewRequest(info);
break;
}
case AddressTableModel::EditStatus::WALLET_UNLOCK_FAILURE:
QMessageBox::critical(this, windowTitle(),
tr("Could not unlock wallet."),
QMessageBox::Ok, QMessageBox::Ok);
break;
case AddressTableModel::EditStatus::KEY_GENERATION_FAILURE:
QMessageBox::critical(this, windowTitle(),
tr("Could not generate new address"),
QMessageBox::Ok, QMessageBox::Ok);
break;
// These aren't valid return values for our action
case AddressTableModel::EditStatus::INVALID_ADDRESS:
case AddressTableModel::EditStatus::DUPLICATE_ADDRESS:
case AddressTableModel::EditStatus::NO_CHANGES:
assert(false);
}
clear();
}

void ReceiveCoinsDialog::on_recentRequestsView_doubleClicked(const QModelIndex &index)
Expand Down
3 changes: 3 additions & 0 deletions src/qt/walletcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@ void CreateWalletActivity::createWallet()
if (m_create_wallet_dialog->isMakeBlankWalletChecked()) {
flags |= WALLET_FLAG_BLANK_WALLET;
}
if (m_create_wallet_dialog->isDescriptorWalletChecked()) {
flags |= WALLET_FLAG_DESCRIPTORS;
}

QTimer::singleShot(500, worker(), [this, name, flags] {
std::unique_ptr<interfaces::Wallet> wallet = node().walletLoader().createWallet(name, m_passphrase, flags, m_error_message, m_warning_message);
Expand Down
4 changes: 3 additions & 1 deletion src/rpc/client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "importpubkey", 2, "rescan" },
{ "importmulti", 0, "requests" },
{ "importmulti", 1, "options" },
{ "importdescriptors", 0, "requests" },
{ "verifychain", 0, "checklevel" },
{ "verifychain", 1, "nblocks" },
{ "getblockstats", 0, "hash_or_height" },
Expand Down Expand Up @@ -208,7 +209,8 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "createwallet", 1, "disable_private_keys"},
{ "createwallet", 2, "blank"},
{ "createwallet", 4, "avoid_reuse"},
{ "createwallet", 5, "load_on_startup"},
{ "createwallet", 5, "descriptors"},
{ "createwallet", 6, "load_on_startup"},
knst marked this conversation as resolved.
Show resolved Hide resolved
{ "loadwallet", 1, "load_on_startup"},
{ "unloadwallet", 1, "load_on_startup"},
{ "upgradetohd", 3, "rescan"},
Expand Down
Loading
Loading