Line data Source code
1 : // Copyright (c) 2011-2021 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #include <key_io.h> 6 : #include <rpc/util.h> 7 : #include <util/message.h> 8 : #include <wallet/rpc/util.h> 9 : #include <wallet/wallet.h> 10 : 11 : #include <univalue.h> 12 : 13 : namespace wallet { 14 2962 : RPCHelpMan signmessage() 15 : { 16 5924 : return RPCHelpMan{"signmessage", 17 2962 : "\nSign a message with the private key of an address" + 18 : HELP_REQUIRING_PASSPHRASE, 19 8886 : { 20 2962 : {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The Dash address to use for the private key."}, 21 2962 : {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, 22 : }, 23 2962 : RPCResult{ 24 2962 : RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" 25 : }, 26 2962 : RPCExamples{ 27 : "\nUnlock the wallet for 30 seconds\n" 28 2962 : + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + 29 : "\nCreate the signature\n" 30 2962 : + HelpExampleCli("signmessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"my message\"") + 31 : "\nVerify the signature\n" 32 2962 : + HelpExampleCli("verifymessage", "\"" + EXAMPLE_ADDRESS[0] + "\" \"signature\" \"my message\"") + 33 : "\nAs a JSON-RPC call\n" 34 2962 : + HelpExampleRpc("signmessage", "\"" + EXAMPLE_ADDRESS[0] + "\", \"my message\"") 35 : }, 36 3018 : [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue 37 : { 38 56 : const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); 39 56 : if (!pwallet) return UniValue::VNULL; 40 : 41 56 : LOCK(pwallet->cs_wallet); 42 : 43 56 : EnsureWalletIsUnlocked(*pwallet); 44 : 45 32 : std::string strAddress = request.params[0].get_str(); 46 32 : std::string strMessage = request.params[1].get_str(); 47 : 48 32 : CTxDestination dest = DecodeDestination(strAddress); 49 32 : if (!IsValidDestination(dest)) { 50 2 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); 51 : } 52 : 53 30 : const PKHash* pkhash = std::get_if<PKHash>(&dest); 54 30 : if (!pkhash) { 55 0 : throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); 56 : } 57 : 58 30 : std::string signature; 59 30 : SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); 60 30 : if (err == SigningResult::SIGNING_FAILED) { 61 0 : throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); 62 30 : } else if (err != SigningResult::OK) { 63 0 : throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); 64 : } 65 : 66 30 : return signature; 67 58 : }, 68 : }; 69 0 : } 70 : } // namespace wallet