mirror of
https://github.com/wownero/wownero-cpp.git
synced 2026-10-17 23:31:32 +02:00
"Can create a wallet from keys" test passing;
remove wallet.get_seed() because redundant with get_private_spend_key()
This commit is contained in:
@@ -221,15 +221,6 @@ namespace monero {
|
||||
throw runtime_error("get_network_type() not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wallet's seed.
|
||||
*
|
||||
* @return the wallet's seed
|
||||
*/
|
||||
virtual string get_seed() const {
|
||||
throw runtime_error("get_seed() not implemented");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the wallet's mnemonic phrase derived from the seed.
|
||||
*
|
||||
|
||||
@@ -57,8 +57,8 @@
|
||||
#include <iostream>
|
||||
#include "mnemonics/electrum-words.h"
|
||||
#include "mnemonics/english.h"
|
||||
#include "cryptonote_basic.h"
|
||||
#include "cryptonote_basic/account.h"
|
||||
#include "cryptonote_basic/cryptonote_format_utils.h"
|
||||
#include "cryptonote_basic/cryptonote_basic_impl.h"
|
||||
#include "string_tools.h"
|
||||
#include "device/device.hpp"
|
||||
|
||||
@@ -89,27 +89,86 @@ namespace monero {
|
||||
if (!is_valid) throw runtime_error("Invalid mnemonic");
|
||||
if (language == crypto::ElectrumWords::old_language_name) language = Language::English().get_language_name();
|
||||
|
||||
// initialize keys
|
||||
cryptonote::account_base account{};
|
||||
account.generate(recovery_key, true, false);
|
||||
const cryptonote::account_keys& keys = account.get_keys();
|
||||
|
||||
// initialize wallet
|
||||
// initialize wallet account
|
||||
monero_wallet_keys* wallet = new monero_wallet_keys();
|
||||
wallet->m_seed = epee::string_tools::pod_to_hex(recovery_key);
|
||||
wallet->m_account = cryptonote::account_base{};
|
||||
wallet->m_account.generate(recovery_key, true, false);
|
||||
|
||||
// initialize remaining wallet
|
||||
wallet->m_network_type = network_type;
|
||||
wallet->m_mnemonic = mnemonic;
|
||||
wallet->m_primary_address = account.get_public_address_str(static_cast<cryptonote::network_type>(network_type));
|
||||
wallet->m_language = language;
|
||||
wallet->m_pub_view_key = epee::string_tools::pod_to_hex(keys.m_account_address.m_view_public_key);
|
||||
wallet->m_prv_view_key = epee::string_tools::pod_to_hex(keys.m_view_secret_key);
|
||||
wallet->m_pub_spend_key = epee::string_tools::pod_to_hex(keys.m_account_address.m_spend_public_key);
|
||||
wallet->m_prv_spend_key = epee::string_tools::pod_to_hex(keys.m_spend_secret_key);
|
||||
wallet->init_common();
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
monero_wallet_keys* monero_wallet_keys::create_wallet_from_keys(const monero_network_type network_type, const string& address, const string& view_key, const string& spend_key, const string& language) {
|
||||
cout << "monero_wallet_keys::create_wallet_from_keys(...)" << endl;
|
||||
throw runtime_error("create_wallet_from_keys() not implemented");
|
||||
|
||||
// validate and parse address
|
||||
cryptonote::address_parse_info info;
|
||||
if (!cryptonote::get_account_address_from_str(info, static_cast<cryptonote::network_type>(network_type), address)) throw runtime_error("failed to parse address");
|
||||
|
||||
// validate and parse optional private spend key
|
||||
crypto::secret_key spend_key_sk;
|
||||
bool has_spend_key = false;
|
||||
if (!spend_key.empty()) {
|
||||
cryptonote::blobdata spend_key_data;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(spend_key, spend_key_data) || spend_key_data.size() != sizeof(crypto::secret_key)) {
|
||||
throw runtime_error("failed to parse secret spend key");
|
||||
}
|
||||
has_spend_key = true;
|
||||
spend_key_sk = *reinterpret_cast<const crypto::secret_key*>(spend_key_data.data());
|
||||
}
|
||||
|
||||
// validate and parse private view key
|
||||
bool has_view_key = true;
|
||||
crypto::secret_key view_key_sk;
|
||||
if (view_key.empty()) {
|
||||
if (has_spend_key) has_view_key = false;
|
||||
else throw runtime_error("Neither view key nor spend key supplied, cancelled");
|
||||
}
|
||||
if (has_view_key) {
|
||||
cryptonote::blobdata view_key_data;
|
||||
if (!epee::string_tools::parse_hexstr_to_binbuff(view_key, view_key_data) || view_key_data.size() != sizeof(crypto::secret_key)) {
|
||||
throw runtime_error("failed to parse secret view key");
|
||||
}
|
||||
view_key_sk = *reinterpret_cast<const crypto::secret_key*>(view_key_data.data());
|
||||
}
|
||||
|
||||
// check the spend and view keys match the given address
|
||||
crypto::public_key pkey;
|
||||
if (has_spend_key) {
|
||||
if (!crypto::secret_key_to_public_key(spend_key_sk, pkey)) throw runtime_error("failed to verify secret spend key");
|
||||
if (info.address.m_spend_public_key != pkey) throw runtime_error("spend key does not match address");
|
||||
}
|
||||
if (has_view_key) {
|
||||
if (!crypto::secret_key_to_public_key(view_key_sk, pkey)) throw runtime_error("failed to verify secret view key");
|
||||
if (info.address.m_view_public_key != pkey) throw runtime_error("view key does not match address");
|
||||
}
|
||||
|
||||
// initialize wallet account
|
||||
monero_wallet_keys* wallet = new monero_wallet_keys();
|
||||
if (has_spend_key && has_view_key) {
|
||||
wallet->m_account.create_from_keys(info.address, spend_key_sk, view_key_sk);
|
||||
} else if (has_spend_key) {
|
||||
wallet->m_account.generate(spend_key_sk, true, false);
|
||||
} else {
|
||||
wallet->m_account.create_from_viewkey(info.address, view_key_sk);
|
||||
}
|
||||
|
||||
// initialize remaining wallet
|
||||
wallet->m_network_type = network_type;
|
||||
wallet->m_language = language;
|
||||
epee::wipeable_string wipeable_mnemonic;
|
||||
if (!crypto::ElectrumWords::bytes_to_words(spend_key_sk, wipeable_mnemonic, wallet->m_language)) {
|
||||
throw runtime_error("Failed to create mnemonic from private spend key for language: " + string(wallet->m_language));
|
||||
}
|
||||
wallet->m_mnemonic = string(wipeable_mnemonic.data(), wipeable_mnemonic.size());
|
||||
wallet->init_common();
|
||||
|
||||
return wallet;
|
||||
}
|
||||
|
||||
// ----------------------------- WALLET METHODS -----------------------------
|
||||
@@ -122,47 +181,20 @@ namespace monero {
|
||||
monero_version monero_wallet_keys::get_version() const {
|
||||
monero_version version;
|
||||
version.m_number = 65552; // same as monero-wallet-rpc v0.15.0.1 release
|
||||
version.m_is_release = false; // TODO: could pull from MONERO_VERSION_IS_RELEASE in version.cpp
|
||||
version.m_is_release = false; // TODO: could pull from MONERO_VERSION_IS_RELEASE in version.cpp
|
||||
return version;
|
||||
}
|
||||
|
||||
monero_network_type monero_wallet_keys::get_network_type() const {
|
||||
cout << "monero_wallet_keys::get_network_type()" << endl;
|
||||
throw runtime_error("monero_wallet_keys::get_network_type() not implemented");
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_language() const {
|
||||
return m_language;
|
||||
}
|
||||
|
||||
vector<string> monero_wallet_keys::get_languages() const {
|
||||
cout << "monero_wallet_keys::get_languages()" << endl;
|
||||
throw runtime_error("monero_wallet_keys::get_languages() not implemented");
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_mnemonic() const {
|
||||
return m_mnemonic;
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_public_view_key() const {
|
||||
return m_pub_view_key;
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_private_view_key() const {
|
||||
return m_prv_view_key;
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_public_spend_key() const {
|
||||
return m_pub_spend_key;
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_private_spend_key() const {
|
||||
return m_prv_spend_key;
|
||||
}
|
||||
|
||||
string monero_wallet_keys::get_address(uint32_t account_idx, uint32_t subaddress_idx) const {
|
||||
cout << "monero_wallet_keys::get_address()" << endl;
|
||||
throw runtime_error("monero_wallet_keys::get_address() not implemented");
|
||||
hw::device &hwdev = m_account.get_device();
|
||||
cryptonote::subaddress_index index{account_idx, subaddress_idx};
|
||||
cryptonote::account_public_address address = hwdev.get_subaddress(m_account.get_keys(), index);
|
||||
return cryptonote::get_account_address_as_str(static_cast<cryptonote::network_type>(m_network_type), !index.is_zero(), address);
|
||||
}
|
||||
|
||||
monero_subaddress monero_wallet_keys::get_address_index(const string& address) const {
|
||||
@@ -209,10 +241,22 @@ namespace monero {
|
||||
cout << "monero_wallet_keys::create_subaddress()" << endl;
|
||||
throw runtime_error("monero_wallet_keys::create_subaddress() not implemented");
|
||||
}
|
||||
void monero_wallet_keys::close() {
|
||||
|
||||
void monero_wallet_keys::close(bool save) {
|
||||
cout << "monero_wallet_keys::close()" << endl;
|
||||
throw runtime_error("monero_wallet_keys::close() not implemented");
|
||||
if (save) throw runtime_error("MoneroWalletKeys does not support saving");
|
||||
// no pointers to destroy
|
||||
}
|
||||
|
||||
// ------------------------------- PRIVATE HELPERS ----------------------------
|
||||
|
||||
void monero_wallet_keys::init_common() {
|
||||
m_primary_address = m_account.get_public_address_str(static_cast<cryptonote::network_type>(m_network_type));
|
||||
const cryptonote::account_keys& keys = m_account.get_keys();
|
||||
m_pub_view_key = epee::string_tools::pod_to_hex(keys.m_account_address.m_view_public_key);
|
||||
m_prv_view_key = epee::string_tools::pod_to_hex(keys.m_view_secret_key);
|
||||
m_pub_spend_key = epee::string_tools::pod_to_hex(keys.m_account_address.m_spend_public_key);
|
||||
m_prv_spend_key = epee::string_tools::pod_to_hex(keys.m_spend_secret_key);
|
||||
if (m_prv_spend_key == "0000000000000000000000000000000000000000000000000000000000000000") m_prv_spend_key = "";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "monero_wallet.h"
|
||||
#include "cryptonote_basic/account.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace monero;
|
||||
@@ -90,8 +91,8 @@ namespace monero {
|
||||
*
|
||||
* @param network_type is the wallet's network type
|
||||
* @param address is the address of the wallet to construct
|
||||
* @param view_key is the view key of the wallet to construct
|
||||
* @param spend_key is the spend key of the wallet to construct
|
||||
* @param view_key is the private view key of the wallet to construct
|
||||
* @param spend_key is the private spend key of the wallet to construct
|
||||
* @param language is the wallet and mnemonic's language (default = "English")
|
||||
*/
|
||||
static monero_wallet_keys* create_wallet_from_keys(const monero_network_type network_type, const string& address, const string& view_key, const string& spend_key, const string& language = "English");
|
||||
@@ -105,14 +106,15 @@ namespace monero {
|
||||
* Supported wallet methods.
|
||||
*/
|
||||
monero_version get_version() const;
|
||||
monero_network_type get_network_type() const;
|
||||
string get_mnemonic() const;
|
||||
string get_language() const;
|
||||
monero_network_type get_network_type() const { return m_network_type; }
|
||||
string get_mnemonic() const { return m_mnemonic; }
|
||||
string get_language() const { return m_language; }
|
||||
vector<string> get_languages() const;
|
||||
string get_public_view_key() const;
|
||||
string get_private_view_key() const;
|
||||
string get_public_spend_key() const;
|
||||
string get_private_spend_key() const;
|
||||
string get_private_view_key() const { return m_prv_view_key; }
|
||||
string get_private_spend_key() const { return m_prv_spend_key; }
|
||||
string get_public_view_key() const { return m_pub_view_key; }
|
||||
string get_public_spend_key() const { return m_pub_spend_key; }
|
||||
string get_primary_address() const { return m_primary_address; }
|
||||
string get_address(const uint32_t account_idx, const uint32_t subaddress_idx) const;
|
||||
monero_subaddress get_address_index(const string& address) const;
|
||||
monero_integrated_address get_integrated_address(const string& standard_address = "", const string& payment_id = "") const;
|
||||
@@ -125,12 +127,13 @@ namespace monero {
|
||||
monero_subaddress create_subaddress(uint32_t account_idx, const string& label = "");
|
||||
string sign(const string& msg) const;
|
||||
bool verify(const string& msg, const string& address, const string& signature) const;
|
||||
void close();
|
||||
void close(bool save = false);
|
||||
|
||||
// --------------------------------- PRIVATE --------------------------------
|
||||
|
||||
private:
|
||||
string m_seed;
|
||||
monero_network_type m_network_type;
|
||||
cryptonote::account_base m_account;
|
||||
string m_mnemonic;
|
||||
string m_language;
|
||||
string m_pub_view_key;
|
||||
@@ -138,5 +141,7 @@ namespace monero {
|
||||
string m_pub_spend_key;
|
||||
string m_prv_spend_key;
|
||||
string m_primary_address;
|
||||
|
||||
void init_common();
|
||||
};
|
||||
}
|
||||
|
||||
@@ -911,8 +911,8 @@ namespace monero {
|
||||
// initialize wallet
|
||||
wallet->m_w2 = unique_ptr<tools::wallet2>(new tools::wallet2(static_cast<cryptonote::network_type>(network_type), 1, true));
|
||||
if (has_spend_key && has_view_key) wallet->m_w2->generate(path, password, info.address, spend_key_sk, view_key_sk);
|
||||
if (!has_spend_key && has_view_key) wallet->m_w2->generate(path, password, info.address, view_key_sk);
|
||||
if (has_spend_key && !has_view_key) wallet->m_w2->generate(path, password, spend_key_sk, true, false);
|
||||
else if (has_spend_key) wallet->m_w2->generate(path, password, spend_key_sk, true, false);
|
||||
else wallet->m_w2->generate(path, password, info.address, view_key_sk);
|
||||
wallet->set_daemon_connection(daemon_connection);
|
||||
wallet->m_w2->set_refresh_from_block_height(restore_height);
|
||||
wallet->m_w2->set_seed_language(language);
|
||||
@@ -1010,9 +1010,9 @@ namespace monero {
|
||||
}
|
||||
|
||||
string monero_wallet_w2::get_mnemonic() const {
|
||||
epee::wipeable_string wipeablePassword;
|
||||
m_w2->get_seed(wipeablePassword);
|
||||
return string(wipeablePassword.data(), wipeablePassword.size());
|
||||
epee::wipeable_string wipeable_mnemonic;
|
||||
m_w2->get_seed(wipeable_mnemonic);
|
||||
return string(wipeable_mnemonic.data(), wipeable_mnemonic.size());
|
||||
}
|
||||
|
||||
string monero_wallet_w2::get_public_view_key() const {
|
||||
|
||||
@@ -131,8 +131,8 @@ namespace monero {
|
||||
* @param password is the password encrypt the wallet
|
||||
* @param network_type is the wallet's network type
|
||||
* @param address is the address of the wallet to construct
|
||||
* @param view_key is the view key of the wallet to construct
|
||||
* @param spend_key is the spend key of the wallet to construct
|
||||
* @param view_key is the private view key of the wallet to construct
|
||||
* @param spend_key is the private spend key of the wallet to construct
|
||||
* @param daemon_connection is connection information to a daemon (default = an unconnected wallet)
|
||||
* @param restore_height is the block height to restore (i.e. scan the chain) from (default = 0)
|
||||
* @param language is the wallet and mnemonic's language (default = "English")
|
||||
|
||||
Reference in New Issue
Block a user