"Can create a wallet from keys" test passing;

remove wallet.get_seed() because redundant with get_private_spend_key()
This commit is contained in:
woodser
2019-12-05 07:50:36 -05:00
parent afcf232960
commit d28c4e574b
5 changed files with 116 additions and 76 deletions
-9
View File
@@ -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.
*
+93 -49
View File
@@ -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 = "";
}
}
+16 -11
View File
@@ -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();
};
}
+5 -5
View File
@@ -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 {
+2 -2
View File
@@ -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")