wallet, rpc: Add exportwatchonlywallet RPC
What changed, and why it matters
This commit adds a new wallet command called exportwatchonlywallet. It lets a user save a copy of their wallet that contains only public information—public descriptors, transactions, and address book data—without private keys. The change is purely additive and exposes no new security weakness based on the code shown.
No security action required. As with any file-exporting RPC, ensure the destination path is validated and permissions are appropriate in the underlying ExportWatchOnlyWallet implementation, but that code is not shown in this commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch registers a new RPC, exportwatchonlywallet, in src/wallet/rpc/wallet.cpp. It accepts a destination path, locks the wallet, tops up the key pool, and calls ExportWatchOnlyWallet() (defined elsewhere in wallet/export.h) to write a watch-only wallet file. The exported data is explicitly public/descriptors/transactions/address book, with hardened-derivation descriptors limited because private keys are excluded. No input validation, path traversal, authentication, or cryptographic logic is visible in this diff.
Changed components
src/wallet/rpc/wallet.cppInspect captured patch +45 / −0
diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp
index 67b2f9e3..a9e72db9 100644
--- a/src/wallet/rpc/wallet.cpp
+++ b/src/wallet/rpc/wallet.cpp
@@ -15,6 +15,7 @@
#include <univalue.h>
#include <util/translation.h>
#include <wallet/context.h>
+#include <wallet/export.h>
#include <wallet/receive.h>
#include <wallet/rpc/util.h>
#include <wallet/wallet.h>
@@ -918,6 +919,49 @@ RPCMethod addhdkey()
};
}
+static RPCMethod exportwatchonlywallet()
+{
+ return RPCMethod{"exportwatchonlywallet",
+ "Creates a wallet file at the specified destination containing a watchonly version "
+ "of the current wallet. This watchonly wallet contains the wallet's public descriptors, "
+ "its transactions, and address book data. Descriptors that use hardened derivation will "
+ "only have a limited number of derived keys included in the export due to hardened "
+ "derivation requiring private keys. Descriptors with unhardened derivation do not have "
+ "this limitation. The watchonly wallet can be imported into another node using 'restorewallet'.",
+ {
+ {"destination", RPCArg::Type::STR, RPCArg::Optional::NO, "The path to the filename the exported watchonly wallet will be saved to"},
+ },
+ RPCResult{
+ RPCResult::Type::OBJ, "", "",
+ {
+ {RPCResult::Type::STR, "exported_file", "The full path that the file has been exported to"},
+ },
+ },
+ RPCExamples{
+ HelpExampleCli("exportwatchonlywallet", "\"/path/to/export.dat\"")
+ + HelpExampleRpc("exportwatchonlywallet", "\"/path/to/export.dat\"")
+ },
+ [&](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
+ {
+ std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);
+ if (!pwallet) return UniValue::VNULL;
+ WalletContext& context = EnsureWalletContext(request.context);
+
+ std::string dest = request.params[0].get_str();
+
+ LOCK(pwallet->cs_wallet);
+ pwallet->TopUpKeyPool();
+ util::Result<std::string> exported = ExportWatchOnlyWallet(*pwallet, fs::PathFromString(dest), context);
+ if (!exported) {
+ throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(exported).original);
+ }
+ UniValue out{UniValue::VOBJ};
+ out.pushKV("exported_file", *exported);
+ return out;
+ }
+ };
+}
+
// addresses
RPCMethod getaddressinfo();
RPCMethod getnewaddress();
@@ -993,6 +1037,7 @@ std::span<const CRPCCommand> GetWalletRPCCommands()
{"wallet", &createwalletdescriptor},
{"wallet", &restorewallet},
{"wallet", &encryptwallet},
+ {"wallet", &exportwatchonlywallet},
{"wallet", &getaddressesbylabel},
{"wallet", &getaddressinfo},
{"wallet", &getbalance},
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.