//
// monero_send_routine.hpp
// Copyright (c) 2014-2019, MyMonero.com
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//
# ifndef monero_send_routine_hpp
# define monero_send_routine_hpp
//
# include <boost/optional.hpp>
# include <boost/property_tree/ptree.hpp>
# include <boost/property_tree/json_parser.hpp>
//
# include "string_tools.h"
# include "crypto.h"
# include "cryptonote_basic.h"
# include "cryptonote_format_utils.h"
//
using namespace tools ;
# include "tools__ret_vals.hpp"
//
# include "monero_transfer_utils.hpp"
//
namespace monero_send_routine
{
using namespace std ;
using namespace boost ;
using namespace cryptonote ;
using namespace monero_transfer_utils ;
using namespace crypto ;
//
// Abstracted Send routine
// - Accessory types - Callbacks - Data fetch hooks
typedef std : : function < void (
const property_tree : : ptree & // opted not to send str but already parsed structure - this may not be optimal but makes it so that e.g. emscr_async_bridge doesn't have to send the response as an escaped JSON string nor redundantly parse/stringify
) > api_fetch_cb_fn ;
//
struct LightwalletAPI_Req_GetUnspentOuts
{ // strings are NOT references, so they get copied, allowing scope of struct init not to be an issue
const string address ;
const string view_key ;
const string amount ; // "0" uint64_string
size_t mixin ;
bool use_dust ; // true; send-funds is now coded to filter unmixable and below threshold dust properly when sweeping and not sweeping
const string dust_threshold ; // uint64_string; String(MoneroConstants.dustThreshold, radix: 10)
} ;
static inline string json_string_from_req_GetUnspentOuts ( const LightwalletAPI_Req_GetUnspentOuts & req_params )
{
boost : : property_tree : : ptree req_params_root ;
req_params_root . put ( " address " , req_params . address ) ;
req_params_root . put ( " view_key " , req_params . view_key ) ;
req_params_root . put ( " amount " , req_params . amount ) ;
req_params_root . put ( " dust_threshold " , req_params . dust_threshold ) ;
req_params_root . put ( " use_dust " , req_params . use_dust ) ;
req_params_root . put ( " mixin " , req_params . mixin ) ;
stringstream req_params_ss ;
boost : : property_tree : : write_json ( req_params_ss , req_params_root , false /*pretty*/ ) ;
//
return req_params_ss . str ( ) ;
}
LightwalletAPI_Req_GetUnspentOuts new__req_params__get_unspent_outs ( // used internally and by emscr async send impl
string from_address_string ,
string sec_viewKey_string
) ;
typedef std : : function < void (
LightwalletAPI_Req_GetUnspentOuts , // req_params - use these for making the request
api_fetch_cb_fn // fn cb … call this after the request responds (successfully)
) > send__get_unspent_outs_fn_type ;
//
struct LightwalletAPI_Req_GetRandomOuts
{
const vector < string > amounts ;
const size_t count ; // =mixin+1
} ;
static inline string json_string_from_req_GetRandomOuts ( const LightwalletAPI_Req_GetRandomOuts & req_params )
{
boost : : property_tree : : ptree req_params_root ;
boost : : property_tree : : ptree amounts_ptree ;
BOOST_FOREACH ( const string & amount_string , req_params . amounts )
{
property_tree : : ptree amount_child ;
amount_child . put ( " " , amount_string ) ;
amounts_ptree . push_back ( std : : make_pair ( " " , amount_child ) ) ;
}
req_params_root . add_child ( " amounts " , amounts_ptree ) ;
req_params_root . put ( " count " , req_params . count ) ;
stringstream req_params_ss ;
boost : : property_tree : : write_json ( req_params_ss , req_params_root , false /*pretty*/ ) ;
return req_params_ss . str ( ) ;
}
LightwalletAPI_Req_GetRandomOuts new__req_params__get_random_outs ( // used internally and by emscr async send impl
vector < SpendableOutput > & step1__using_outs
) ;
typedef std : : function < void (
LightwalletAPI_Req_GetRandomOuts , // req_params - use these for making the request
api_fetch_cb_fn // fn cb … call this after the request responds (successfully)
) > send__get_random_outs_fn_type ;
//
struct LightwalletAPI_Req_SubmitRawTx
{ // strings are NOT references, so they get copied, allowing scope of struct init not to be an issue
const string address ;
const string view_key ;
const string tx ; // serialized tx
} ;
static inline string json_string_from_req_SubmitRawTx ( const LightwalletAPI_Req_SubmitRawTx & req_params )
{
boost : : property_tree : : ptree req_params_root ;
boost : : property_tree : : ptree amounts_ptree ;
req_params_root . put ( " address " , std : : move ( req_params . address ) ) ;
req_params_root . put ( " view_key " , std : : move ( req_params . view_key ) ) ;
req_params_root . put ( " tx " , std : : move ( req_params . tx ) ) ;
stringstream req_params_ss ;
boost : : property_tree : : write_json ( req_params_ss , req_params_root , false /*pretty*/ ) ;
//
return req_params_ss . str ( ) ;
}
typedef std : : function < void (
LightwalletAPI_Req_SubmitRawTx , // req_params - use these for making the request
api_fetch_cb_fn // fn cb … call this after the request responds (successfully)
) > send__submit_raw_tx_fn_type ;
//
// - Accessory types - Callbacks - Updates
enum SendFunds_ProcessStep
{ // These codes have values for serialization
fetchingLatestBalance = 1 ,
calculatingFee = 2 ,
fetchingDecoyOutputs = 3 ,
constructingTransaction = 4 ,
submittingTransaction = 5
} ;
typedef std : : function < void ( SendFunds_ProcessStep code ) > send__status_update_fn_type ;
static inline string err_msg_from_err_code__send_funds_step ( SendFunds_ProcessStep code )
{
switch ( code ) {
case fetchingLatestBalance :
return " Fetching latest balance. " ;
case calculatingFee :
return " Calculating fee. " ;
case fetchingDecoyOutputs :
return " Fetching decoy outputs. " ;
case constructingTransaction :
return " Constructing transaction. " ; // which may go back to .calculatingFee
case submittingTransaction :
return " Submitted transaction. " ;
}
}
// - Accessory types - Callbacks - Routine completions
struct SendFunds_Error_RetVals
{
optional < string > explicit_errMsg ;
optional < CreateTransactionErrorCode > errCode ; // if != noError, abort Send process
// for display / information purposes on errCode=needMoreMoneyThanFound during step1:
uint64_t spendable_balance ; // (effectively but not the same as spendable_balance)
uint64_t required_balance ; // for display / information purposes on errCode=needMoreMoneyThanFound during step1
} ;
typedef std : : function < void ( const SendFunds_Error_RetVals & ) > send__error_cb_fn_type ;
//
struct SendFunds_Success_RetVals
{
uint64_t used_fee ;
uint64_t total_sent ; // final_total_wo_fee + final_fee
size_t mixin ;
optional < string > final_payment_id ; // will be filled if a payment id was passed in or an integrated address was used
string signed_serialized_tx_string ;
string tx_hash_string ;
string tx_key_string ; // this includes additional_tx_keys
string tx_pub_key_string ; // from get_tx_pub_key_from_extra()
} ;
typedef std : : function < void ( const SendFunds_Success_RetVals & ) > send__success_cb_fn_type ;
//
// Response parsing
struct LightwalletAPI_Res_GetUnspentOuts
{
optional < string > err_msg ;
// OR
optional < uint64_t > per_byte_fee ;
optional < uint64_t > fee_mask ;
optional < vector < SpendableOutput > > unspent_outs ;
uint8_t fork_version ;
} ;
struct LightwalletAPI_Res_GetRandomOuts
{
optional < string > err_msg ;
// OR
optional < vector < RandomAmountOutputs > > mix_outs ;
} ;
LightwalletAPI_Res_GetUnspentOuts new__parsed_res__get_unspent_outs (
const property_tree : : ptree & res ,
const secret_key & sec_viewKey ,
const secret_key & sec_spendKey ,
const public_key & pub_spendKey
) ;
LightwalletAPI_Res_GetRandomOuts new__parsed_res__get_random_outs (
const property_tree : : ptree & res
) ;
//
// - Routine entrypoint
struct Async_SendFunds_Args
{ // TODO: add a way to pass native structures if available
string from_address_string ;
string sec_viewKey_string ;
string sec_spendKey_string ;
string pub_spendKey_string ;
string to_address_string ;
optional < string > payment_id_string ;
uint64_t sending_amount ;
bool is_sweeping ;
uint32_t simple_priority ;
send__get_unspent_outs_fn_type get_unspent_outs_fn ;
send__get_random_outs_fn_type get_random_outs_fn ;
send__submit_raw_tx_fn_type submit_raw_tx_fn ;
send__status_update_fn_type status_update_fn ;
send__error_cb_fn_type error_cb_fn ;
send__success_cb_fn_type success_cb_fn ;
//
optional < uint64_t > unlock_time ; // default 0
optional < cryptonote : : network_type > nettype ;
} ;
void async__send_funds ( Async_SendFunds_Args args ) ;
}
# endif /* monero_send_routine_hpp */