Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 2 additions & 4 deletions doc/managing-wallets.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,9 @@ In the GUI, the `Create a new wallet` button is displayed on the main screen whe
The following command, for example, creates a descriptor wallet. More information about this command may be found by running `dash-cli help createwallet`.

```
$ dash-cli -named createwallet wallet_name="wallet-01" descriptors=true
$ dash-cli createwallet "wallet-01"
```

The `descriptors` parameter can be omitted if the intention is to create a legacy wallet. For now, the default type is the legacy wallet, but that is expected to change in a future release.

By default, wallets are created in the `wallets` folder of the data directory, which varies by operating system, as shown below. The user can change the default by using the `-datadir` or `-walletdir` initialization parameters.

| Operating System | Default wallet directory |
Expand Down Expand Up @@ -54,7 +52,7 @@ Only the wallet's private key is encrypted. All other wallet information, such a
The wallet's private key can also be encrypted in the `createwallet` command via the `passphrase` argument:

```
$ dash-cli -named createwallet wallet_name="wallet-01" descriptors=true passphrase="passphrase"
$ dash-cli -named createwallet wallet_name="wallet-01" passphrase="passphrase"
```

Note that if the passphrase is lost, all the coins in the wallet will also be lost forever.
Expand Down
4 changes: 2 additions & 2 deletions doc/multisig-tutorial.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ These three wallets should not be used directly for privacy reasons (public key
```bash
for ((n=1;n<=3;n++))
do
./src/dash-cli -testnet -named createwallet wallet_name="participant_${n}" descriptors=true
./src/dash-cli -testnet createwallet "participant_${n}"
done
```

Expand Down Expand Up @@ -105,7 +105,7 @@ Then import the descriptors created in the previous step using the `importdescri
After that, `getwalletinfo` can be used to check if the wallet was created successfully.

```bash
./src/dash-cli -testnet -named createwallet wallet_name="multisig_wallet_01" disable_private_keys=true blank=true descriptors=true
./src/dash-cli -testnet -named createwallet wallet_name="multisig_wallet_01" disable_private_keys=true blank=true

./src/dash-cli -testnet -rpcwallet="multisig_wallet_01" importdescriptors "$multisig_desc"

Expand Down
21 changes: 21 additions & 0 deletions doc/release-notes-7204.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Notable changes
===============

Updated RPCs
------------


Changes to wallet related RPCs can be found in the Wallet section below.
Copy link

@coderabbitai coderabbitai bot Mar 6, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Hyphenate “wallet-related”.

Line 8 should use the compound adjective form for consistency and readability.

Suggested wording
-Changes to wallet related RPCs can be found in the Wallet section below.
+Changes to wallet-related RPCs can be found in the Wallet section below.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Changes to wallet related RPCs can be found in the Wallet section below.
Changes to wallet-related RPCs can be found in the Wallet section below.
🧰 Tools
🪛 LanguageTool

[grammar] ~8-~8: Use a hyphen to join words.
Context: ...ed RPCs ------------ Changes to wallet related RPCs can be found in the Wallet ...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@doc/release-notes-7204.md` at line 8, Update the sentence "Changes to wallet
related RPCs can be found in the Wallet section below." to use the compound
adjective form by replacing "wallet related" with "wallet-related" so it reads
"Changes to wallet-related RPCs can be found in the Wallet section below.";
ensure only that hyphenation is changed and surrounding punctuation/spacing
remains unchanged.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

it's copy-paste of bitcoin core's release note. I'd like to see human's feedback here

Copy link

Choose a reason for hiding this comment

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

@knst, confirmed — the phrase is a direct copy-paste from Bitcoin Core. Bitcoin Core's v23.0 release notes use the exact unhyphenated form "Changes to wallet related RPCs can be found in the Wallet section below." The same wording appears verbatim across v24.0.1, v26.0, and v25.0 release notes as well.

So while the LanguageTool grammar flag is technically valid, Bitcoin Core has consistently used this unhyphenated style across multiple releases. For a downstream project like Dash Core that tracks Bitcoin Core's release notes, keeping the text identical to upstream is a reasonable choice — it eases future diffs and attribution. I'll defer to your judgment on whether to apply the hyphen or preserve the upstream wording as-is.


✏️ Learnings added
Learnt from: knst
Repo: dashpay/dash PR: 7204
File: doc/release-notes-7204.md:8-8
Timestamp: 2026-03-06T08:37:29.753Z
Learning: In the Dash Core repository, release notes text copied verbatim from Bitcoin Core upstream (e.g. "Changes to wallet related RPCs can be found in the Wallet section below." in doc/release-notes-7204.md) should be kept identical to the upstream source to ease future diffs and attribution. Do not flag grammar/style issues in such copy-pasted upstream text.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


Wallet
------

- Descriptor wallets are now the default wallet type. Newly created wallets
will use descriptors unless `descriptors=false` is set during `createwallet`, or
the `Descriptor wallet` checkbox is unchecked in the GUI. (dash#7204)

Note that wallet RPC commands like `importmulti` and `dumpprivkey` cannot be
used with descriptor wallets, so if your client code relies on these commands
without specifying `descriptors=false` during wallet creation, you will need
to update your code.

1 change: 1 addition & 0 deletions src/bitcoin-wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ static void SetupWalletToolArgs(ArgsManager& argsman)
argsman.AddArg("-dumpfile=<file name>", "When used with 'dump', writes out the records to this file. When used with 'createfromdump', loads the records into a new wallet.", ArgsManager::ALLOW_ANY | ArgsManager::DISALLOW_NEGATION, OptionsCategory::OPTIONS);
argsman.AddArg("-debug=<category>", "Output debugging information (default: 0).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);
argsman.AddArg("-descriptors", "Create descriptors wallet. Only for 'create'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-legacy", "Create legacy wallet. Only for 'create'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-format=<format>", "The format of the wallet file to create. Either \"bdb\" or \"sqlite\". Only used with 'createfromdump'", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS);
argsman.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -debug is true, 0 otherwise).", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST);

Expand Down
3 changes: 3 additions & 0 deletions src/qt/forms/createwalletdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,9 @@
<property name="text">
<string>Descriptor Wallet</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
Expand Down
10 changes: 5 additions & 5 deletions src/wallet/rpc/wallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -634,7 +634,7 @@ static RPCHelpMan createwallet()
{"blank", RPCArg::Type::BOOL, RPCArg::Default{false}, "Create a blank wallet. A blank wallet has no keys or HD seed. One can be set using upgradetohd (by mnemonic) or sethdseed (WIF private key)."},
{"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Encrypt the wallet with this passphrase."},
{"avoid_reuse", RPCArg::Type::BOOL, RPCArg::Default{false}, "Keep track of coin reuse, and treat dirty and clean coins differently with privacy considerations in mind."},
{"descriptors", RPCArg::Type::BOOL, RPCArg::Default{false}, "Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation."},
{"descriptors", RPCArg::Type::BOOL, RPCArg::Default{true}, "Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation."},
{"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED_NAMED_ARG, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},
{"external_signer", RPCArg::Type::BOOL, RPCArg::Default{false}, "Use an external signer such as a hardware wallet. Requires -signer to be configured. Wallet creation will fail if keys cannot be fetched. Requires disable_private_keys and descriptors set to true."},
},
Expand Down Expand Up @@ -676,13 +676,13 @@ static RPCHelpMan createwallet()
if (!request.params[4].isNull() && request.params[4].get_bool()) {
flags |= WALLET_FLAG_AVOID_REUSE;
}
if (!request.params[5].isNull() && request.params[5].get_bool()) {
if (!request.params[5].isNull() && request.params[6].isNull()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "The createwallet RPC requires specifying the 'load_on_startup' flag when param 'descriptors' is specified. Dash Core v21 introduced this requirement due to breaking changes in the createwallet RPC.");
}
if (request.params[5].isNull() || request.params[5].get_bool()) {
#ifndef USE_SQLITE
throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)");
#endif
if (request.params[6].isNull()) {
throw JSONRPCError(RPC_INVALID_PARAMETER, "The createwallet RPC requires specifying the 'load_on_startup' flag when creating descriptor wallets. Dash Core v21 introduced this requirement due to breaking changes in the createwallet RPC.");
}
flags |= WALLET_FLAG_DESCRIPTORS;
}
if (!request.params[7].isNull() && request.params[7].get_bool()) {
Expand Down
18 changes: 17 additions & 1 deletion src/wallet/wallettool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,10 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
tfm::format(std::cerr, "The -descriptors option can only be used with the 'create' command.\n");
return false;
}
if (args.IsArgSet("-legacy") && command != "create") {
tfm::format(std::cerr, "The -legacy option can only be used with the 'create' command.\n");
return false;
}
if (command == "create" && !args.IsArgSet("-wallet")) {
tfm::format(std::cerr, "Wallet name must be provided when creating a new wallet.\n");
return false;
Expand All @@ -145,7 +149,19 @@ bool ExecuteWalletToolFunc(const ArgsManager& args, const std::string& command)
DatabaseOptions options;
ReadDatabaseArgs(args, options);
options.require_create = true;
if (args.GetBoolArg("-descriptors", false)) {
// If -legacy is set, use it. Otherwise default to false.
bool make_legacy = args.GetBoolArg("-legacy", false);
// If neither -legacy nor -descriptors is set, default to true. If -descriptors is set, use its value.
bool make_descriptors = (!args.IsArgSet("-descriptors") && !args.IsArgSet("-legacy")) || (args.IsArgSet("-descriptors") && args.GetBoolArg("-descriptors", true));
if (make_legacy && make_descriptors) {
tfm::format(std::cerr, "Only one of -legacy or -descriptors can be set to true, not both\n");
return false;
}
if (!make_legacy && !make_descriptors) {
tfm::format(std::cerr, "One of -legacy or -descriptors must be set to true (or omitted)\n");
return false;
Comment on lines +152 to +162
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Keep -descriptors=0 and -nodescriptors working as the legacy path.

This now turns an explicit descriptor opt-out into a hard error because both make_legacy and make_descriptors end up false. That is a larger CLI break than just changing the default, and it will break scripts that were already being explicit about creating a BDB wallet.

Compatibility-preserving approach
-        // If -legacy is set, use it. Otherwise default to false.
-        bool make_legacy = args.GetBoolArg("-legacy", false);
-        // If neither -legacy nor -descriptors is set, default to true. If -descriptors is set, use its value.
-        bool make_descriptors = (!args.IsArgSet("-descriptors") && !args.IsArgSet("-legacy")) || (args.IsArgSet("-descriptors") && args.GetBoolArg("-descriptors", true));
-        if (make_legacy && make_descriptors) {
+        const bool legacy_requested = args.GetBoolArg("-legacy", false);
+        const bool descriptors_requested = args.GetBoolArg("-descriptors", true);
+
+        if (legacy_requested && args.IsArgSet("-descriptors") && descriptors_requested) {
             tfm::format(std::cerr, "Only one of -legacy or -descriptors can be set to true, not both\n");
             return false;
         }
-        if (!make_legacy && !make_descriptors) {
-            tfm::format(std::cerr, "One of -legacy or -descriptors must be set to true (or omitted)\n");
-            return false;
-        }
+
+        // Preserve explicit descriptor opt-out for older automation.
+        const bool make_legacy = legacy_requested || (args.IsArgSet("-descriptors") && !descriptors_requested);
+        const bool make_descriptors = !make_legacy;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/wallet/wallettool.cpp` around lines 152 - 162, The CLI logic must
preserve explicit descriptor opt-outs as the legacy path: change the decision so
that make_legacy becomes true when -legacy is true OR when the user explicitly
set -descriptors to false (e.g. -descriptors=0) or provided -nodescriptors, and
make_descriptors becomes true only when descriptors are selected (either by
default when neither flag is set, or when -descriptors=true). Concretely,
compute descriptors_set = args.IsArgSet("-descriptors"), descriptors_val =
args.GetBoolArg("-descriptors", true), legacy_set = args.IsArgSet("-legacy"),
legacy_val = args.GetBoolArg("-legacy", false), nodescriptors_set =
args.IsArgSet("-nodescriptors"); then set make_legacy = legacy_val ||
nodescriptors_set || (descriptors_set && !descriptors_val) and set
make_descriptors = (!descriptors_set && !legacy_set && !nodescriptors_set) ||
(descriptors_set && descriptors_val). Update the checks that use make_legacy and
make_descriptors (the error messages) accordingly.

}
if (make_descriptors) {
options.create_flags |= WALLET_FLAG_DESCRIPTORS;
options.require_format = DatabaseFormat::SQLITE;
}
Expand Down
4 changes: 2 additions & 2 deletions test/functional/tool_wallet.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ def skip_test_if_missing_module(self):

def dash_wallet_process(self, *args):
default_args = ['-datadir={}'.format(self.nodes[0].datadir), '-chain=%s' % self.chain]
if self.options.descriptors and 'create' in args:
default_args.append('-descriptors')
if not self.options.descriptors and 'create' in args:
default_args.append('-legacy')

return subprocess.Popen([self.options.bitcoinwallet] + default_args + list(args), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

Expand Down
Loading