| 12 | |
| 13 | namespace wallet { |
| 14 | RPCHelpMan signmessage() |
| 15 | { |
| 16 | return RPCHelpMan{"signmessage", |
| 17 | "\nSign a message with the private key of an address" + |
| 18 | HELP_REQUIRING_PASSPHRASE, |
| 19 | { |
| 20 | {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The address to use for the private key."}, |
| 21 | {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."}, |
| 22 | }, |
| 23 | RPCResult{ |
| 24 | RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" |
| 25 | }, |
| 26 | RPCExamples{ |
| 27 | "\nUnlock the wallet for 30 seconds\n" |
| 28 | + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") + |
| 29 | "\nCreate the signature\n" |
| 30 | + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") + |
| 31 | "\nVerify the signature\n" |
| 32 | + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") + |
| 33 | "\nAs a JSON-RPC call\n" |
| 34 | + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"") |
| 35 | }, |
| 36 | [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue |
| 37 | { |
| 38 | const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request); |
| 39 | if (!pwallet) return NullUniValue; |
| 40 | |
| 41 | LOCK(pwallet->cs_wallet); |
| 42 | |
| 43 | EnsureWalletIsUnlocked(*pwallet); |
| 44 | |
| 45 | std::string strAddress = request.params[0].get_str(); |
| 46 | std::string strMessage = request.params[1].get_str(); |
| 47 | |
| 48 | CTxDestination dest = DecodeDestination(strAddress); |
| 49 | if (!IsValidDestination(dest)) { |
| 50 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address"); |
| 51 | } |
| 52 | |
| 53 | const PKHash* pkhash = std::get_if<PKHash>(&dest); |
| 54 | if (!pkhash) { |
| 55 | throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key"); |
| 56 | } |
| 57 | |
| 58 | std::string signature; |
| 59 | SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature); |
| 60 | if (err == SigningResult::SIGNING_FAILED) { |
| 61 | throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err)); |
| 62 | } else if (err != SigningResult::OK) { |
| 63 | throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err)); |
| 64 | } |
| 65 | |
| 66 | return signature; |
| 67 | }, |
| 68 | }; |
| 69 | } |
| 70 | } // namespace wallet |
nothing calls this directly
no test coverage detected