Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 136 additions & 41 deletions src/simplewallet/simplewallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#include "multisig/multisig.h"
#include "wallet/wallet_args.h"
#include "wallet/fee_priority.h"
#include "wallet/uri.hpp"
#include "version.h"
#include <stdexcept>
#include "wallet/message_store.h"
Expand Down Expand Up @@ -6479,15 +6480,18 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
{
std::string payment_id_str = local_args.back();
crypto::hash payment_id;
bool r = true;
if (tools::wallet2::parse_long_payment_id(payment_id_str, payment_id))
{
LONG_PAYMENT_ID_SUPPORT_CHECK();
}
if(!r)
{
fail_msg_writer() << tr("payment id failed to encode");
return false;
std::string extra_nonce;
set_payment_id_to_tx_extra_nonce(extra_nonce, payment_id);
if (!add_extra_nonce_to_tx_extra(extra, extra_nonce))
{
fail_msg_writer() << tr("failed to set up payment id");
return false;
}
payment_id_seen = true;
local_args.pop_back();
}
}

Expand All @@ -6514,6 +6518,7 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca

vector<cryptonote::address_parse_info> dsts_info;
vector<cryptonote::tx_destination_entry> dsts;
std::string tx_description;
for (size_t i = 0; i < local_args.size(); )
{
dsts_info.emplace_back();
Expand All @@ -6522,25 +6527,106 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
bool r = true;

// check for a URI
std::string address_uri, payment_id_uri, tx_description, recipient_name, error;
std::vector<std::string> unknown_parameters;
uint64_t amount = 0;
bool has_uri = m_wallet->parse_uri(local_args[i], address_uri, payment_id_uri, amount, tx_description, recipient_name, unknown_parameters, error);
std::string error;
std::vector<std::string> unknown_parameters, addresses, recipient_names;
std::vector<uint64_t> amounts;
bool has_uri = parse_uri(local_args[i], addresses, amounts, recipient_names, tx_description, unknown_parameters, error);
if (has_uri)
{
r = cryptonote::get_account_address_from_str_or_url(info, m_wallet->nettype(), address_uri, oa_prompter);
if (payment_id_uri.size() == 16)
std::string payment_id_uri;
for (auto &unknown_parameter : unknown_parameters)
{
if (!tools::wallet2::parse_short_payment_id(payment_id_uri, info.payment_id))
if (boost::starts_with(unknown_parameter, "tx_payment_id="))
{
fail_msg_writer() << tr("failed to parse short payment ID from URI");
payment_id_uri = unknown_parameter.substr(std::string("tx_payment_id=").size());
}
}

if (!payment_id_uri.empty() && addresses.size() > 1)
{
fail_msg_writer() << tr("a single transaction-level payment id (tx_payment_id) cannot be used with multiple outputs");
return false;
}

if (!payment_id_uri.empty())
{
if (payment_id_seen)
{
fail_msg_writer() << tr("a single transaction cannot use more than one payment id");
return false;
}
info.has_payment_id = true;

if (payment_id_uri.size() == 16)
{
crypto::hash8 short_pid;
if (!tools::wallet2::parse_short_payment_id(payment_id_uri, short_pid))
{
fail_msg_writer() << tr("failed to parse short payment ID from URI");
return false;
}
std::string extra_nonce;
set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, short_pid);
if (!add_extra_nonce_to_tx_extra(extra, extra_nonce))
{
fail_msg_writer() << tr("failed to set up payment id");
return false;
}
payment_id_seen = true;
}
else
{
crypto::hash long_pid;
if (!tools::wallet2::parse_long_payment_id(payment_id_uri, long_pid))
{
fail_msg_writer() << tr("failed to parse payment ID from URI");
return false;
}
LONG_PAYMENT_ID_SUPPORT_CHECK();
std::string extra_nonce;
set_payment_id_to_tx_extra_nonce(extra_nonce, long_pid);
if (!add_extra_nonce_to_tx_extra(extra, extra_nonce))
{
fail_msg_writer() << tr("failed to set up payment id");
return false;
}
payment_id_seen = true;
}
}
for (size_t j = 0; j < addresses.size(); ++j)
{
r = cryptonote::get_account_address_from_str_or_url(info, m_wallet->nettype(), addresses[j], oa_prompter);
if (!r)
{
fail_msg_writer() << tr("failed to parse address");
return false;
}

if (info.has_payment_id)
{
if (payment_id_seen)
{
fail_msg_writer() << tr("a single transaction cannot use more than one payment id");
return false;
}
std::string extra_nonce;
set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id);
if (!add_extra_nonce_to_tx_extra(extra, extra_nonce))
{
fail_msg_writer() << tr("failed to set up payment id");
return false;
}
payment_id_seen = true;
}

de.amount = amounts[j];
de.original = addresses[j];
de.addr = info.address;
de.is_subaddress = info.is_subaddress;
de.is_integrated = info.has_payment_id;
dsts.push_back(de);
}
de.amount = amount;
de.original = local_args[i];
++i;
continue;
}
else if (i + 1 < local_args.size())
{
Expand Down Expand Up @@ -6573,33 +6659,18 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
de.is_subaddress = info.is_subaddress;
de.is_integrated = info.has_payment_id;

if (info.has_payment_id || !payment_id_uri.empty())
if (info.has_payment_id)
{
if (payment_id_seen)
{
fail_msg_writer() << tr("a single transaction cannot use more than one payment id");
return false;
}

crypto::hash payment_id;
std::string extra_nonce;
if (info.has_payment_id)
{
set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id);
}
else if (tools::wallet2::parse_payment_id(payment_id_uri, payment_id))
{
LONG_PAYMENT_ID_SUPPORT_CHECK();
}
else
{
fail_msg_writer() << tr("failed to parse payment id, though it was detected");
return false;
}
bool r = add_extra_nonce_to_tx_extra(extra, extra_nonce);
if(!r)
set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id);
if (!add_extra_nonce_to_tx_extra(extra, extra_nonce))
{
fail_msg_writer() << tr("failed to set up payment id, though it was decoded correctly");
fail_msg_writer() << tr("failed to set up payment id");
return false;
}
payment_id_seen = true;
Expand All @@ -6617,6 +6688,11 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca

SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return false;);

if (payment_id_seen && dsts.size() > 1) {
fail_msg_writer() << tr("a single transaction-level payment id (tx_payment_id) cannot be used with multiple outputs");
return false;
}

try
{
// figure out what tx will be necessary
Expand Down Expand Up @@ -6747,6 +6823,7 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
}
}

auto backup_ptx_vector = ptx_vector;
// actually commit the transactions
const multisig::multisig_account_status ms_status{m_wallet->get_multisig_status()};
if (ms_status.multisig_is_active && called_by_mms)
Expand Down Expand Up @@ -6812,6 +6889,15 @@ bool simple_wallet::transfer_main(const std::vector<std::string> &args_, bool ca
{
commit_or_save(ptx_vector, m_do_not_relay);
}

if (!tx_description.empty())
{
for (const auto &ptx : backup_ptx_vector)
{
crypto::hash txid = get_transaction_hash(ptx.tx);
m_wallet->set_tx_note(txid, tx_description);
}
}
}
catch (const std::exception &e)
{
Expand Down Expand Up @@ -8699,12 +8785,21 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
std::string destinations = "-";
if (!transfer.outputs.empty())
{
destinations = "";
for (const auto& output : transfer.outputs)
if (transfer.outputs.size() == 1)
{
destinations = (transfer.direction == "in" ? transfer.outputs[0].first.substr(0, 6) : transfer.outputs[0].first);
}
else
{
if (!destinations.empty())
destinations += ", ";
destinations += (transfer.direction == "in" ? output.first.substr(0, 6) : output.first) + ":" + print_money(output.second);
destinations.clear();
for (const auto& output : transfer.outputs)
{
if (!destinations.empty())
{
destinations += ", ";
}
destinations += (transfer.direction == "in" ? output.first.substr(0, 6) : output.first) + ":" + print_money(output.second);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/wallet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ set(wallet_sources
node_rpc_proxy.cpp
message_store.cpp
message_transporter.cpp
uri.cpp
)

monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
Expand Down
Loading
Loading