aboutsummaryrefslogtreecommitdiff
path: root/src/wallet/api
diff options
context:
space:
mode:
Diffstat (limited to 'src/wallet/api')
-rw-r--r--src/wallet/api/wallet.cpp110
-rw-r--r--src/wallet/api/wallet.h3
-rw-r--r--src/wallet/api/wallet2_api.h21
3 files changed, 113 insertions, 21 deletions
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index fdecacd8f..7ade42e11 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -554,18 +554,26 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
}
// parse view secret key
+ bool has_viewkey = true;
+ crypto::secret_key viewkey;
if (viewkey_string.empty()) {
- setStatusError(tr("No view key supplied, cancelled"));
- return false;
+ if(has_spendkey) {
+ has_viewkey = false;
+ }
+ else {
+ setStatusError(tr("Neither view key nor spend key supplied, cancelled"));
+ return false;
+ }
}
- cryptonote::blobdata viewkey_data;
- if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key))
- {
- setStatusError(tr("failed to parse secret view key"));
- return false;
+ if(has_viewkey) {
+ cryptonote::blobdata viewkey_data;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(viewkey_string, viewkey_data) || viewkey_data.size() != sizeof(crypto::secret_key))
+ {
+ setStatusError(tr("failed to parse secret view key"));
+ return false;
+ }
+ viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
}
- crypto::secret_key viewkey = *reinterpret_cast<const crypto::secret_key*>(viewkey_data.data());
-
// check the spend and view keys match the given address
crypto::public_key pkey;
if(has_spendkey) {
@@ -578,26 +586,32 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path,
return false;
}
}
- if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
- setStatusError(tr("failed to verify secret view key"));
- return false;
- }
- if (info.address.m_view_public_key != pkey) {
- setStatusError(tr("view key does not match address"));
- return false;
+ if(has_viewkey) {
+ if (!crypto::secret_key_to_public_key(viewkey, pkey)) {
+ setStatusError(tr("failed to verify secret view key"));
+ return false;
+ }
+ if (info.address.m_view_public_key != pkey) {
+ setStatusError(tr("view key does not match address"));
+ return false;
+ }
}
try
{
- if (has_spendkey) {
+ if (has_spendkey && has_viewkey) {
m_wallet->generate(path, password, info.address, spendkey, viewkey);
- setSeedLanguage(language);
- LOG_PRINT_L1("Generated new wallet from keys with seed language: " + language);
+ LOG_PRINT_L1("Generated new wallet from spend key and view key");
}
- else {
+ if(!has_spendkey && has_viewkey) {
m_wallet->generate(path, password, info.address, viewkey);
LOG_PRINT_L1("Generated new view only wallet from keys");
}
+ if(has_spendkey && !has_viewkey) {
+ m_wallet->generate(path, password, spendkey, true, false, false);
+ setSeedLanguage(language);
+ LOG_PRINT_L1("Generated deterministic wallet from spend key with seed language: " + language);
+ }
}
catch (const std::exception& e) {
@@ -778,6 +792,16 @@ std::string WalletImpl::publicSpendKey() const
return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key);
}
+std::string WalletImpl::publicMultisigSignerKey() const
+{
+ try {
+ crypto::public_key signer = m_wallet->get_multisig_signer_public_key();
+ return epee::string_tools::pod_to_hex(signer);
+ } catch (const std::exception&) {
+ return "";
+ }
+}
+
std::string WalletImpl::path() const
{
return m_wallet->path();
@@ -1766,6 +1790,50 @@ bool WalletImpl::verifySignedMessage(const std::string &message, const std::stri
return m_wallet->verify(message, info.address, signature);
}
+std::string WalletImpl::signMultisigParticipant(const std::string &message) const
+{
+ clearStatus();
+
+ bool ready = false;
+ if (!m_wallet->multisig(&ready) || !ready) {
+ m_status = Status_Error;
+ m_errorString = tr("The wallet must be in multisig ready state");
+ return {};
+ }
+
+ try {
+ return m_wallet->sign_multisig_participant(message);
+ } catch (const std::exception& e) {
+ m_status = Status_Error;
+ m_errorString = e.what();
+ }
+
+ return {};
+}
+
+bool WalletImpl::verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const
+{
+ clearStatus();
+
+ cryptonote::blobdata pkeyData;
+ if(!epee::string_tools::parse_hexstr_to_binbuff(publicKey, pkeyData) || pkeyData.size() != sizeof(crypto::public_key))
+ {
+ m_status = Status_Error;
+ m_errorString = tr("Given string is not a key");
+ return false;
+ }
+
+ try {
+ crypto::public_key pkey = *reinterpret_cast<const crypto::public_key*>(pkeyData.data());
+ return m_wallet->verify_with_public_key(message, pkey, signature);
+ } catch (const std::exception& e) {
+ m_status = Status_Error;
+ m_errorString = e.what();
+ }
+
+ return false;
+}
+
bool WalletImpl::connectToDaemon()
{
bool result = m_wallet->check_connection(NULL, DEFAULT_CONNECTION_TIMEOUT_MILLIS);
@@ -1842,7 +1910,7 @@ void WalletImpl::refreshThreadFunc()
// if auto refresh enabled, we wait for the "m_refreshIntervalSeconds" interval.
// if not - we wait forever
if (m_refreshIntervalMillis > 0) {
- boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis);
+ boost::posix_time::milliseconds wait_for_ms(m_refreshIntervalMillis.load());
m_refreshCV.timed_wait(lock, wait_for_ms);
} else {
m_refreshCV.wait(lock);
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index e0e627c36..813ca4b30 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -91,6 +91,7 @@ public:
std::string publicViewKey() const;
std::string secretSpendKey() const;
std::string publicSpendKey() const;
+ std::string publicMultisigSignerKey() const;
std::string path() const;
bool store(const std::string &path);
std::string filename() const;
@@ -166,6 +167,8 @@ 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;
virtual std::string signMessage(const std::string &message);
virtual bool verifySignedMessage(const std::string &message, const std::string &address, const std::string &signature) const;
+ virtual std::string signMultisigParticipant(const std::string &message) const;
+ virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const;
virtual void startRefresh();
virtual void pauseRefresh();
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error);
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 27d290e68..5b99bd975 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -444,6 +444,12 @@ struct Wallet
virtual std::string publicSpendKey() const = 0;
/*!
+ * \brief publicMultisigSignerKey - returns public signer key
+ * \return - public multisignature signer key or empty string if wallet is not multisig
+ */
+ virtual std::string publicMultisigSignerKey() const = 0;
+
+ /*!
* \brief store - stores wallet to file.
* \param path - main filename to store wallet to. additionally stores address file and keys file.
* to store to the same file - just pass empty string;
@@ -825,6 +831,21 @@ struct Wallet
*/
virtual bool verifySignedMessage(const std::string &message, const std::string &addres, const std::string &signature) const = 0;
+ /*!
+ * \brief signMultisigParticipant signs given message with the multisig public signer key
+ * \param message message to sign
+ * \return signature in case of success. Sets status to Error and return empty string in case of error
+ */
+ virtual std::string signMultisigParticipant(const std::string &message) const = 0;
+ /*!
+ * \brief verifyMessageWithPublicKey verifies that message was signed with the given public key
+ * \param message message
+ * \param publicKey hex encoded public key
+ * \param signature signature of the message
+ * \return true if the signature is correct. false and sets error state in case of error
+ */
+ virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0;
+
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) = 0;
virtual std::string getDefaultDataDir() const = 0;