aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDusan Klinec <dusan.klinec@gmail.com>2019-05-31 10:41:52 +0200
committerDusan Klinec <dusan.klinec@gmail.com>2019-06-17 16:49:04 +0200
commitf074b6b5715f90960e5ebf8d440101ba446d94b0 (patch)
treea25bbf87a3ae70430ebc3e73755a07ee708d2f8e
parentMerge pull request #5548 (diff)
downloadmonero-f074b6b5715f90960e5ebf8d440101ba446d94b0.tar.xz
device: show address on device display
- Trezor: support for device address display (subaddress, integrated address) - Wallet::API support added - Simplewallet: - address device [<index>] - address new <label> // shows address on device also - integrated_address [device] <payment_id|address> // new optional "device" arg to display also on the device
m---------external/trezor-common0
-rw-r--r--src/device/device.hpp1
-rw-r--r--src/device/device_cold.hpp1
-rw-r--r--src/device_trezor/device_trezor.cpp16
-rw-r--r--src/device_trezor/device_trezor.hpp4
-rw-r--r--src/device_trezor/trezor/protocol.cpp3
-rw-r--r--src/simplewallet/simplewallet.cpp55
-rw-r--r--src/wallet/api/wallet.cpp17
-rw-r--r--src/wallet/api/wallet.h1
-rw-r--r--src/wallet/api/wallet2_api.h3
-rw-r--r--src/wallet/wallet2.cpp30
-rw-r--r--src/wallet/wallet2.h2
12 files changed, 127 insertions, 6 deletions
diff --git a/external/trezor-common b/external/trezor-common
-Subproject cb238cb1f134accc4200217d9511115a8f61c6c
+Subproject 31a0073c62738827b48d725facd376687942912
diff --git a/src/device/device.hpp b/src/device/device.hpp
index 866e2c676..215e97eb6 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -236,6 +236,7 @@ namespace hw {
virtual bool compute_key_image(const cryptonote::account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const cryptonote::subaddress_index& received_index, cryptonote::keypair& in_ephemeral, crypto::key_image& ki) { return false; }
virtual void computing_key_images(bool started) {};
virtual void set_network_type(cryptonote::network_type network_type) { }
+ virtual void display_address(const cryptonote::subaddress_index& index, const boost::optional<crypto::hash8> &payment_id) {}
protected:
device_mode mode;
diff --git a/src/device/device_cold.hpp b/src/device/device_cold.hpp
index 31b1504ab..22708c46a 100644
--- a/src/device/device_cold.hpp
+++ b/src/device/device_cold.hpp
@@ -47,6 +47,7 @@ namespace hw {
std::vector<cryptonote::address_parse_info> tx_recipients; // as entered by user
boost::optional<int> bp_version; // BP version to use
boost::optional<unsigned> client_version; // Signing client version to use (testing)
+ boost::optional<uint8_t> hard_fork; // hard fork being used for the transaction
};
class device_cold {
diff --git a/src/device_trezor/device_trezor.cpp b/src/device_trezor/device_trezor.cpp
index b1022dd9c..a77f6697f 100644
--- a/src/device_trezor/device_trezor.cpp
+++ b/src/device_trezor/device_trezor.cpp
@@ -200,6 +200,10 @@ namespace trezor {
}
}
+ void device_trezor::display_address(const cryptonote::subaddress_index& index, const boost::optional<crypto::hash8> &payment_id) {
+ get_address(index, payment_id, true);
+ }
+
/* ======================================================================= */
/* Helpers */
/* ======================================================================= */
@@ -209,8 +213,12 @@ namespace trezor {
/* ======================================================================= */
std::shared_ptr<messages::monero::MoneroAddress> device_trezor::get_address(
+ const boost::optional<cryptonote::subaddress_index> & subaddress,
+ const boost::optional<crypto::hash8> & payment_id,
+ bool show_address,
const boost::optional<std::vector<uint32_t>> & path,
const boost::optional<cryptonote::network_type> & network_type){
+ CHECK_AND_ASSERT_THROW_MES(!payment_id || !subaddress || subaddress->is_zero(), "Subaddress cannot be integrated");
TREZOR_AUTO_LOCK_CMD();
require_connected();
device_state_reset_unsafe();
@@ -218,6 +226,14 @@ namespace trezor {
auto req = std::make_shared<messages::monero::MoneroGetAddress>();
this->set_msg_addr<messages::monero::MoneroGetAddress>(req.get(), path, network_type);
+ req->set_show_display(show_address);
+ if (subaddress){
+ req->set_account(subaddress->major);
+ req->set_minor(subaddress->minor);
+ }
+ if (payment_id){
+ req->set_payment_id(std::string(payment_id->data, 8));
+ }
auto response = this->client_exchange<messages::monero::MoneroAddress>(req);
MTRACE("Get address response received");
diff --git a/src/device_trezor/device_trezor.hpp b/src/device_trezor/device_trezor.hpp
index 0e91847dc..a26a42788 100644
--- a/src/device_trezor/device_trezor.hpp
+++ b/src/device_trezor/device_trezor.hpp
@@ -110,6 +110,7 @@ namespace trezor {
/* ======================================================================= */
bool get_public_address(cryptonote::account_public_address &pubkey) override;
bool get_secret_keys(crypto::secret_key &viewkey , crypto::secret_key &spendkey) override;
+ void display_address(const cryptonote::subaddress_index& index, const boost::optional<crypto::hash8> &payment_id) override;
/* ======================================================================= */
/* TREZOR PROTOCOL */
@@ -119,6 +120,9 @@ namespace trezor {
* Get address. Throws.
*/
std::shared_ptr<messages::monero::MoneroAddress> get_address(
+ const boost::optional<cryptonote::subaddress_index> & subaddress = boost::none,
+ const boost::optional<crypto::hash8> & payment_id = boost::none,
+ bool show_address = false,
const boost::optional<std::vector<uint32_t>> & path = boost::none,
const boost::optional<cryptonote::network_type> & network_type = boost::none);
diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp
index 5fe08abbe..61e51be14 100644
--- a/src/device_trezor/trezor/protocol.cpp
+++ b/src/device_trezor/trezor/protocol.cpp
@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
+#include "version.h"
#include "protocol.hpp"
#include <unordered_map>
#include <set>
@@ -502,6 +503,8 @@ namespace tx {
tsx_data.set_num_inputs(static_cast<google::protobuf::uint32>(tx.sources.size()));
tsx_data.set_mixin(static_cast<google::protobuf::uint32>(tx.sources[0].outputs.size() - 1));
tsx_data.set_account(tx.subaddr_account);
+ tsx_data.set_monero_version(std::string(MONERO_VERSION) + "|" + MONERO_VERSION_TAG);
+ tsx_data.set_hard_fork(m_aux_data->hard_fork ? m_aux_data->hard_fork.get() : 0);
assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end());
// Rsig decision
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 02a099811..43323be2c 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -177,8 +177,8 @@ namespace
" account tag <tag_name> <account_index_1> [<account_index_2> ...]\n"
" account untag <account_index_1> [<account_index_2> ...]\n"
" account tag_description <tag_name> <description>");
- const char* USAGE_ADDRESS("address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed>]");
- const char* USAGE_INTEGRATED_ADDRESS("integrated_address [<payment_id> | <address>]");
+ const char* USAGE_ADDRESS("address [ new <label text with white spaces allowed> | all | <index_min> [<index_max>] | label <index> <label text with white spaces allowed> | device [<index>]]");
+ const char* USAGE_INTEGRATED_ADDRESS("integrated_address [device] [<payment_id> | <address>]");
const char* USAGE_ADDRESS_BOOK("address_book [(add ((<address> [pid <id>])|<integrated address>) [<description possibly with whitespaces>])|(delete <index>)]");
const char* USAGE_SET_VARIABLE("set <option> [<value>]");
const char* USAGE_GET_TX_KEY("get_tx_key <txid>");
@@ -8501,6 +8501,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::
// address all
// address <index_min> [<index_max>]
// address label <index> <label text with white spaces allowed>
+ // address device [<index>]
std::vector<std::string> local_args = args;
tools::wallet2::transfer_container transfers;
@@ -8537,6 +8538,7 @@ bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::
label = tr("(Untitled address)");
m_wallet->add_subaddress(m_current_subaddress_account, label);
print_address_sub(m_wallet->get_num_subaddresses(m_current_subaddress_account) - 1);
+ m_wallet->device_show_address(m_current_subaddress_account, m_wallet->get_num_subaddresses(m_current_subaddress_account) - 1, boost::none);
}
else if (local_args.size() >= 2 && local_args[0] == "label")
{
@@ -8585,6 +8587,27 @@ bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::
for (index = index_min; index <= index_max; ++index)
print_address_sub(index);
}
+ else if (local_args[0] == "device")
+ {
+ index = 0;
+ local_args.erase(local_args.begin());
+ if (local_args.size() > 0)
+ {
+ if (!epee::string_tools::get_xtype_from_string(index, local_args[0]))
+ {
+ fail_msg_writer() << tr("failed to parse index: ") << local_args[0];
+ return true;
+ }
+ if (index >= m_wallet->get_num_subaddresses(m_current_subaddress_account))
+ {
+ fail_msg_writer() << tr("<index> is out of bounds");
+ return true;
+ }
+ }
+
+ print_address_sub(index);
+ m_wallet->device_show_address(m_current_subaddress_account, index, boost::none);
+ }
else
{
PRINT_USAGE(USAGE_ADDRESS);
@@ -8596,12 +8619,29 @@ bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::
bool simple_wallet::print_integrated_address(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
crypto::hash8 payment_id;
- if (args.size() > 1)
+ bool display_on_device = false;
+ std::vector<std::string> local_args = args;
+
+ if (local_args.size() > 0 && local_args[0] == "device")
+ {
+ local_args.erase(local_args.begin());
+ display_on_device = true;
+ }
+
+ auto device_show_integrated = [this, display_on_device](crypto::hash8 payment_id)
+ {
+ if (display_on_device)
+ {
+ m_wallet->device_show_address(m_current_subaddress_account, 0, payment_id);
+ }
+ };
+
+ if (local_args.size() > 1)
{
PRINT_USAGE(USAGE_INTEGRATED_ADDRESS);
return true;
}
- if (args.size() == 0)
+ if (local_args.size() == 0)
{
if (m_current_subaddress_account != 0)
{
@@ -8611,9 +8651,10 @@ bool simple_wallet::print_integrated_address(const std::vector<std::string> &arg
payment_id = crypto::rand<crypto::hash8>();
success_msg_writer() << tr("Random payment ID: ") << payment_id;
success_msg_writer() << tr("Matching integrated address: ") << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->nettype());
+ device_show_integrated(payment_id);
return true;
}
- if(tools::wallet2::parse_short_payment_id(args.back(), payment_id))
+ if(tools::wallet2::parse_short_payment_id(local_args.back(), payment_id))
{
if (m_current_subaddress_account != 0)
{
@@ -8621,16 +8662,18 @@ bool simple_wallet::print_integrated_address(const std::vector<std::string> &arg
return true;
}
success_msg_writer() << m_wallet->get_account().get_public_integrated_address_str(payment_id, m_wallet->nettype());
+ device_show_integrated(payment_id);
return true;
}
else {
address_parse_info info;
- if(get_account_address_from_str(info, m_wallet->nettype(), args.back()))
+ if(get_account_address_from_str(info, m_wallet->nettype(), local_args.back()))
{
if (info.has_payment_id)
{
success_msg_writer() << boost::format(tr("Integrated address: %s, payment ID: %s")) %
get_account_address_as_str(m_wallet->nettype(), false, info.address) % epee::string_tools::pod_to_hex(info.payment_id);
+ device_show_integrated(info.payment_id);
}
else
{
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index 1711db482..a85e31474 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -2419,6 +2419,23 @@ uint64_t WalletImpl::coldKeyImageSync(uint64_t &spent, uint64_t &unspent)
{
return m_wallet->cold_key_image_sync(spent, unspent);
}
+
+void WalletImpl::deviceShowAddress(uint32_t accountIndex, uint32_t addressIndex, const std::string &paymentId)
+{
+ boost::optional<crypto::hash8> payment_id_param = boost::none;
+ if (!paymentId.empty())
+ {
+ crypto::hash8 payment_id;
+ bool res = tools::wallet2::parse_short_payment_id(paymentId, payment_id);
+ if (!res)
+ {
+ throw runtime_error("Invalid payment ID");
+ }
+ payment_id_param = payment_id;
+ }
+
+ m_wallet->device_show_address(accountIndex, addressIndex, payment_id_param);
+}
} // namespace
namespace Bitmonero = Monero;
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 9e07b6e19..57265470c 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -201,6 +201,7 @@ public:
virtual bool unlockKeysFile() override;
virtual bool isKeysFileLocked() override;
virtual uint64_t coldKeyImageSync(uint64_t &spent, uint64_t &unspent) override;
+ virtual void deviceShowAddress(uint32_t accountIndex, uint32_t addressIndex, const std::string &paymentId) override;
private:
void clearStatus() const;
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 0af3b1867..7193eddd7 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -1003,6 +1003,9 @@ struct Wallet
//! cold-device protocol key image sync
virtual uint64_t coldKeyImageSync(uint64_t &spent, uint64_t &unspent) = 0;
+
+ //! shows address on device display
+ virtual void deviceShowAddress(uint32_t accountIndex, uint32_t addressIndex, const std::string &paymentId) = 0;
};
/**
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index c87947e39..8462c659d 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -10048,6 +10048,7 @@ void wallet2::cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_
setup_shim(&wallet_shim, this);
aux_data.tx_recipients = dsts_info;
aux_data.bp_version = use_fork_rules(HF_VERSION_SMALLER_BP, -10) ? 2 : 1;
+ aux_data.hard_fork = get_current_hard_fork();
dev_cold->tx_sign(&wallet_shim, txs, exported_txs, aux_data);
tx_device_aux = aux_data.tx_device_aux;
@@ -10075,6 +10076,35 @@ uint64_t wallet2::cold_key_image_sync(uint64_t &spent, uint64_t &unspent) {
return import_res;
}
//----------------------------------------------------------------------------------------------------
+void wallet2::device_show_address(uint32_t account_index, uint32_t address_index, const boost::optional<crypto::hash8> &payment_id)
+{
+ if (!key_on_device())
+ {
+ return;
+ }
+
+ auto & hwdev = get_account().get_device();
+ hwdev.display_address(subaddress_index{account_index, address_index}, payment_id);
+}
+//----------------------------------------------------------------------------------------------------
+uint8_t wallet2::get_current_hard_fork()
+{
+ if (m_offline)
+ return 0;
+
+ cryptonote::COMMAND_RPC_HARD_FORK_INFO::request req_t = AUTO_VAL_INIT(req_t);
+ cryptonote::COMMAND_RPC_HARD_FORK_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
+
+ m_daemon_rpc_mutex.lock();
+ req_t.version = 0;
+ bool r = net_utils::invoke_http_json_rpc("/json_rpc", "hard_fork_info", req_t, resp_t, m_http_client, rpc_timeout);
+ m_daemon_rpc_mutex.unlock();
+ THROW_WALLET_EXCEPTION_IF(!r, tools::error::no_connection_to_daemon, "hard_fork_info");
+ THROW_WALLET_EXCEPTION_IF(resp_t.status == CORE_RPC_STATUS_BUSY, tools::error::daemon_busy, "hard_fork_info");
+ THROW_WALLET_EXCEPTION_IF(resp_t.status != CORE_RPC_STATUS_OK, tools::error::wallet_generic_rpc_error, "hard_fork_info", m_trusted_daemon ? resp_t.status : "daemon error");
+ return resp_t.version;
+}
+//----------------------------------------------------------------------------------------------------
void wallet2::get_hard_fork_info(uint8_t version, uint64_t &earliest_height) const
{
boost::optional<std::string> result = m_node_rpc_proxy.get_earliest_height(version, earliest_height);
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 921c150cb..1ea10d333 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -843,6 +843,7 @@ private:
void cold_tx_aux_import(const std::vector<pending_tx>& ptx, const std::vector<std::string>& tx_device_aux);
void cold_sign_tx(const std::vector<pending_tx>& ptx_vector, signed_tx_set &exported_txs, std::vector<cryptonote::address_parse_info> &dsts_info, std::vector<std::string> & tx_device_aux);
uint64_t cold_key_image_sync(uint64_t &spent, uint64_t &unspent);
+ void device_show_address(uint32_t account_index, uint32_t address_index, const boost::optional<crypto::hash8> &payment_id);
bool parse_multisig_tx_from_str(std::string multisig_tx_st, multisig_tx_set &exported_txs) const;
bool load_multisig_tx(cryptonote::blobdata blob, multisig_tx_set &exported_txs, std::function<bool(const multisig_tx_set&)> accept_func = NULL);
bool load_multisig_tx_from_file(const std::string &filename, multisig_tx_set &exported_txs, std::function<bool(const multisig_tx_set&)> accept_func = NULL);
@@ -1094,6 +1095,7 @@ private:
size_t get_num_transfer_details() const { return m_transfers.size(); }
const transfer_details &get_transfer_details(size_t idx) const;
+ uint8_t get_current_hard_fork();
void get_hard_fork_info(uint8_t version, uint64_t &earliest_height) const;
bool use_fork_rules(uint8_t version, int64_t early_blocks = 0) const;
int get_fee_algorithm() const;