From 9447de6c963bdc6c08e68938ebb304823bb00482 Mon Sep 17 00:00:00 2001 From: cryptozoidberg Date: Wed, 25 Aug 2021 20:39:33 +0200 Subject: [PATCH] added proper handling of wrpa transactions in simplewallet --- src/common/general_purpose_commands_defs.h | 40 ++++++++++++ src/simplewallet/simplewallet.cpp | 74 +++++++++++++++++++--- src/simplewallet/simplewallet.h | 1 + 3 files changed, 105 insertions(+), 10 deletions(-) create mode 100644 src/common/general_purpose_commands_defs.h diff --git a/src/common/general_purpose_commands_defs.h b/src/common/general_purpose_commands_defs.h new file mode 100644 index 00000000..f9da9968 --- /dev/null +++ b/src/common/general_purpose_commands_defs.h @@ -0,0 +1,40 @@ +// Copyright (c) 2014-2018 Zano Project +// Distributed under the MIT/X11 software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#pragma once +#include "serialization/keyvalue_hexemizer.h" +#include "currency_core/currency_basic.h" +#include "storages/portable_storage_base.h" +#include "currency_core/basic_api_response_codes.h" +#include "common/error_codes.h" +namespace currency +{ + //----------------------------------------------- + + + struct tx_cost_struct + { + std::string usd_needed_for_erc20; + std::string zano_needed_for_erc20; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(usd_needed_for_erc20) + KV_SERIALIZE(zano_needed_for_erc20) + END_KV_SERIALIZE_MAP() + }; + + struct rpc_get_wrap_info_response + { + std::string unwraped_coins_left; + tx_cost_struct tx_cost; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(unwraped_coins_left) + KV_SERIALIZE(tx_cost) + END_KV_SERIALIZE_MAP() + }; + + +} + diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index c72242d3..5ca38d56 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -21,7 +21,7 @@ #include "version.h" #include "string_coding.h" #include "wallet/wrap_service.h" - +#include "common/general_purpose_commands_defs.h" #include #if defined(WIN32) @@ -1176,6 +1176,52 @@ bool simple_wallet::show_wallet_bcheight(const std::vector& args) return true; } //---------------------------------------------------------------------------------------------------- +bool simple_wallet::validate_wrap_status(uint64_t amount) +{ + //check if amount is fit erc20 fees and amount left in circulation + epee::net_utils::http::http_simple_client http_client; + + currency::void_struct req = AUTO_VAL_INIT(req); + currency::rpc_get_wrap_info_response res = AUTO_VAL_INIT(res); + bool r = epee::net_utils::invoke_http_json_remote_command2("http://wrapped.zano.org/api/get_wrap_info", req, res, http_client, 10000); + if (!r) + { + fail_msg_writer() << "Failed to request wrap status from server, check internet connection"; + return false; + } + //check if amount is bigger then erc20 fee + uint64_t zano_needed_for_wrap = std::stoll(res.tx_cost.zano_needed_for_erc20); + if (amount <= zano_needed_for_wrap) + { + fail_msg_writer() << "Too small amount to cover ERC20 fee. ERC20 cost is: " + << print_money(zano_needed_for_wrap) << " Zano" << + "($" << res.tx_cost.usd_needed_for_erc20 << ")"; + return false; + } + uint64_t unwrapped_coins_left = std::stoll(res.unwraped_coins_left); + if (amount > unwrapped_coins_left) + { + fail_msg_writer() << "Amount is bigger than ERC20 tokens left available: " + << print_money(unwrapped_coins_left) << " wZano"; + return false; + } + + success_msg_writer(false) << "You'll receive estimate " << print_money(amount - zano_needed_for_wrap) << " wZano (" << print_money(zano_needed_for_wrap)<< " Zano will be used to cover ERC20 fee)"; + success_msg_writer(false) << "Proceed? (yes/no)"; + while (true) + { + std::string user_response; + std::getline(std::cin, user_response); + if (user_response == "yes" || user_response == "y") + return true; + else if (user_response == "no" || user_response == "n") + return false; + else { + success_msg_writer(false) << "Wrong response, can be \"yes\" or \"no\""; + } + } +} +//---------------------------------------------------------------------------------------------------- bool simple_wallet::transfer(const std::vector &args_) { if (!try_connect_to_daemon()) @@ -1223,10 +1269,26 @@ bool simple_wallet::transfer(const std::vector &args_) std::string integrated_payment_id; currency::tx_destination_entry de; de.addr.resize(1); + + bool ok = currency::parse_amount(de.amount, local_args[i + 1]); + if (!ok || 0 == de.amount) + { + fail_msg_writer() << "amount is wrong: " << local_args[i] << ' ' << local_args[i + 1] << + ", expected number from 0 to " << print_money(std::numeric_limits::max()); + return true; + } + //check if address looks like wrapped address if (is_address_like_wrapped(local_args[i])) { - success_msg_writer(true) << "Address " << local_args[i] << " recognized as wrapped address, creating wrapping transaction..."; + + success_msg_writer(false) << "Address " << local_args[i] << " recognized as wrapped address, creating wrapping transaction."; + success_msg_writer(false) << "This transaction will create wZano (\"Wrapped Zano\") which will be sent to the specified address on the Ethereum network."; + + if (!validate_wrap_status(de.amount)) + { + return true; + } //put into service attachment specially encrypted entry which will contain wrap address and network tx_service_attachment sa = AUTO_VAL_INIT(sa); sa.service_id = BC_WRAP_SERVICE_ID; @@ -1252,14 +1314,6 @@ bool simple_wallet::transfer(const std::vector &args_) return true; } - bool ok = currency::parse_amount(de.amount, local_args[i + 1]); - if(!ok || 0 == de.amount) - { - fail_msg_writer() << "amount is wrong: " << local_args[i] << ' ' << local_args[i + 1] << - ", expected number from 0 to " << print_money(std::numeric_limits::max()); - return true; - } - if (integrated_payment_id.size() != 0) { if (payment_id.size() != 0) diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 156da7c8..35f99128 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -86,6 +86,7 @@ namespace currency bool sign_transfer(const std::vector &args); bool submit_transfer(const std::vector &args); bool sweep_below(const std::vector &args); + bool validate_wrap_status(uint64_t amount); bool get_alias_from_daemon(const std::string& alias_name, currency::extra_alias_entry_base& ai); bool get_transfer_address(const std::string& adr_str, currency::account_public_address& addr);