diff --git a/doc/release-notes/release-notes-0.19.11.md b/doc/release-notes/release-notes-0.19.11.md --- a/doc/release-notes/release-notes-0.19.11.md +++ b/doc/release-notes/release-notes-0.19.11.md @@ -4,11 +4,12 @@ This release includes the following features and fixes: -Dynamic loading of wallets --------------------------- +Dynamic loading and creation of wallets +--------------------------------------- -Previously, wallets could only be loaded at startup, by specifying `-wallet` parameters on the command line or in the bitcoin.conf file. It is now possible to load wallets dynamically at runtime by calling the `loadwallet` RPC. +Previously, wallets could only be loaded or created at startup, by specifying `-wallet` parameters on the command line or in the bitcoin.conf file. It is now possible to load and create wallets dynamically at runtime: -The wallet can be specified as file/directory basename (which must be located in the `walletdir` directory), or as an absolute path to a file/directory. +- Existing wallets can be loaded by calling the `loadwallet` RPC. The wallet can be specified as file/directory basename (which must be located in the `walletdir` directory), or as an absolute path to a file/directory. +- New wallets can be created (and loaded) by calling the `createwallet` RPC. The provided name must not match a wallet file in the `walletdir` directory or the name of a wallet that is currently loaded. -This feature is currently only available through the RPC interface. Wallets loaded in this way will not display in the bitcoin-qt GUI. +This feature is currently only available through the RPC interface. diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -3409,38 +3409,49 @@ return obj; } -UniValue createwallet(const JSONRPCRequest& request) -{ - if (request.fHelp || request.params.size() != 1) +UniValue createwallet(const Config &config, const JSONRPCRequest &request) { + if (request.fHelp || request.params.size() != 1) { throw std::runtime_error( "createwallet \"wallet_name\"\n" "\nCreates and loads a new wallet.\n" "\nArguments:\n" - "1. \"wallet_name\" (string, required) The name for the new wallet.\n" + "1. \"wallet_name\" (string, required) The name for the new " + "wallet. If this is a path, the wallet will be created at the path " + "location.\n" "\nResult:\n" "{\n" - " \"name\" : , (string) The wallet name if created successfully.\n" - " \"warning\" : , (string) Warning message if wallet was not loaded cleanly.\n" + " \"name\" : , (string) The wallet name if " + "created successfully. If the wallet was created using a full " + "path, the wallet_name will be the full path.\n" + " \"warning\" : , (string) Warning message if " + "wallet was not loaded cleanly.\n" "}\n" - "\nExamples:\n" - + HelpExampleCli("createwallet", "\"test.dat\"") - + HelpExampleRpc("createwallet", "\"test.dat\"") - ); + "\nExamples:\n" + + HelpExampleCli("createwallet", "\"testwallet\"") + + HelpExampleRpc("createwallet", "\"testwallet\"")); + } + + const CChainParams &chainParams = config.GetChainParams(); + std::string wallet_name = request.params[0].get_str(); std::string error; std::string warning; fs::path wallet_path = fs::absolute(wallet_name, GetWalletDir()); if (fs::symlink_status(wallet_path).type() != fs::file_not_found) { - throw JSONRPCError(RPC_WALLET_ERROR, "Wallet " + wallet_name + " already exists."); + throw JSONRPCError(RPC_WALLET_ERROR, + "Wallet " + wallet_name + " already exists."); } - // Wallet::Verify will check if we're trying to create a wallet with a duplication name. - if (!CWallet::Verify(wallet_name, false, error, warning)) { - throw JSONRPCError(RPC_WALLET_ERROR, "Wallet file verification failed: " + error); + // Wallet::Verify will check if we're trying to create a wallet with a + // duplication name. + if (!CWallet::Verify(chainParams, wallet_name, false, error, warning)) { + throw JSONRPCError(RPC_WALLET_ERROR, + "Wallet file verification failed: " + error); } - std::shared_ptr const wallet = CWallet::CreateWalletFromFile(wallet_name, fs::absolute(wallet_name, GetWalletDir())); + std::shared_ptr const wallet = CWallet::CreateWalletFromFile( + chainParams, wallet_name, fs::absolute(wallet_name, GetWalletDir())); if (!wallet) { throw JSONRPCError(RPC_WALLET_ERROR, "Wallet creation failed."); } @@ -4507,7 +4518,7 @@ { "wallet", "abandontransaction", abandontransaction, {"txid"} }, { "wallet", "addmultisigaddress", addmultisigaddress, {"nrequired","keys","label|account"} }, { "wallet", "backupwallet", backupwallet, {"destination"} }, - { "wallet", "createwallet", createwallet, {"filename"} }, + { "wallet", "createwallet", createwallet, {"wallet_name"} }, { "wallet", "encryptwallet", encryptwallet, {"passphrase"} }, { "wallet", "getaccountaddress", getlabeladdress, {"account"} }, { "wallet", "getlabeladdress", getlabeladdress, {"label"} },