LCOV - code coverage report
Current view: top level - src/wallet/rpc - wallet.cpp (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 510 554 92.1 %
Date: 2022-04-21 14:51:19 Functions: 19 20 95.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 98 124 79.0 %

           Branch data     Line data    Source code
#       1                 :            : // Copyright (c) 2010 Satoshi Nakamoto
#       2                 :            : // Copyright (c) 2009-2021 The Bitcoin Core developers
#       3                 :            : // Distributed under the MIT software license, see the accompanying
#       4                 :            : // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#       5                 :            : 
#       6                 :            : #include <core_io.h>
#       7                 :            : #include <key_io.h>
#       8                 :            : #include <rpc/server.h>
#       9                 :            : #include <rpc/util.h>
#      10                 :            : #include <util/translation.h>
#      11                 :            : #include <wallet/context.h>
#      12                 :            : #include <wallet/receive.h>
#      13                 :            : #include <wallet/rpc/wallet.h>
#      14                 :            : #include <wallet/rpc/util.h>
#      15                 :            : #include <wallet/wallet.h>
#      16                 :            : 
#      17                 :            : #include <optional>
#      18                 :            : 
#      19                 :            : #include <univalue.h>
#      20                 :            : 
#      21                 :            : 
#      22                 :            : namespace wallet {
#      23                 :            : /** Checks if a CKey is in the given CWallet compressed or otherwise*/
#      24                 :            : bool HaveKey(const SigningProvider& wallet, const CKey& key)
#      25                 :          8 : {
#      26                 :          8 :     CKey key2;
#      27                 :          8 :     key2.Set(key.begin(), key.end(), !key.IsCompressed());
#      28 [ +  + ][ -  + ]:          8 :     return wallet.HaveKey(key.GetPubKey().GetID()) || wallet.HaveKey(key2.GetPubKey().GetID());
#      29                 :          8 : }
#      30                 :            : 
#      31                 :            : static RPCHelpMan getwalletinfo()
#      32                 :       2598 : {
#      33                 :       2598 :     return RPCHelpMan{"getwalletinfo",
#      34                 :       2598 :                 "Returns an object containing various wallet state info.\n",
#      35                 :       2598 :                 {},
#      36                 :       2598 :                 RPCResult{
#      37                 :       2598 :                     RPCResult::Type::OBJ, "", "",
#      38                 :       2598 :                     {
#      39                 :       2598 :                         {
#      40                 :       2598 :                         {RPCResult::Type::STR, "walletname", "the wallet name"},
#      41                 :       2598 :                         {RPCResult::Type::NUM, "walletversion", "the wallet version"},
#      42                 :       2598 :                         {RPCResult::Type::STR, "format", "the database format (bdb or sqlite)"},
#      43                 :       2598 :                         {RPCResult::Type::STR_AMOUNT, "balance", "DEPRECATED. Identical to getbalances().mine.trusted"},
#      44                 :       2598 :                         {RPCResult::Type::STR_AMOUNT, "unconfirmed_balance", "DEPRECATED. Identical to getbalances().mine.untrusted_pending"},
#      45                 :       2598 :                         {RPCResult::Type::STR_AMOUNT, "immature_balance", "DEPRECATED. Identical to getbalances().mine.immature"},
#      46                 :       2598 :                         {RPCResult::Type::NUM, "txcount", "the total number of transactions in the wallet"},
#      47                 :       2598 :                         {RPCResult::Type::NUM_TIME, "keypoololdest", /*optional=*/true, "the " + UNIX_EPOCH_TIME + " of the oldest pre-generated key in the key pool. Legacy wallets only."},
#      48                 :       2598 :                         {RPCResult::Type::NUM, "keypoolsize", "how many new keys are pre-generated (only counts external keys)"},
#      49                 :       2598 :                         {RPCResult::Type::NUM, "keypoolsize_hd_internal", /*optional=*/true, "how many new keys are pre-generated for internal use (used for change outputs, only appears if the wallet is using this feature, otherwise external keys are used)"},
#      50                 :       2598 :                         {RPCResult::Type::NUM_TIME, "unlocked_until", /*optional=*/true, "the " + UNIX_EPOCH_TIME + " until which the wallet is unlocked for transfers, or 0 if the wallet is locked (only present for passphrase-encrypted wallets)"},
#      51                 :       2598 :                         {RPCResult::Type::STR_AMOUNT, "paytxfee", "the transaction fee configuration, set in " + CURRENCY_UNIT + "/kvB"},
#      52                 :       2598 :                         {RPCResult::Type::STR_HEX, "hdseedid", /*optional=*/true, "the Hash160 of the HD seed (only present when HD is enabled)"},
#      53                 :       2598 :                         {RPCResult::Type::BOOL, "private_keys_enabled", "false if privatekeys are disabled for this wallet (enforced watch-only wallet)"},
#      54                 :       2598 :                         {RPCResult::Type::BOOL, "avoid_reuse", "whether this wallet tracks clean/dirty coins in terms of reuse"},
#      55                 :       2598 :                         {RPCResult::Type::OBJ, "scanning", "current scanning details, or false if no scan is in progress",
#      56                 :       2598 :                         {
#      57                 :       2598 :                             {RPCResult::Type::NUM, "duration", "elapsed seconds since scan start"},
#      58                 :       2598 :                             {RPCResult::Type::NUM, "progress", "scanning progress percentage [0.0, 1.0]"},
#      59                 :       2598 :                         }, /*skip_type_check=*/true},
#      60                 :       2598 :                         {RPCResult::Type::BOOL, "descriptors", "whether this wallet uses descriptors for scriptPubKey management"},
#      61                 :       2598 :                         {RPCResult::Type::BOOL, "external_signer", "whether this wallet is configured to use an external signer such as a hardware wallet"},
#      62                 :       2598 :                     }},
#      63                 :       2598 :                 },
#      64                 :       2598 :                 RPCExamples{
#      65                 :       2598 :                     HelpExampleCli("getwalletinfo", "")
#      66                 :       2598 :             + HelpExampleRpc("getwalletinfo", "")
#      67                 :       2598 :                 },
#      68                 :       2598 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#      69                 :       2598 : {
#      70                 :       1014 :     const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
#      71         [ -  + ]:       1014 :     if (!pwallet) return NullUniValue;
#      72                 :            : 
#      73                 :            :     // Make sure the results are valid at least up to the most recent block
#      74                 :            :     // the user could have gotten from another RPC command prior to now
#      75                 :       1014 :     pwallet->BlockUntilSyncedToCurrentChain();
#      76                 :            : 
#      77                 :       1014 :     LOCK(pwallet->cs_wallet);
#      78                 :            : 
#      79                 :       1014 :     UniValue obj(UniValue::VOBJ);
#      80                 :            : 
#      81                 :       1014 :     size_t kpExternalSize = pwallet->KeypoolCountExternalKeys();
#      82                 :       1014 :     const auto bal = GetBalance(*pwallet);
#      83                 :       1014 :     obj.pushKV("walletname", pwallet->GetName());
#      84                 :       1014 :     obj.pushKV("walletversion", pwallet->GetVersion());
#      85                 :       1014 :     obj.pushKV("format", pwallet->GetDatabase().Format());
#      86                 :       1014 :     obj.pushKV("balance", ValueFromAmount(bal.m_mine_trusted));
#      87                 :       1014 :     obj.pushKV("unconfirmed_balance", ValueFromAmount(bal.m_mine_untrusted_pending));
#      88                 :       1014 :     obj.pushKV("immature_balance", ValueFromAmount(bal.m_mine_immature));
#      89                 :       1014 :     obj.pushKV("txcount",       (int)pwallet->mapWallet.size());
#      90                 :       1014 :     const auto kp_oldest = pwallet->GetOldestKeyPoolTime();
#      91         [ +  + ]:       1014 :     if (kp_oldest.has_value()) {
#      92                 :        651 :         obj.pushKV("keypoololdest", kp_oldest.value());
#      93                 :        651 :     }
#      94                 :       1014 :     obj.pushKV("keypoolsize", (int64_t)kpExternalSize);
#      95                 :            : 
#      96                 :       1014 :     LegacyScriptPubKeyMan* spk_man = pwallet->GetLegacyScriptPubKeyMan();
#      97         [ +  + ]:       1014 :     if (spk_man) {
#      98                 :        651 :         CKeyID seed_id = spk_man->GetHDChain().seed_id;
#      99         [ +  + ]:        651 :         if (!seed_id.IsNull()) {
#     100                 :        570 :             obj.pushKV("hdseedid", seed_id.GetHex());
#     101                 :        570 :         }
#     102                 :        651 :     }
#     103                 :            : 
#     104         [ +  + ]:       1014 :     if (pwallet->CanSupportFeature(FEATURE_HD_SPLIT)) {
#     105                 :        991 :         obj.pushKV("keypoolsize_hd_internal",   (int64_t)(pwallet->GetKeyPoolSize() - kpExternalSize));
#     106                 :        991 :     }
#     107         [ +  + ]:       1014 :     if (pwallet->IsCrypted()) {
#     108                 :         31 :         obj.pushKV("unlocked_until", pwallet->nRelockTime);
#     109                 :         31 :     }
#     110                 :       1014 :     obj.pushKV("paytxfee", ValueFromAmount(pwallet->m_pay_tx_fee.GetFeePerK()));
#     111                 :       1014 :     obj.pushKV("private_keys_enabled", !pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
#     112                 :       1014 :     obj.pushKV("avoid_reuse", pwallet->IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE));
#     113         [ -  + ]:       1014 :     if (pwallet->IsScanning()) {
#     114                 :          0 :         UniValue scanning(UniValue::VOBJ);
#     115                 :          0 :         scanning.pushKV("duration", pwallet->ScanningDuration() / 1000);
#     116                 :          0 :         scanning.pushKV("progress", pwallet->ScanningProgress());
#     117                 :          0 :         obj.pushKV("scanning", scanning);
#     118                 :       1014 :     } else {
#     119                 :       1014 :         obj.pushKV("scanning", false);
#     120                 :       1014 :     }
#     121                 :       1014 :     obj.pushKV("descriptors", pwallet->IsWalletFlagSet(WALLET_FLAG_DESCRIPTORS));
#     122                 :       1014 :     obj.pushKV("external_signer", pwallet->IsWalletFlagSet(WALLET_FLAG_EXTERNAL_SIGNER));
#     123                 :       1014 :     return obj;
#     124                 :       1014 : },
#     125                 :       2598 :     };
#     126                 :       2598 : }
#     127                 :            : 
#     128                 :            : static RPCHelpMan listwalletdir()
#     129                 :       1597 : {
#     130                 :       1597 :     return RPCHelpMan{"listwalletdir",
#     131                 :       1597 :                 "Returns a list of wallets in the wallet directory.\n",
#     132                 :       1597 :                 {},
#     133                 :       1597 :                 RPCResult{
#     134                 :       1597 :                     RPCResult::Type::OBJ, "", "",
#     135                 :       1597 :                     {
#     136                 :       1597 :                         {RPCResult::Type::ARR, "wallets", "",
#     137                 :       1597 :                         {
#     138                 :       1597 :                             {RPCResult::Type::OBJ, "", "",
#     139                 :       1597 :                             {
#     140                 :       1597 :                                 {RPCResult::Type::STR, "name", "The wallet name"},
#     141                 :       1597 :                             }},
#     142                 :       1597 :                         }},
#     143                 :       1597 :                     }
#     144                 :       1597 :                 },
#     145                 :       1597 :                 RPCExamples{
#     146                 :       1597 :                     HelpExampleCli("listwalletdir", "")
#     147                 :       1597 :             + HelpExampleRpc("listwalletdir", "")
#     148                 :       1597 :                 },
#     149                 :       1597 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     150                 :       1597 : {
#     151                 :         13 :     UniValue wallets(UniValue::VARR);
#     152         [ +  + ]:         88 :     for (const auto& path : ListDatabases(GetWalletDir())) {
#     153                 :         88 :         UniValue wallet(UniValue::VOBJ);
#     154                 :         88 :         wallet.pushKV("name", path.u8string());
#     155                 :         88 :         wallets.push_back(wallet);
#     156                 :         88 :     }
#     157                 :            : 
#     158                 :         13 :     UniValue result(UniValue::VOBJ);
#     159                 :         13 :     result.pushKV("wallets", wallets);
#     160                 :         13 :     return result;
#     161                 :         13 : },
#     162                 :       1597 :     };
#     163                 :       1597 : }
#     164                 :            : 
#     165                 :            : static RPCHelpMan listwallets()
#     166                 :       1697 : {
#     167                 :       1697 :     return RPCHelpMan{"listwallets",
#     168                 :       1697 :                 "Returns a list of currently loaded wallets.\n"
#     169                 :       1697 :                 "For full information on the wallet, use \"getwalletinfo\"\n",
#     170                 :       1697 :                 {},
#     171                 :       1697 :                 RPCResult{
#     172                 :       1697 :                     RPCResult::Type::ARR, "", "",
#     173                 :       1697 :                     {
#     174                 :       1697 :                         {RPCResult::Type::STR, "walletname", "the wallet name"},
#     175                 :       1697 :                     }
#     176                 :       1697 :                 },
#     177                 :       1697 :                 RPCExamples{
#     178                 :       1697 :                     HelpExampleCli("listwallets", "")
#     179                 :       1697 :             + HelpExampleRpc("listwallets", "")
#     180                 :       1697 :                 },
#     181                 :       1697 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     182                 :       1697 : {
#     183                 :        113 :     UniValue obj(UniValue::VARR);
#     184                 :            : 
#     185                 :        113 :     WalletContext& context = EnsureWalletContext(request.context);
#     186         [ +  + ]:        386 :     for (const std::shared_ptr<CWallet>& wallet : GetWallets(context)) {
#     187                 :        386 :         LOCK(wallet->cs_wallet);
#     188                 :        386 :         obj.push_back(wallet->GetName());
#     189                 :        386 :     }
#     190                 :            : 
#     191                 :        113 :     return obj;
#     192                 :        113 : },
#     193                 :       1697 :     };
#     194                 :       1697 : }
#     195                 :            : 
#     196                 :            : static RPCHelpMan loadwallet()
#     197                 :       1803 : {
#     198                 :       1803 :     return RPCHelpMan{"loadwallet",
#     199                 :       1803 :                 "\nLoads a wallet from a wallet file or directory."
#     200                 :       1803 :                 "\nNote that all wallet command-line options used when starting bitcoind will be"
#     201                 :       1803 :                 "\napplied to the new wallet.\n",
#     202                 :       1803 :                 {
#     203                 :       1803 :                     {"filename", RPCArg::Type::STR, RPCArg::Optional::NO, "The wallet directory or .dat file."},
#     204                 :       1803 :                     {"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."},
#     205                 :       1803 :                 },
#     206                 :       1803 :                 RPCResult{
#     207                 :       1803 :                     RPCResult::Type::OBJ, "", "",
#     208                 :       1803 :                     {
#     209                 :       1803 :                         {RPCResult::Type::STR, "name", "The wallet name if loaded successfully."},
#     210                 :       1803 :                         {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
#     211                 :       1803 :                     }
#     212                 :       1803 :                 },
#     213                 :       1803 :                 RPCExamples{
#     214                 :       1803 :                     HelpExampleCli("loadwallet", "\"test.dat\"")
#     215                 :       1803 :             + HelpExampleRpc("loadwallet", "\"test.dat\"")
#     216                 :       1803 :                 },
#     217                 :       1803 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     218                 :       1803 : {
#     219                 :        219 :     WalletContext& context = EnsureWalletContext(request.context);
#     220                 :        219 :     const std::string name(request.params[0].get_str());
#     221                 :            : 
#     222                 :        219 :     DatabaseOptions options;
#     223                 :        219 :     DatabaseStatus status;
#     224                 :        219 :     ReadDatabaseArgs(*context.args, options);
#     225                 :        219 :     options.require_existing = true;
#     226                 :        219 :     bilingual_str error;
#     227                 :        219 :     std::vector<bilingual_str> warnings;
#     228         [ +  + ]:        219 :     std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());
#     229                 :        219 :     std::shared_ptr<CWallet> const wallet = LoadWallet(context, name, load_on_start, options, status, error, warnings);
#     230                 :            : 
#     231                 :        219 :     HandleWalletError(wallet, status, error);
#     232                 :            : 
#     233                 :        219 :     UniValue obj(UniValue::VOBJ);
#     234                 :        219 :     obj.pushKV("name", wallet->GetName());
#     235                 :        219 :     obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
#     236                 :            : 
#     237                 :        219 :     return obj;
#     238                 :        219 : },
#     239                 :       1803 :     };
#     240                 :       1803 : }
#     241                 :            : 
#     242                 :            : static RPCHelpMan setwalletflag()
#     243                 :       1597 : {
#     244                 :       1597 :             std::string flags = "";
#     245         [ +  + ]:       1597 :             for (auto& it : WALLET_FLAG_MAP)
#     246         [ +  + ]:      11179 :                 if (it.second & MUTABLE_WALLET_FLAGS)
#     247         [ +  - ]:       1597 :                     flags += (flags == "" ? "" : ", ") + it.first;
#     248                 :            : 
#     249                 :       1597 :     return RPCHelpMan{"setwalletflag",
#     250                 :       1597 :                 "\nChange the state of the given wallet flag for a wallet.\n",
#     251                 :       1597 :                 {
#     252                 :       1597 :                     {"flag", RPCArg::Type::STR, RPCArg::Optional::NO, "The name of the flag to change. Current available flags: " + flags},
#     253                 :       1597 :                     {"value", RPCArg::Type::BOOL, RPCArg::Default{true}, "The new state."},
#     254                 :       1597 :                 },
#     255                 :       1597 :                 RPCResult{
#     256                 :       1597 :                     RPCResult::Type::OBJ, "", "",
#     257                 :       1597 :                     {
#     258                 :       1597 :                         {RPCResult::Type::STR, "flag_name", "The name of the flag that was modified"},
#     259                 :       1597 :                         {RPCResult::Type::BOOL, "flag_state", "The new state of the flag"},
#     260                 :       1597 :                         {RPCResult::Type::STR, "warnings", /*optional=*/true, "Any warnings associated with the change"},
#     261                 :       1597 :                     }
#     262                 :       1597 :                 },
#     263                 :       1597 :                 RPCExamples{
#     264                 :       1597 :                     HelpExampleCli("setwalletflag", "avoid_reuse")
#     265                 :       1597 :                   + HelpExampleRpc("setwalletflag", "\"avoid_reuse\"")
#     266                 :       1597 :                 },
#     267                 :       1597 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     268                 :       1597 : {
#     269                 :         13 :     std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
#     270         [ -  + ]:         13 :     if (!pwallet) return NullUniValue;
#     271                 :            : 
#     272                 :         13 :     std::string flag_str = request.params[0].get_str();
#     273 [ +  + ][ +  + ]:         13 :     bool value = request.params[1].isNull() || request.params[1].get_bool();
#     274                 :            : 
#     275         [ -  + ]:         13 :     if (!WALLET_FLAG_MAP.count(flag_str)) {
#     276                 :          0 :         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unknown wallet flag: %s", flag_str));
#     277                 :          0 :     }
#     278                 :            : 
#     279                 :         13 :     auto flag = WALLET_FLAG_MAP.at(flag_str);
#     280                 :            : 
#     281         [ +  + ]:         13 :     if (!(flag & MUTABLE_WALLET_FLAGS)) {
#     282                 :          5 :         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is immutable: %s", flag_str));
#     283                 :          5 :     }
#     284                 :            : 
#     285                 :          8 :     UniValue res(UniValue::VOBJ);
#     286                 :            : 
#     287         [ +  + ]:          8 :     if (pwallet->IsWalletFlagSet(flag) == value) {
#     288         [ +  + ]:          4 :         throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is already set to %s: %s", value ? "true" : "false", flag_str));
#     289                 :          4 :     }
#     290                 :            : 
#     291                 :          4 :     res.pushKV("flag_name", flag_str);
#     292                 :          4 :     res.pushKV("flag_state", value);
#     293                 :            : 
#     294         [ +  + ]:          4 :     if (value) {
#     295                 :          2 :         pwallet->SetWalletFlag(flag);
#     296                 :          2 :     } else {
#     297                 :          2 :         pwallet->UnsetWalletFlag(flag);
#     298                 :          2 :     }
#     299                 :            : 
#     300 [ +  + ][ +  - ]:          4 :     if (flag && value && WALLET_FLAG_CAVEATS.count(flag)) {
#         [ +  + ][ +  - ]
#     301                 :          2 :         res.pushKV("warnings", WALLET_FLAG_CAVEATS.at(flag));
#     302                 :          2 :     }
#     303                 :            : 
#     304                 :          4 :     return res;
#     305                 :          8 : },
#     306                 :       1597 :     };
#     307                 :       1597 : }
#     308                 :            : 
#     309                 :            : static RPCHelpMan createwallet()
#     310                 :       2054 : {
#     311                 :       2054 :     return RPCHelpMan{
#     312                 :       2054 :         "createwallet",
#     313                 :       2054 :         "\nCreates and loads a new wallet.\n",
#     314                 :       2054 :         {
#     315                 :       2054 :             {"wallet_name", RPCArg::Type::STR, RPCArg::Optional::NO, "The name for the new wallet. If this is a path, the wallet will be created at the path location."},
#     316                 :       2054 :             {"disable_private_keys", RPCArg::Type::BOOL, RPCArg::Default{false}, "Disable the possibility of private keys (only watchonlys are possible in this mode)."},
#     317                 :       2054 :             {"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 sethdseed."},
#     318                 :       2054 :             {"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "Encrypt the wallet with this passphrase."},
#     319                 :       2054 :             {"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."},
#     320                 :       2054 :             {"descriptors", RPCArg::Type::BOOL, RPCArg::Default{true}, "Create a native descriptor wallet. The wallet will use descriptors internally to handle address creation."
#     321                 :       2054 :                                                                        " Setting to \"false\" will create a legacy wallet; however, the legacy wallet type is being deprecated and"
#     322                 :       2054 :                                                                        " support for creating and opening legacy wallets will be removed in the future."},
#     323                 :       2054 :             {"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."},
#     324                 :       2054 :             {"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."},
#     325                 :       2054 :         },
#     326                 :       2054 :         RPCResult{
#     327                 :       2054 :             RPCResult::Type::OBJ, "", "",
#     328                 :       2054 :             {
#     329                 :       2054 :                 {RPCResult::Type::STR, "name", "The wallet name if created successfully. If the wallet was created using a full path, the wallet_name will be the full path."},
#     330                 :       2054 :                 {RPCResult::Type::STR, "warning", "Warning message if wallet was not loaded cleanly."},
#     331                 :       2054 :             }
#     332                 :       2054 :         },
#     333                 :       2054 :         RPCExamples{
#     334                 :       2054 :             HelpExampleCli("createwallet", "\"testwallet\"")
#     335                 :       2054 :             + HelpExampleRpc("createwallet", "\"testwallet\"")
#     336                 :       2054 :             + HelpExampleCliNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}})
#     337                 :       2054 :             + HelpExampleRpcNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"descriptors", true}, {"load_on_startup", true}})
#     338                 :       2054 :         },
#     339                 :       2054 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     340                 :       2054 : {
#     341                 :        470 :     WalletContext& context = EnsureWalletContext(request.context);
#     342                 :        470 :     uint64_t flags = 0;
#     343 [ +  + ][ +  + ]:        470 :     if (!request.params[1].isNull() && request.params[1].get_bool()) {
#     344                 :         60 :         flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;
#     345                 :         60 :     }
#     346                 :            : 
#     347 [ +  + ][ +  + ]:        470 :     if (!request.params[2].isNull() && request.params[2].get_bool()) {
#     348                 :         50 :         flags |= WALLET_FLAG_BLANK_WALLET;
#     349                 :         50 :     }
#     350                 :        470 :     SecureString passphrase;
#     351                 :        470 :     passphrase.reserve(100);
#     352                 :        470 :     std::vector<bilingual_str> warnings;
#     353         [ +  + ]:        470 :     if (!request.params[3].isNull()) {
#     354                 :        468 :         passphrase = request.params[3].get_str().c_str();
#     355         [ +  + ]:        468 :         if (passphrase.empty()) {
#     356                 :            :             // Empty string means unencrypted
#     357                 :        454 :             warnings.emplace_back(Untranslated("Empty string given as passphrase, wallet will not be encrypted."));
#     358                 :        454 :         }
#     359                 :        468 :     }
#     360                 :            : 
#     361 [ +  + ][ +  + ]:        470 :     if (!request.params[4].isNull() && request.params[4].get_bool()) {
#     362                 :          5 :         flags |= WALLET_FLAG_AVOID_REUSE;
#     363                 :          5 :     }
#     364 [ -  + ][ +  + ]:        470 :     if (request.params[5].isNull() || request.params[5].get_bool()) {
#     365                 :            : #ifndef USE_SQLITE
#     366                 :            :         throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without sqlite support (required for descriptor wallets)");
#     367                 :            : #endif
#     368                 :        200 :         flags |= WALLET_FLAG_DESCRIPTORS;
#     369                 :        200 :     }
#     370 [ +  + ][ +  + ]:        470 :     if (!request.params[7].isNull() && request.params[7].get_bool()) {
#     371                 :          4 : #ifdef ENABLE_EXTERNAL_SIGNER
#     372                 :          4 :         flags |= WALLET_FLAG_EXTERNAL_SIGNER;
#     373                 :            : #else
#     374                 :            :         throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without external signing support (required for external signing)");
#     375                 :            : #endif
#     376                 :          4 :     }
#     377                 :            : 
#     378                 :            : #ifndef USE_BDB
#     379                 :            :     if (!(flags & WALLET_FLAG_DESCRIPTORS)) {
#     380                 :            :         throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without bdb support (required for legacy wallets)");
#     381                 :            :     }
#     382                 :            : #endif
#     383                 :            : 
#     384                 :        470 :     DatabaseOptions options;
#     385                 :        470 :     DatabaseStatus status;
#     386                 :        470 :     ReadDatabaseArgs(*context.args, options);
#     387                 :        470 :     options.require_create = true;
#     388                 :        470 :     options.create_flags = flags;
#     389                 :        470 :     options.create_passphrase = passphrase;
#     390                 :        470 :     bilingual_str error;
#     391         [ +  + ]:        470 :     std::optional<bool> load_on_start = request.params[6].isNull() ? std::nullopt : std::optional<bool>(request.params[6].get_bool());
#     392                 :        470 :     const std::shared_ptr<CWallet> wallet = CreateWallet(context, request.params[0].get_str(), load_on_start, options, status, error, warnings);
#     393         [ +  + ]:        470 :     if (!wallet) {
#     394         [ -  + ]:         12 :         RPCErrorCode code = status == DatabaseStatus::FAILED_ENCRYPT ? RPC_WALLET_ENCRYPTION_FAILED : RPC_WALLET_ERROR;
#     395                 :         12 :         throw JSONRPCError(code, error.original);
#     396                 :         12 :     }
#     397                 :            : 
#     398                 :        458 :     UniValue obj(UniValue::VOBJ);
#     399                 :        458 :     obj.pushKV("name", wallet->GetName());
#     400                 :        458 :     obj.pushKV("warning", Join(warnings, Untranslated("\n")).original);
#     401                 :            : 
#     402                 :        458 :     return obj;
#     403                 :        470 : },
#     404                 :       2054 :     };
#     405                 :       2054 : }
#     406                 :            : 
#     407                 :            : static RPCHelpMan unloadwallet()
#     408                 :       1763 : {
#     409                 :       1763 :     return RPCHelpMan{"unloadwallet",
#     410                 :       1763 :                 "Unloads the wallet referenced by the request endpoint otherwise unloads the wallet specified in the argument.\n"
#     411                 :       1763 :                 "Specifying the wallet name on a wallet endpoint is invalid.",
#     412                 :       1763 :                 {
#     413                 :       1763 :                     {"wallet_name", RPCArg::Type::STR, RPCArg::DefaultHint{"the wallet name from the RPC endpoint"}, "The name of the wallet to unload. If provided both here and in the RPC endpoint, the two must be identical."},
#     414                 :       1763 :                     {"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."},
#     415                 :       1763 :                 },
#     416                 :       1763 :                 RPCResult{RPCResult::Type::OBJ, "", "", {
#     417                 :       1763 :                     {RPCResult::Type::STR, "warning", "Warning message if wallet was not unloaded cleanly."},
#     418                 :       1763 :                 }},
#     419                 :       1763 :                 RPCExamples{
#     420                 :       1763 :                     HelpExampleCli("unloadwallet", "wallet_name")
#     421                 :       1763 :             + HelpExampleRpc("unloadwallet", "wallet_name")
#     422                 :       1763 :                 },
#     423                 :       1763 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     424                 :       1763 : {
#     425                 :        179 :     std::string wallet_name;
#     426         [ +  + ]:        179 :     if (GetWalletNameFromJSONRPCRequest(request, wallet_name)) {
#     427 [ +  + ][ +  + ]:         45 :         if (!(request.params[0].isNull() || request.params[0].get_str() == wallet_name)) {
#     428                 :          3 :             throw JSONRPCError(RPC_INVALID_PARAMETER, "RPC endpoint wallet and wallet_name parameter specify different wallets");
#     429                 :          3 :         }
#     430                 :        134 :     } else {
#     431                 :        134 :         wallet_name = request.params[0].get_str();
#     432                 :        134 :     }
#     433                 :            : 
#     434                 :        176 :     WalletContext& context = EnsureWalletContext(request.context);
#     435                 :        176 :     std::shared_ptr<CWallet> wallet = GetWallet(context, wallet_name);
#     436         [ +  + ]:        176 :     if (!wallet) {
#     437                 :          6 :         throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");
#     438                 :          6 :     }
#     439                 :            : 
#     440                 :            :     // Release the "main" shared pointer and prevent further notifications.
#     441                 :            :     // Note that any attempt to load the same wallet would fail until the wallet
#     442                 :            :     // is destroyed (see CheckUniqueFileid).
#     443                 :        170 :     std::vector<bilingual_str> warnings;
#     444         [ +  + ]:        170 :     std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());
#     445         [ -  + ]:        170 :     if (!RemoveWallet(context, wallet, load_on_start, warnings)) {
#     446                 :          0 :         throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");
#     447                 :          0 :     }
#     448                 :            : 
#     449                 :        170 :     UnloadWallet(std::move(wallet));
#     450                 :            : 
#     451                 :        170 :     UniValue result(UniValue::VOBJ);
#     452                 :        170 :     result.pushKV("warning", Join(warnings, Untranslated("\n")).original);
#     453                 :        170 :     return result;
#     454                 :        170 : },
#     455                 :       1763 :     };
#     456                 :       1763 : }
#     457                 :            : 
#     458                 :            : static RPCHelpMan sethdseed()
#     459                 :       1605 : {
#     460                 :       1605 :     return RPCHelpMan{"sethdseed",
#     461                 :       1605 :                 "\nSet or generate a new HD wallet seed. Non-HD wallets will not be upgraded to being a HD wallet. Wallets that are already\n"
#     462                 :       1605 :                 "HD will have a new HD seed set so that new keys added to the keypool will be derived from this new seed.\n"
#     463                 :       1605 :                 "\nNote that you will need to MAKE A NEW BACKUP of your wallet after setting the HD wallet seed." +
#     464                 :       1605 :         HELP_REQUIRING_PASSPHRASE,
#     465                 :       1605 :                 {
#     466                 :       1605 :                     {"newkeypool", RPCArg::Type::BOOL, RPCArg::Default{true}, "Whether to flush old unused addresses, including change addresses, from the keypool and regenerate it.\n"
#     467                 :       1605 :                                          "If true, the next address from getnewaddress and change address from getrawchangeaddress will be from this new seed.\n"
#     468                 :       1605 :                                          "If false, addresses (including change addresses if the wallet already had HD Chain Split enabled) from the existing\n"
#     469                 :       1605 :                                          "keypool will be used until it has been depleted."},
#     470                 :       1605 :                     {"seed", RPCArg::Type::STR, RPCArg::DefaultHint{"random seed"}, "The WIF private key to use as the new HD seed.\n"
#     471                 :       1605 :                                          "The seed value can be retrieved using the dumpwallet command. It is the private key marked hdseed=1"},
#     472                 :       1605 :                 },
#     473                 :       1605 :                 RPCResult{RPCResult::Type::NONE, "", ""},
#     474                 :       1605 :                 RPCExamples{
#     475                 :       1605 :                     HelpExampleCli("sethdseed", "")
#     476                 :       1605 :             + HelpExampleCli("sethdseed", "false")
#     477                 :       1605 :             + HelpExampleCli("sethdseed", "true \"wifkey\"")
#     478                 :       1605 :             + HelpExampleRpc("sethdseed", "true, \"wifkey\"")
#     479                 :       1605 :                 },
#     480                 :       1605 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     481                 :       1605 : {
#     482                 :         20 :     std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
#     483         [ -  + ]:         20 :     if (!pwallet) return NullUniValue;
#     484                 :            : 
#     485                 :         20 :     LegacyScriptPubKeyMan& spk_man = EnsureLegacyScriptPubKeyMan(*pwallet, true);
#     486                 :            : 
#     487         [ -  + ]:         20 :     if (pwallet->IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) {
#     488                 :          0 :         throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set a HD seed to a wallet with private keys disabled");
#     489                 :          0 :     }
#     490                 :            : 
#     491                 :         20 :     LOCK2(pwallet->cs_wallet, spk_man.cs_KeyStore);
#     492                 :            : 
#     493                 :            :     // Do not do anything to non-HD wallets
#     494         [ -  + ]:         20 :     if (!pwallet->CanSupportFeature(FEATURE_HD)) {
#     495                 :          0 :         throw JSONRPCError(RPC_WALLET_ERROR, "Cannot set an HD seed on a non-HD wallet. Use the upgradewallet RPC in order to upgrade a non-HD wallet to HD");
#     496                 :          0 :     }
#     497                 :            : 
#     498                 :         20 :     EnsureWalletIsUnlocked(*pwallet);
#     499                 :            : 
#     500                 :         20 :     bool flush_key_pool = true;
#     501         [ +  + ]:         20 :     if (!request.params[0].isNull()) {
#     502                 :         14 :         flush_key_pool = request.params[0].get_bool();
#     503                 :         14 :     }
#     504                 :            : 
#     505                 :         20 :     CPubKey master_pub_key;
#     506         [ +  + ]:         20 :     if (request.params[1].isNull()) {
#     507                 :          8 :         master_pub_key = spk_man.GenerateNewSeed();
#     508                 :         12 :     } else {
#     509                 :         12 :         CKey key = DecodeSecret(request.params[1].get_str());
#     510         [ +  + ]:         12 :         if (!key.IsValid()) {
#     511                 :          1 :             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid private key");
#     512                 :          1 :         }
#     513                 :            : 
#     514         [ +  + ]:         11 :         if (HaveKey(spk_man, key)) {
#     515                 :          2 :             throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Already have this key (either as an HD seed or as a loose private key)");
#     516                 :          2 :         }
#     517                 :            : 
#     518                 :          9 :         master_pub_key = spk_man.DeriveNewSeed(key);
#     519                 :          9 :     }
#     520                 :            : 
#     521                 :         17 :     spk_man.SetHDSeed(master_pub_key);
#     522         [ +  + ]:         17 :     if (flush_key_pool) spk_man.NewKeyPool();
#     523                 :            : 
#     524                 :         17 :     return NullUniValue;
#     525                 :         20 : },
#     526                 :       1605 :     };
#     527                 :       1605 : }
#     528                 :            : 
#     529                 :            : static RPCHelpMan upgradewallet()
#     530                 :       1584 : {
#     531                 :       1584 :     return RPCHelpMan{"upgradewallet",
#     532                 :       1584 :         "\nUpgrade the wallet. Upgrades to the latest version if no version number is specified.\n"
#     533                 :       1584 :         "New keys may be generated and a new wallet backup will need to be made.",
#     534                 :       1584 :         {
#     535                 :       1584 :             {"version", RPCArg::Type::NUM, RPCArg::Default{FEATURE_LATEST}, "The version number to upgrade to. Default is the latest wallet version."}
#     536                 :       1584 :         },
#     537                 :       1584 :         RPCResult{
#     538                 :       1584 :             RPCResult::Type::OBJ, "", "",
#     539                 :       1584 :             {
#     540                 :       1584 :                 {RPCResult::Type::STR, "wallet_name", "Name of wallet this operation was performed on"},
#     541                 :       1584 :                 {RPCResult::Type::NUM, "previous_version", "Version of wallet before this operation"},
#     542                 :       1584 :                 {RPCResult::Type::NUM, "current_version", "Version of wallet after this operation"},
#     543                 :       1584 :                 {RPCResult::Type::STR, "result", /*optional=*/true, "Description of result, if no error"},
#     544                 :       1584 :                 {RPCResult::Type::STR, "error", /*optional=*/true, "Error message (if there is one)"}
#     545                 :       1584 :             },
#     546                 :       1584 :         },
#     547                 :       1584 :         RPCExamples{
#     548                 :       1584 :             HelpExampleCli("upgradewallet", "169900")
#     549                 :       1584 :             + HelpExampleRpc("upgradewallet", "169900")
#     550                 :       1584 :         },
#     551                 :       1584 :         [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
#     552                 :       1584 : {
#     553                 :          0 :     std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
#     554         [ #  # ]:          0 :     if (!pwallet) return NullUniValue;
#     555                 :            : 
#     556                 :          0 :     RPCTypeCheck(request.params, {UniValue::VNUM}, true);
#     557                 :            : 
#     558                 :          0 :     EnsureWalletIsUnlocked(*pwallet);
#     559                 :            : 
#     560                 :          0 :     int version = 0;
#     561         [ #  # ]:          0 :     if (!request.params[0].isNull()) {
#     562                 :          0 :         version = request.params[0].get_int();
#     563                 :          0 :     }
#     564                 :          0 :     bilingual_str error;
#     565                 :          0 :     const int previous_version{pwallet->GetVersion()};
#     566                 :          0 :     const bool wallet_upgraded{pwallet->UpgradeWallet(version, error)};
#     567                 :          0 :     const int current_version{pwallet->GetVersion()};
#     568                 :          0 :     std::string result;
#     569                 :            : 
#     570         [ #  # ]:          0 :     if (wallet_upgraded) {
#     571         [ #  # ]:          0 :         if (previous_version == current_version) {
#     572                 :          0 :             result = "Already at latest version. Wallet version unchanged.";
#     573                 :          0 :         } else {
#     574                 :          0 :             result = strprintf("Wallet upgraded successfully from version %i to version %i.", previous_version, current_version);
#     575                 :          0 :         }
#     576                 :          0 :     }
#     577                 :            : 
#     578                 :          0 :     UniValue obj(UniValue::VOBJ);
#     579                 :          0 :     obj.pushKV("wallet_name", pwallet->GetName());
#     580                 :          0 :     obj.pushKV("previous_version", previous_version);
#     581                 :          0 :     obj.pushKV("current_version", current_version);
#     582         [ #  # ]:          0 :     if (!result.empty()) {
#     583                 :          0 :         obj.pushKV("result", result);
#     584                 :          0 :     } else {
#     585         [ #  # ]:          0 :         CHECK_NONFATAL(!error.empty());
#     586                 :          0 :         obj.pushKV("error", error.original);
#     587                 :          0 :     }
#     588                 :          0 :     return obj;
#     589                 :          0 : },
#     590                 :       1584 :     };
#     591                 :       1584 : }
#     592                 :            : 
#     593                 :            : // addresses
#     594                 :            : RPCHelpMan getaddressinfo();
#     595                 :            : RPCHelpMan getnewaddress();
#     596                 :            : RPCHelpMan getrawchangeaddress();
#     597                 :            : RPCHelpMan setlabel();
#     598                 :            : RPCHelpMan listaddressgroupings();
#     599                 :            : RPCHelpMan addmultisigaddress();
#     600                 :            : RPCHelpMan keypoolrefill();
#     601                 :            : RPCHelpMan newkeypool();
#     602                 :            : RPCHelpMan getaddressesbylabel();
#     603                 :            : RPCHelpMan listlabels();
#     604                 :            : #ifdef ENABLE_EXTERNAL_SIGNER
#     605                 :            : RPCHelpMan walletdisplayaddress();
#     606                 :            : #endif // ENABLE_EXTERNAL_SIGNER
#     607                 :            : 
#     608                 :            : // backup
#     609                 :            : RPCHelpMan dumpprivkey();
#     610                 :            : RPCHelpMan importprivkey();
#     611                 :            : RPCHelpMan importaddress();
#     612                 :            : RPCHelpMan importpubkey();
#     613                 :            : RPCHelpMan dumpwallet();
#     614                 :            : RPCHelpMan importwallet();
#     615                 :            : RPCHelpMan importprunedfunds();
#     616                 :            : RPCHelpMan removeprunedfunds();
#     617                 :            : RPCHelpMan importmulti();
#     618                 :            : RPCHelpMan importdescriptors();
#     619                 :            : RPCHelpMan listdescriptors();
#     620                 :            : RPCHelpMan backupwallet();
#     621                 :            : RPCHelpMan restorewallet();
#     622                 :            : 
#     623                 :            : // coins
#     624                 :            : RPCHelpMan getreceivedbyaddress();
#     625                 :            : RPCHelpMan getreceivedbylabel();
#     626                 :            : RPCHelpMan getbalance();
#     627                 :            : RPCHelpMan getunconfirmedbalance();
#     628                 :            : RPCHelpMan lockunspent();
#     629                 :            : RPCHelpMan listlockunspent();
#     630                 :            : RPCHelpMan getbalances();
#     631                 :            : RPCHelpMan listunspent();
#     632                 :            : 
#     633                 :            : // encryption
#     634                 :            : RPCHelpMan walletpassphrase();
#     635                 :            : RPCHelpMan walletpassphrasechange();
#     636                 :            : RPCHelpMan walletlock();
#     637                 :            : RPCHelpMan encryptwallet();
#     638                 :            : 
#     639                 :            : // spend
#     640                 :            : RPCHelpMan sendtoaddress();
#     641                 :            : RPCHelpMan sendmany();
#     642                 :            : RPCHelpMan settxfee();
#     643                 :            : RPCHelpMan fundrawtransaction();
#     644                 :            : RPCHelpMan bumpfee();
#     645                 :            : RPCHelpMan psbtbumpfee();
#     646                 :            : RPCHelpMan send();
#     647                 :            : RPCHelpMan sendall();
#     648                 :            : RPCHelpMan walletprocesspsbt();
#     649                 :            : RPCHelpMan walletcreatefundedpsbt();
#     650                 :            : RPCHelpMan signrawtransactionwithwallet();
#     651                 :            : 
#     652                 :            : // signmessage
#     653                 :            : RPCHelpMan signmessage();
#     654                 :            : 
#     655                 :            : // transactions
#     656                 :            : RPCHelpMan listreceivedbyaddress();
#     657                 :            : RPCHelpMan listreceivedbylabel();
#     658                 :            : RPCHelpMan listtransactions();
#     659                 :            : RPCHelpMan listsinceblock();
#     660                 :            : RPCHelpMan gettransaction();
#     661                 :            : RPCHelpMan abandontransaction();
#     662                 :            : RPCHelpMan rescanblockchain();
#     663                 :            : RPCHelpMan abortrescan();
#     664                 :            : 
#     665                 :            : Span<const CRPCCommand> GetWalletRPCCommands()
#     666                 :        799 : {
#     667                 :            : // clang-format off
#     668                 :        799 : static const CRPCCommand commands[] =
#     669                 :        799 : { //  category              actor (function)
#     670                 :            :   //  ------------------    ------------------------
#     671                 :        799 :     { "rawtransactions",    &fundrawtransaction,             },
#     672                 :        799 :     { "wallet",             &abandontransaction,             },
#     673                 :        799 :     { "wallet",             &abortrescan,                    },
#     674                 :        799 :     { "wallet",             &addmultisigaddress,             },
#     675                 :        799 :     { "wallet",             &backupwallet,                   },
#     676                 :        799 :     { "wallet",             &bumpfee,                        },
#     677                 :        799 :     { "wallet",             &psbtbumpfee,                    },
#     678                 :        799 :     { "wallet",             &createwallet,                   },
#     679                 :        799 :     { "wallet",             &restorewallet,                  },
#     680                 :        799 :     { "wallet",             &dumpprivkey,                    },
#     681                 :        799 :     { "wallet",             &dumpwallet,                     },
#     682                 :        799 :     { "wallet",             &encryptwallet,                  },
#     683                 :        799 :     { "wallet",             &getaddressesbylabel,            },
#     684                 :        799 :     { "wallet",             &getaddressinfo,                 },
#     685                 :        799 :     { "wallet",             &getbalance,                     },
#     686                 :        799 :     { "wallet",             &getnewaddress,                  },
#     687                 :        799 :     { "wallet",             &getrawchangeaddress,            },
#     688                 :        799 :     { "wallet",             &getreceivedbyaddress,           },
#     689                 :        799 :     { "wallet",             &getreceivedbylabel,             },
#     690                 :        799 :     { "wallet",             &gettransaction,                 },
#     691                 :        799 :     { "wallet",             &getunconfirmedbalance,          },
#     692                 :        799 :     { "wallet",             &getbalances,                    },
#     693                 :        799 :     { "wallet",             &getwalletinfo,                  },
#     694                 :        799 :     { "wallet",             &importaddress,                  },
#     695                 :        799 :     { "wallet",             &importdescriptors,              },
#     696                 :        799 :     { "wallet",             &importmulti,                    },
#     697                 :        799 :     { "wallet",             &importprivkey,                  },
#     698                 :        799 :     { "wallet",             &importprunedfunds,              },
#     699                 :        799 :     { "wallet",             &importpubkey,                   },
#     700                 :        799 :     { "wallet",             &importwallet,                   },
#     701                 :        799 :     { "wallet",             &keypoolrefill,                  },
#     702                 :        799 :     { "wallet",             &listaddressgroupings,           },
#     703                 :        799 :     { "wallet",             &listdescriptors,                },
#     704                 :        799 :     { "wallet",             &listlabels,                     },
#     705                 :        799 :     { "wallet",             &listlockunspent,                },
#     706                 :        799 :     { "wallet",             &listreceivedbyaddress,          },
#     707                 :        799 :     { "wallet",             &listreceivedbylabel,            },
#     708                 :        799 :     { "wallet",             &listsinceblock,                 },
#     709                 :        799 :     { "wallet",             &listtransactions,               },
#     710                 :        799 :     { "wallet",             &listunspent,                    },
#     711                 :        799 :     { "wallet",             &listwalletdir,                  },
#     712                 :        799 :     { "wallet",             &listwallets,                    },
#     713                 :        799 :     { "wallet",             &loadwallet,                     },
#     714                 :        799 :     { "wallet",             &lockunspent,                    },
#     715                 :        799 :     { "wallet",             &newkeypool,                     },
#     716                 :        799 :     { "wallet",             &removeprunedfunds,              },
#     717                 :        799 :     { "wallet",             &rescanblockchain,               },
#     718                 :        799 :     { "wallet",             &send,                           },
#     719                 :        799 :     { "wallet",             &sendmany,                       },
#     720                 :        799 :     { "wallet",             &sendtoaddress,                  },
#     721                 :        799 :     { "wallet",             &sethdseed,                      },
#     722                 :        799 :     { "wallet",             &setlabel,                       },
#     723                 :        799 :     { "wallet",             &settxfee,                       },
#     724                 :        799 :     { "wallet",             &setwalletflag,                  },
#     725                 :        799 :     { "wallet",             &signmessage,                    },
#     726                 :        799 :     { "wallet",             &signrawtransactionwithwallet,   },
#     727                 :        799 :     { "wallet",             &sendall,                        },
#     728                 :        799 :     { "wallet",             &unloadwallet,                   },
#     729                 :        799 :     { "wallet",             &upgradewallet,                  },
#     730                 :        799 :     { "wallet",             &walletcreatefundedpsbt,         },
#     731                 :        799 : #ifdef ENABLE_EXTERNAL_SIGNER
#     732                 :        799 :     { "wallet",             &walletdisplayaddress,           },
#     733                 :        799 : #endif // ENABLE_EXTERNAL_SIGNER
#     734                 :        799 :     { "wallet",             &walletlock,                     },
#     735                 :        799 :     { "wallet",             &walletpassphrase,               },
#     736                 :        799 :     { "wallet",             &walletpassphrasechange,         },
#     737                 :        799 :     { "wallet",             &walletprocesspsbt,              },
#     738                 :        799 : };
#     739                 :            : // clang-format on
#     740                 :        799 :     return commands;
#     741                 :        799 : }
#     742                 :            : } // namespace wallet

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a