diff options
Diffstat (limited to 'src/wallet')
-rw-r--r-- | src/wallet/rpc/signmessage.cpp | 68 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 61 | ||||
-rw-r--r-- | src/wallet/rpcwallet.h | 2 |
3 files changed, 72 insertions, 59 deletions
diff --git a/src/wallet/rpc/signmessage.cpp b/src/wallet/rpc/signmessage.cpp new file mode 100644 index 0000000000..275eb2f1f7 --- /dev/null +++ b/src/wallet/rpc/signmessage.cpp @@ -0,0 +1,68 @@ +// Copyright (c) 2011-2021 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include <key_io.h> +#include <rpc/util.h> +#include <util/message.h> +#include <wallet/rpcwallet.h> +#include <wallet/wallet.h> + +#include <univalue.h> + +RPCHelpMan signmessage() +{ + return RPCHelpMan{"signmessage", + "\nSign a message with the private key of an address" + + HELP_REQUIRING_PASSPHRASE, + { + {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."}, + {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, + }, + RPCResult{ + RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" + }, + RPCExamples{ + "\nUnlock the wallet for 30 seconds\n" + + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + + "\nCreate the signature\n" + + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + + "\nVerify the signature\n" + + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); + if (!pwallet) return NullUniValue; + + LOCK(pwallet->cs_wallet); + + EnsureWalletIsUnlocked(*pwallet); + + std::string strAddress = request.params[0].get_str(); + std::string strMessage = request.params[1].get_str(); + + CTxDestination dest = DecodeDestination(strAddress); + if (!IsValidDestination(dest)) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); + } + + const PKHash* pkhash = std::get_if<PKHash>(&dest); + if (!pkhash) { + throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); + } + + std::string signature; + SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); + if (err == SigningResult::SIGNING_FAILED) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); + } else if (err != SigningResult::OK) { + throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); + } + + return signature; + }, + }; +} diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index bb5b388791..beda86e4b4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -20,7 +20,6 @@ #include <script/sign.h> #include <util/bip32.h> #include <util/fees.h> -#include <util/message.h> // For MessageSign() #include <util/moneystr.h> #include <util/string.h> #include <util/system.h> @@ -48,7 +47,7 @@ using interfaces::FoundBlock; static const std::string WALLET_ENDPOINT_BASE = "/wallet/"; -static const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"}; +const std::string HELP_REQUIRING_PASSPHRASE{"\nRequires wallet passphrase to be set with walletpassphrase call if wallet is encrypted.\n"}; static inline bool GetAvoidReuseFlag(const CWallet& wallet, const UniValue& param) { bool can_avoid_reuse = wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE); @@ -612,63 +611,6 @@ static RPCHelpMan listaddressgroupings() }; } -static RPCHelpMan signmessage() -{ - return RPCHelpMan{"signmessage", - "\nSign a message with the private key of an address" + - HELP_REQUIRING_PASSPHRASE, - { - {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."}, - {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, - }, - RPCResult{ - RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" - }, - RPCExamples{ - "\nUnlock the wallet for 30 seconds\n" - + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + - "\nCreate the signature\n" - + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + - "\nVerify the signature\n" - + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + - "\nAs a JSON-RPC call\n" - + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") - }, - [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue -{ - const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); - if (!pwallet) return NullUniValue; - - LOCK(pwallet->cs_wallet); - - EnsureWalletIsUnlocked(*pwallet); - - std::string strAddress = request.params[0].get_str(); - std::string strMessage = request.params[1].get_str(); - - CTxDestination dest = DecodeDestination(strAddress); - if (!IsValidDestination(dest)) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); - } - - const PKHash* pkhash = std::get_if<PKHash>(&dest); - if (!pkhash) { - throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); - } - - std::string signature; - SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); - if (err == SigningResult::SIGNING_FAILED) { - throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); - } else if (err != SigningResult::OK){ - throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); - } - - return signature; -}, - }; -} - static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) { std::set<CTxDestination> address_set; @@ -4862,6 +4804,7 @@ RPCHelpMan removeprunedfunds(); RPCHelpMan importmulti(); RPCHelpMan importdescriptors(); RPCHelpMan listdescriptors(); +RPCHelpMan signmessage(); Span<const CRPCCommand> GetWalletRPCCommands() { diff --git a/src/wallet/rpcwallet.h b/src/wallet/rpcwallet.h index 40eb49cf87..fda685e9ee 100644 --- a/src/wallet/rpcwallet.h +++ b/src/wallet/rpcwallet.h @@ -21,6 +21,8 @@ class CTransaction; struct PartiallySignedTransaction; struct WalletContext; +extern const std::string HELP_REQUIRING_PASSPHRASE; + Span<const CRPCCommand> GetWalletRPCCommands(); /** |