Coverage Report

Created: 2026-05-30 09:47

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/tmp/bitcoin/src/wallet/rpc/signmessage.cpp
Line
Count
Source
1
// Copyright (c) 2011-present 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 <common/signmessage.h>
6
#include <key_io.h>
7
#include <rpc/util.h>
8
#include <wallet/rpc/util.h>
9
#include <wallet/wallet.h>
10
11
#include <univalue.h>
12
13
namespace wallet {
14
RPCMethod signmessage()
15
839
{
16
839
    return RPCMethod{
17
839
        "signmessage",
18
839
        "Sign a message with the private key of an address" +
19
839
          HELP_REQUIRING_PASSPHRASE,
20
839
        {
21
839
            {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."},
22
839
            {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
23
839
        },
24
839
        RPCResult{
25
839
            RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
26
839
        },
27
839
        RPCExamples{
28
839
            "\nUnlock the wallet for 30 seconds\n"
29
839
            + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
30
839
            "\nCreate the signature\n"
31
839
            + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
32
839
            "\nVerify the signature\n"
33
839
            + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
34
839
            "\nAs a JSON-RPC call\n"
35
839
            + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
36
839
        },
37
839
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
38
839
        {
39
17
            const std::shared_ptr<const CWallet> pwallet = GetWalletForJSONRPCRequest(request);
40
17
            if (!pwallet) return UniValue::VNULL;
41
42
17
            LOCK(pwallet->cs_wallet);
43
44
17
            EnsureWalletIsUnlocked(*pwallet);
45
46
17
            std::string strAddress = request.params[0].get_str();
47
17
            std::string strMessage = request.params[1].get_str();
48
49
17
            CTxDestination dest = DecodeDestination(strAddress);
50
17
            if (!IsValidDestination(dest)) {
51
1
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid address");
52
1
            }
53
54
16
            const PKHash* pkhash = std::get_if<PKHash>(&dest);
55
16
            if (!pkhash) {
56
0
                throw JSONRPCError(RPC_TYPE_ERROR, "Address does not refer to key");
57
0
            }
58
59
16
            std::string signature;
60
16
            SigningResult err = pwallet->SignMessage(strMessage, *pkhash, signature);
61
16
            if (err == SigningResult::SIGNING_FAILED) {
62
0
                throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err));
63
16
            } else if (err != SigningResult::OK) {
64
0
                throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err));
65
0
            }
66
67
16
            return signature;
68
16
        },
69
839
    };
70
839
}
71
} // namespace wallet