Inside Bitcoin
Opening the selected file…
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
251+ HelpExampleCli("loadwallet", "\"DriveLetter:\\path\\to\\walletname\\\"")252+ HelpExampleRpc("loadwallet", R"("DriveLetter:\\path\\to\\walletname")")253},254[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue255{256WalletContext& context = EnsureWalletContext(request.context);257const std::string name(request.params[0].get_str());259DatabaseOptions options;260DatabaseStatus status;261ReadDatabaseArgs(*context.args, options);262options.require_existing = true;263bilingual_str error;264std::vector<bilingual_str> warnings;265std::optional<bool> load_on_start = request.params[1].isNull() ? std::nullopt : std::optional<bool>(request.params[1].get_bool());267{268LOCK(context.wallets_mutex);269if (std::any_of(context.wallets.begin(), context.wallets.end(), [&name](const auto& wallet) { return wallet->GetName() == name; })) {270throw JSONRPCError(RPC_WALLET_ALREADY_LOADED, "Wallet \"" + name + "\" is already loaded.");271}272}274std::shared_ptr<CWallet> const wallet = LoadWallet(context, name, load_on_start, options, status, error, warnings);276HandleWalletError(wallet, status, error);278UniValue obj(UniValue::VOBJ);279obj.pushKV("name", wallet->GetName());280PushWarnings(warnings, obj);282return obj;283},284};285}287static RPCMethod setwalletflag()288{289std::string flags;290for (auto& it : STRING_TO_WALLET_FLAG)291if (it.second & MUTABLE_WALLET_FLAGS)292flags += (flags == "" ? "" : ", ") + it.first;294return RPCMethod{295"setwalletflag",296"Change the state of the given wallet flag for a wallet.\n",297{298{"flag", RPCArg::Type::STR, RPCArg::Optional::NO, "The name of the flag to change. Current available flags: " + flags},299{"value", RPCArg::Type::BOOL, RPCArg::Default{true}, "The new state."},300},301RPCResult{302RPCResult::Type::OBJ, "", "",303{304{RPCResult::Type::STR, "flag_name", "The name of the flag that was modified"},305{RPCResult::Type::BOOL, "flag_state", "The new state of the flag"},306{RPCResult::Type::STR, "warnings", /*optional=*/true, "Any warnings associated with the change"},307}308},309RPCExamples{310HelpExampleCli("setwalletflag", "avoid_reuse")311+ HelpExampleRpc("setwalletflag", "\"avoid_reuse\"")312},313[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue314{315std::shared_ptr<CWallet> const pwallet = GetWalletForJSONRPCRequest(request);316if (!pwallet) return UniValue::VNULL;318std::string flag_str = request.params[0].get_str();319bool value = request.params[1].isNull() || request.params[1].get_bool();321if (!STRING_TO_WALLET_FLAG.contains(flag_str)) {322throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Unknown wallet flag: %s", flag_str));323}325auto flag = STRING_TO_WALLET_FLAG.at(flag_str);327if (!(flag & MUTABLE_WALLET_FLAGS)) {328throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is immutable: %s", flag_str));329}331UniValue res(UniValue::VOBJ);333if (pwallet->IsWalletFlagSet(flag) == value) {334throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("Wallet flag is already set to %s: %s", value ? "true" : "false", flag_str));335}337res.pushKV("flag_name", flag_str);338res.pushKV("flag_state", value);340if (value) {341pwallet->SetWalletFlag(flag);342} else {343pwallet->UnsetWalletFlag(flag);344}346if (flag && value && WALLET_FLAG_CAVEATS.contains(flag)) {347res.pushKV("warnings", WALLET_FLAG_CAVEATS.at(flag));348}350return res;351},352};353}355static RPCMethod createwallet()356{357return RPCMethod{358"createwallet",359"Creates and loads a new wallet.\n",360{361{"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."},362{"disable_private_keys", RPCArg::Type::BOOL, RPCArg::Default{false}, "Disable the possibility of private keys (only watchonlys are possible in this mode)."},363{"blank", RPCArg::Type::BOOL, RPCArg::Default{false}, "Create a blank wallet. A blank wallet has no keys."},364{"passphrase", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Encrypt the wallet with this passphrase."},365{"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."},366{"descriptors", RPCArg::Type::BOOL, RPCArg::Default{true}, "If set, must be \"true\""},367{"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},368{"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."},369},370RPCResult{371RPCResult::Type::OBJ, "", "",372{373{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."},374{RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to creating and loading the wallet.",375{376{RPCResult::Type::STR, "", ""},377}},378}379},380RPCExamples{381HelpExampleCli("createwallet", "\"testwallet\"")382+ HelpExampleRpc("createwallet", "\"testwallet\"")383+ HelpExampleCliNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"load_on_startup", true}})384+ HelpExampleRpcNamed("createwallet", {{"wallet_name", "descriptors"}, {"avoid_reuse", true}, {"load_on_startup", true}})385},386[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue387{388WalletContext& context = EnsureWalletContext(request.context);389uint64_t flags = 0;390if (!request.params[1].isNull() && request.params[1].get_bool()) {391flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS;392}394if (!request.params[2].isNull() && request.params[2].get_bool()) {395flags |= WALLET_FLAG_BLANK_WALLET;396}397SecureString passphrase;398passphrase.reserve(100);399std::vector<bilingual_str> warnings;400if (!request.params[3].isNull()) {401passphrase = std::string_view{request.params[3].get_str()};402if (passphrase.empty()) {403// Empty string means unencrypted404warnings.emplace_back(Untranslated("Empty string given as passphrase, wallet will not be encrypted."));405}406}408if (!request.params[4].isNull() && request.params[4].get_bool()) {409flags |= WALLET_FLAG_AVOID_REUSE;410}411flags |= WALLET_FLAG_DESCRIPTORS;412if (!self.Arg<bool>("descriptors")) {413throw JSONRPCError(RPC_WALLET_ERROR, "descriptors argument must be set to \"true\"; it is no longer possible to create a legacy wallet.");414}415if (!request.params[7].isNull() && request.params[7].get_bool()) {416#ifdef ENABLE_EXTERNAL_SIGNER417flags |= WALLET_FLAG_EXTERNAL_SIGNER;418#else419throw JSONRPCError(RPC_WALLET_ERROR, "Compiled without external signing support (required for external signing)");420#endif421}423DatabaseOptions options;424DatabaseStatus status;425ReadDatabaseArgs(*context.args, options);426options.require_create = true;427options.create_flags = flags;428options.create_passphrase = passphrase;429bilingual_str error;430std::optional<bool> load_on_start = request.params[6].isNull() ? std::nullopt : std::optional<bool>(request.params[6].get_bool());431const std::shared_ptr<CWallet> wallet = CreateWallet(context, request.params[0].get_str(), load_on_start, options, status, error, warnings);432HandleWalletError(wallet, status, error);434UniValue obj(UniValue::VOBJ);435obj.pushKV("name", wallet->GetName());436PushWarnings(warnings, obj);438return obj;439},440};441}443static RPCMethod unloadwallet()444{445return RPCMethod{"unloadwallet",446"Unloads the wallet referenced by the request endpoint or the wallet_name argument.\n"447"If both are specified, they must be identical.",448{449{"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."},450{"load_on_startup", RPCArg::Type::BOOL, RPCArg::Optional::OMITTED, "Save wallet name to persistent settings and load on startup. True to add wallet to startup list, false to remove, null to leave unchanged."},451},452RPCResult{RPCResult::Type::OBJ, "", "", {453{RPCResult::Type::ARR, "warnings", /*optional=*/true, "Warning messages, if any, related to unloading the wallet.",454{455{RPCResult::Type::STR, "", ""},456}},457}},458RPCExamples{459HelpExampleCli("unloadwallet", "wallet_name")460+ HelpExampleRpc("unloadwallet", R"("wallet_name")")461},462[](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue463{464const std::string wallet_name{EnsureUniqueWalletName(request, self.MaybeArg<std::string_view>("wallet_name"))};466WalletContext& context = EnsureWalletContext(request.context);467std::shared_ptr<CWallet> wallet = GetWallet(context, wallet_name);468if (!wallet) {469throw JSONRPCError(RPC_WALLET_NOT_FOUND, "Requested wallet does not exist or is not loaded");470}472std::vector<bilingual_str> warnings;473{474WalletRescanReserver reserver(*wallet);475if (!reserver.reserve()) {476throw JSONRPCError(RPC_WALLET_ERROR, "Wallet is currently rescanning. Abort existing rescan or wait.");477}479// Release the "main" shared pointer and prevent further notifications.480// Note that any attempt to load the same wallet would fail until the wallet481// is destroyed (see CheckUniqueFileid).482std::optional<bool> load_on_start{self.MaybeArg<bool>("load_on_startup")};483if (!RemoveWallet(context, wallet, load_on_start, warnings)) {484throw JSONRPCError(RPC_MISC_ERROR, "Requested wallet already unloaded");485}486}488WaitForDeleteWallet(std::move(wallet));490UniValue result(UniValue::VOBJ);491PushWarnings(warnings, result);493return result;494},495};496}498RPCMethod simulaterawtransaction()499{500return RPCMethod{