Changeset View
Changeset View
Standalone View
Standalone View
src/wallet/rpcwallet.cpp
Show All 17 Lines | |||||
#include <rpc/rawtransaction_util.h> | #include <rpc/rawtransaction_util.h> | ||||
#include <rpc/server.h> | #include <rpc/server.h> | ||||
#include <rpc/util.h> | #include <rpc/util.h> | ||||
#include <script/descriptor.h> | #include <script/descriptor.h> | ||||
#include <util/bip32.h> | #include <util/bip32.h> | ||||
#include <util/error.h> | #include <util/error.h> | ||||
#include <util/message.h> // For MessageSign() | #include <util/message.h> // For MessageSign() | ||||
#include <util/moneystr.h> | #include <util/moneystr.h> | ||||
#include <util/ref.h> | |||||
#include <util/string.h> | #include <util/string.h> | ||||
#include <util/system.h> | #include <util/system.h> | ||||
#include <util/translation.h> | #include <util/translation.h> | ||||
#include <util/url.h> | #include <util/url.h> | ||||
#include <util/vector.h> | #include <util/vector.h> | ||||
#include <wallet/coincontrol.h> | #include <wallet/coincontrol.h> | ||||
#include <wallet/context.h> | |||||
#include <wallet/rpcwallet.h> | #include <wallet/rpcwallet.h> | ||||
#include <wallet/wallet.h> | #include <wallet/wallet.h> | ||||
#include <wallet/walletdb.h> | #include <wallet/walletdb.h> | ||||
#include <wallet/walletutil.h> | #include <wallet/walletutil.h> | ||||
#include <univalue.h> | #include <univalue.h> | ||||
#include <event2/http.h> | #include <event2/http.h> | ||||
▲ Show 20 Lines • Show All 101 Lines • ▼ Show 20 Lines | |||||
void EnsureWalletIsUnlocked(const CWallet *pwallet) { | void EnsureWalletIsUnlocked(const CWallet *pwallet) { | ||||
if (pwallet->IsLocked()) { | if (pwallet->IsLocked()) { | ||||
throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, | throw JSONRPCError(RPC_WALLET_UNLOCK_NEEDED, | ||||
"Error: Please enter the wallet passphrase with " | "Error: Please enter the wallet passphrase with " | ||||
"walletpassphrase first."); | "walletpassphrase first."); | ||||
} | } | ||||
} | } | ||||
WalletContext &EnsureWalletContext(const util::Ref &context) { | |||||
if (!context.Has<WalletContext>()) { | |||||
throw JSONRPCError(RPC_INTERNAL_ERROR, "Wallet context not found"); | |||||
} | |||||
return context.Get<WalletContext>(); | |||||
} | |||||
// also_create should only be set to true only when the RPC is expected to add | // also_create should only be set to true only when the RPC is expected to add | ||||
// things to a blank wallet and make it no longer blank | // things to a blank wallet and make it no longer blank | ||||
LegacyScriptPubKeyMan &EnsureLegacyScriptPubKeyMan(CWallet &wallet, | LegacyScriptPubKeyMan &EnsureLegacyScriptPubKeyMan(CWallet &wallet, | ||||
bool also_create) { | bool also_create) { | ||||
LegacyScriptPubKeyMan *spk_man = wallet.GetLegacyScriptPubKeyMan(); | LegacyScriptPubKeyMan *spk_man = wallet.GetLegacyScriptPubKeyMan(); | ||||
if (!spk_man && also_create) { | if (!spk_man && also_create) { | ||||
spk_man = wallet.GetOrCreateLegacyScriptPubKeyMan(); | spk_man = wallet.GetOrCreateLegacyScriptPubKeyMan(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 3,012 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
}}, | }}, | ||||
RPCExamples{HelpExampleCli("loadwallet", "\"test.dat\"") + | RPCExamples{HelpExampleCli("loadwallet", "\"test.dat\"") + | ||||
HelpExampleRpc("loadwallet", "\"test.dat\"")}, | HelpExampleRpc("loadwallet", "\"test.dat\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
const CChainParams &chainParams = config.GetChainParams(); | const CChainParams &chainParams = config.GetChainParams(); | ||||
WalletContext &context = EnsureWalletContext(request.context); | |||||
WalletLocation location(request.params[0].get_str()); | WalletLocation location(request.params[0].get_str()); | ||||
if (!location.Exists()) { | if (!location.Exists()) { | ||||
throw JSONRPCError(RPC_WALLET_NOT_FOUND, | throw JSONRPCError(RPC_WALLET_NOT_FOUND, | ||||
"Wallet " + location.GetName() + " not found."); | "Wallet " + location.GetName() + " not found."); | ||||
} else if (fs::is_directory(location.GetPath())) { | } else if (fs::is_directory(location.GetPath())) { | ||||
// The given filename is a directory. Check that there's a wallet.dat | // The given filename is a directory. Check that there's a wallet.dat | ||||
// file. | // file. | ||||
fs::path wallet_dat_file = location.GetPath() / "wallet.dat"; | fs::path wallet_dat_file = location.GetPath() / "wallet.dat"; | ||||
if (fs::symlink_status(wallet_dat_file).type() == fs::file_not_found) { | if (fs::symlink_status(wallet_dat_file).type() == fs::file_not_found) { | ||||
throw JSONRPCError(RPC_WALLET_NOT_FOUND, | throw JSONRPCError(RPC_WALLET_NOT_FOUND, | ||||
"Directory " + location.GetName() + | "Directory " + location.GetName() + | ||||
" does not contain a wallet.dat file."); | " does not contain a wallet.dat file."); | ||||
} | } | ||||
} | } | ||||
bilingual_str error; | bilingual_str error; | ||||
std::vector<bilingual_str> warnings; | std::vector<bilingual_str> warnings; | ||||
std::shared_ptr<CWallet> const wallet = | std::shared_ptr<CWallet> const wallet = | ||||
LoadWallet(chainParams, *g_rpc_chain, location, error, warnings); | LoadWallet(chainParams, *context.chain, location, error, warnings); | ||||
if (!wallet) { | if (!wallet) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, error.original); | throw JSONRPCError(RPC_WALLET_ERROR, error.original); | ||||
} | } | ||||
UniValue obj(UniValue::VOBJ); | UniValue obj(UniValue::VOBJ); | ||||
obj.pushKV("name", wallet->GetName()); | obj.pushKV("name", wallet->GetName()); | ||||
obj.pushKV("warning", Join(warnings, "\n", OpOriginal)); | obj.pushKV("warning", Join(warnings, "\n", OpOriginal)); | ||||
▲ Show 20 Lines • Show All 115 Lines • ▼ Show 20 Lines | RPCHelpMan{ | ||||
{RPCResult::Type::STR, "warning", | {RPCResult::Type::STR, "warning", | ||||
"Warning message if wallet was not loaded cleanly."}, | "Warning message if wallet was not loaded cleanly."}, | ||||
}}, | }}, | ||||
RPCExamples{HelpExampleCli("createwallet", "\"testwallet\"") + | RPCExamples{HelpExampleCli("createwallet", "\"testwallet\"") + | ||||
HelpExampleRpc("createwallet", "\"testwallet\"")}, | HelpExampleRpc("createwallet", "\"testwallet\"")}, | ||||
} | } | ||||
.Check(request); | .Check(request); | ||||
WalletContext &context = EnsureWalletContext(request.context); | |||||
uint64_t flags = 0; | uint64_t flags = 0; | ||||
if (!request.params[1].isNull() && request.params[1].get_bool()) { | if (!request.params[1].isNull() && request.params[1].get_bool()) { | ||||
flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS; | flags |= WALLET_FLAG_DISABLE_PRIVATE_KEYS; | ||||
} | } | ||||
if (!request.params[2].isNull() && request.params[2].get_bool()) { | if (!request.params[2].isNull() && request.params[2].get_bool()) { | ||||
flags |= WALLET_FLAG_BLANK_WALLET; | flags |= WALLET_FLAG_BLANK_WALLET; | ||||
} | } | ||||
Show All 16 Lines | static UniValue createwallet(const Config &config, | ||||
} | } | ||||
if (!request.params[5].isNull() && request.params[5].get_bool()) { | if (!request.params[5].isNull() && request.params[5].get_bool()) { | ||||
flags |= WALLET_FLAG_DESCRIPTORS; | flags |= WALLET_FLAG_DESCRIPTORS; | ||||
} | } | ||||
bilingual_str error; | bilingual_str error; | ||||
std::shared_ptr<CWallet> wallet; | std::shared_ptr<CWallet> wallet; | ||||
WalletCreationStatus status = | WalletCreationStatus status = | ||||
CreateWallet(config.GetChainParams(), *g_rpc_chain, passphrase, flags, | CreateWallet(config.GetChainParams(), *context.chain, passphrase, flags, | ||||
request.params[0].get_str(), error, warnings, wallet); | request.params[0].get_str(), error, warnings, wallet); | ||||
switch (status) { | switch (status) { | ||||
case WalletCreationStatus::CREATION_FAILED: | case WalletCreationStatus::CREATION_FAILED: | ||||
throw JSONRPCError(RPC_WALLET_ERROR, error.original); | throw JSONRPCError(RPC_WALLET_ERROR, error.original); | ||||
case WalletCreationStatus::ENCRYPTION_FAILED: | case WalletCreationStatus::ENCRYPTION_FAILED: | ||||
throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, error.original); | throw JSONRPCError(RPC_WALLET_ENCRYPTION_FAILED, error.original); | ||||
case WalletCreationStatus::SUCCESS: | case WalletCreationStatus::SUCCESS: | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 1,620 Lines • ▼ Show 20 Lines | static UniValue upgradewallet(const Config &config, | ||||
bilingual_str error; | bilingual_str error; | ||||
std::vector<bilingual_str> warnings; | std::vector<bilingual_str> warnings; | ||||
if (!pwallet->UpgradeWallet(version, error, warnings)) { | if (!pwallet->UpgradeWallet(version, error, warnings)) { | ||||
throw JSONRPCError(RPC_WALLET_ERROR, error.original); | throw JSONRPCError(RPC_WALLET_ERROR, error.original); | ||||
} | } | ||||
return error.original; | return error.original; | ||||
} | } | ||||
void RegisterWalletRPCCommands( | Span<const CRPCCommand> GetWalletRPCCommands() { | ||||
interfaces::Chain &chain, | |||||
std::vector<std::unique_ptr<interfaces::Handler>> &handlers) { | |||||
// clang-format off | // clang-format off | ||||
static const CRPCCommand commands[] = { | static const CRPCCommand commands[] = { | ||||
// category name actor (function) argNames | // category name actor (function) argNames | ||||
// ------------------- ------------------------ ---------------------- ---------- | // ------------------- ------------------------ ---------------------- ---------- | ||||
{ "rawtransactions", "fundrawtransaction", fundrawtransaction, {"hexstring","options"} }, | { "rawtransactions", "fundrawtransaction", fundrawtransaction, {"hexstring","options"} }, | ||||
{ "wallet", "abandontransaction", abandontransaction, {"txid"} }, | { "wallet", "abandontransaction", abandontransaction, {"txid"} }, | ||||
{ "wallet", "addmultisigaddress", addmultisigaddress, {"nrequired","keys","label"} }, | { "wallet", "addmultisigaddress", addmultisigaddress, {"nrequired","keys","label"} }, | ||||
{ "wallet", "backupwallet", backupwallet, {"destination"} }, | { "wallet", "backupwallet", backupwallet, {"destination"} }, | ||||
Show All 37 Lines | static const CRPCCommand commands[] = { | ||||
{ "wallet", "walletcreatefundedpsbt", walletcreatefundedpsbt, {"inputs","outputs","locktime","options","bip32derivs"} }, | { "wallet", "walletcreatefundedpsbt", walletcreatefundedpsbt, {"inputs","outputs","locktime","options","bip32derivs"} }, | ||||
{ "wallet", "walletlock", walletlock, {} }, | { "wallet", "walletlock", walletlock, {} }, | ||||
{ "wallet", "walletpassphrase", walletpassphrase, {"passphrase","timeout"} }, | { "wallet", "walletpassphrase", walletpassphrase, {"passphrase","timeout"} }, | ||||
{ "wallet", "walletpassphrasechange", walletpassphrasechange, {"oldpassphrase","newpassphrase"} }, | { "wallet", "walletpassphrasechange", walletpassphrasechange, {"oldpassphrase","newpassphrase"} }, | ||||
{ "wallet", "walletprocesspsbt", walletprocesspsbt, {"psbt","sign","sighashtype","bip32derivs"} }, | { "wallet", "walletprocesspsbt", walletprocesspsbt, {"psbt","sign","sighashtype","bip32derivs"} }, | ||||
}; | }; | ||||
// clang-format on | // clang-format on | ||||
for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++) { | return MakeSpan(commands); | ||||
handlers.emplace_back(chain.handleRpc(commands[vcidx])); | |||||
} | } | ||||
} | |||||
interfaces::Chain *g_rpc_chain = nullptr; |