From 5e42addb90ab9aeddf58b9ff608fb3da54d2e314 Mon Sep 17 00:00:00 2001 From: selsta Date: Tue, 1 Sep 2026 19:00:05 +0200 Subject: [PATCH] wallet_api: expose signed message verification details --- src/wallet/api/wallet.cpp | 17 +++++++++++++++-- src/wallet/api/wallet.h | 1 + src/wallet/api/wallet2_api.h | 21 +++++++++++++++++++++ src/wallet/wallet2.h | 4 ++-- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 07e09dd8d..2c31920a0 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -2262,13 +2262,26 @@ std::string WalletImpl::signMessage(const std::string &message, const std::strin } bool WalletImpl::verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const +{ + return verifySignedMessageWithDetails(message, address, signature).valid; +} + +Wallet::MessageSignatureResult WalletImpl::verifySignedMessageWithDetails(const std::string &message, const std::string &address, const std::string &signature) const { cryptonote::address_parse_info info; if (!cryptonote::get_account_address_from_str(info, m_wallet->nettype(), address)) - return false; + return {}; - return m_wallet->verify(message, info.address, signature).valid; + const tools::wallet2::message_signature_result_t result = m_wallet->verify(message, info.address, signature); + MessageSignatureType type = MessageSignatureType_Invalid; + switch (result.type) + { + case tools::wallet2::sign_with_spend_key: type = MessageSignatureType_Spend; break; + case tools::wallet2::sign_with_view_key: type = MessageSignatureType_View; break; + default: break; + } + return {result.valid, result.version, result.old, type}; } std::string WalletImpl::signMultisigParticipant(const std::string &message) const diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 931f31dd5..30659cd2d 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -211,6 +211,7 @@ public: virtual bool checkReserveProof(const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &total, uint64_t &spent) const override; virtual std::string signMessage(const std::string &message, const std::string &address) override; virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const override; + virtual MessageSignatureResult verifySignedMessageWithDetails(const std::string &message, const std::string &address, const std::string &signature) const override; virtual std::string signMultisigParticipant(const std::string &message) const override; virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const override; virtual void startRefresh() override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index a8c1e8d9c..de13e55c1 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -445,6 +445,19 @@ struct Wallet BackgroundSync_CustomPassword = 2 }; + enum MessageSignatureType { + MessageSignatureType_Invalid = 0, + MessageSignatureType_Spend, + MessageSignatureType_View + }; + + struct MessageSignatureResult { + bool valid = false; + unsigned version = 0; + bool old = false; + MessageSignatureType type = MessageSignatureType_Invalid; + }; + virtual ~Wallet() = 0; virtual std::string seed(const std::string& seed_offset = "") const = 0; virtual std::string getSeedLanguage() const = 0; @@ -1052,6 +1065,14 @@ struct Wallet * \return true if the signature verified, false otherwise */ virtual bool verifySignedMessage(const std::string &message, const std::string &addres, const std::string &signature) const = 0; + /*! + * \brief verifySignedMessageWithDetails - verify a signature and identify the signing key and algorithm + * \param message - the message (arbitrary byte data) + * \param address - the address the signature claims to be made with + * \param signature - the signature + * \return the verification result, including the signature version and key type + */ + virtual MessageSignatureResult verifySignedMessageWithDetails(const std::string &message, const std::string &address, const std::string &signature) const = 0; /*! * \brief signMultisigParticipant signs given message with the multisig public signer key diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 5c4b414b2..e0a778bdc 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -1304,9 +1304,9 @@ private: */ void set_account_tag_description(const std::string& tag, const std::string& description); - enum message_signature_type_t { sign_with_spend_key, sign_with_view_key }; + enum message_signature_type_t { sign_with_spend_key, sign_with_view_key, sign_with_invalid_key }; std::string sign(const std::string &data, message_signature_type_t signature_type, cryptonote::subaddress_index index = {0, 0}) const; - struct message_signature_result_t { bool valid; unsigned version; bool old; message_signature_type_t type; }; + struct message_signature_result_t { bool valid = false; unsigned version = 0; bool old = false; message_signature_type_t type = sign_with_invalid_key; }; message_signature_result_t verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const; /*!