Coverage Report

Created: 2026-04-29 19:21

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
833
{
16
833
    return RPCMethod{
17
833
        "signmessage",
18
833
        "Sign a message with the private key of an address" +
19
833
          HELP_REQUIRING_PASSPHRASE,
20
833
        {
21
833
            {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address to use for the private key."},
22
833
            {"message", RPCArg::Type::STR, RPCArg::Optional::NO, "The message to create a signature of."},
23
833
        },
24
833
        RPCResult{
25
833
            RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64"
26
833
        },
27
833
        RPCExamples{
28
833
            "\nUnlock the wallet for 30 seconds\n"
29
833
            + HelpExampleCli("walletpassphrase", "\"mypassphrase\" 30") +
30
833
            "\nCreate the signature\n"
31
833
            + HelpExampleCli("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"my message\"") +
32
833
            "\nVerify the signature\n"
33
833
            + HelpExampleCli("verifymessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\" \"signature\" \"my message\"") +
34
833
            "\nAs a JSON-RPC call\n"
35
833
            + HelpExampleRpc("signmessage", "\"1D1ZrZNe3JUo7ZycKEYQQiQAWd9y54F4XX\", \"my message\"")
36
833
        },
37
833
        [](const RPCMethod& self, const JSONRPCRequest& request) -> UniValue
38
833
        {
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
833
    };
70
833
}
71
} // namespace wallet