signmessage.cpp raw

   1  // Copyright (c) 2011-2022 The Limenka 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  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 limenka 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 UniValue::VNULL;
  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              MessageSignatureFormat sig_format{MessageSignatureFormat::LEGACY};
  55              // TODO: Make sig_format choosable
  56              if (!pkhash) {
  57                  sig_format = MessageSignatureFormat::SIMPLE;
  58              }
  59  
  60              std::string signature;
  61              SigningResult err = pwallet->SignMessage(sig_format, strMessage, dest, signature);
  62              if (err == SigningResult::SIGNING_FAILED) {
  63                  throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, SigningResultString(err));
  64              } else if (err != SigningResult::OK) {
  65                  throw JSONRPCError(RPC_WALLET_ERROR, SigningResultString(err));
  66              }
  67  
  68              return signature;
  69          },
  70      };
  71  }
  72  } // namespace wallet
  73