2014-04-02 16:00:17 +00:00
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
# include "include_base_utils.h"
using namespace epee ;
# include "wallet_rpc_server.h"
# include "common/command_line.h"
# include "cryptonote_core/cryptonote_format_utils.h"
# include "cryptonote_core/account.h"
# include "misc_language.h"
2014-04-29 16:26:45 +00:00
# include "string_tools.h"
2014-04-02 16:00:17 +00:00
# include "crypto/hash.h"
namespace tools
{
//-----------------------------------------------------------------------------------
const command_line : : arg_descriptor < std : : string > wallet_rpc_server : : arg_rpc_bind_port = { " rpc-bind-port " , " Starts wallet as rpc server for wallet operations, sets bind port for server " , " " , true } ;
const command_line : : arg_descriptor < std : : string > wallet_rpc_server : : arg_rpc_bind_ip = { " rpc-bind-ip " , " Specify ip to bind rpc server " , " 127.0.0.1 " } ;
void wallet_rpc_server : : init_options ( boost : : program_options : : options_description & desc )
{
command_line : : add_arg ( desc , arg_rpc_bind_ip ) ;
command_line : : add_arg ( desc , arg_rpc_bind_port ) ;
}
//------------------------------------------------------------------------------------------------------------------------------
wallet_rpc_server : : wallet_rpc_server ( wallet2 & w ) : m_wallet ( w )
{ }
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server : : run ( )
{
m_net_server . add_idle_handler ( [ this ] ( ) {
m_wallet . refresh ( ) ;
return true ;
} , 20000 ) ;
//DO NOT START THIS SERVER IN MORE THEN 1 THREADS WITHOUT REFACTORING
return epee : : http_server_impl_base < wallet_rpc_server , connection_context > : : run ( 1 , true ) ;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server : : handle_command_line ( const boost : : program_options : : variables_map & vm )
{
m_bind_ip = command_line : : get_arg ( vm , arg_rpc_bind_ip ) ;
m_port = command_line : : get_arg ( vm , arg_rpc_bind_port ) ;
return true ;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server : : init ( const boost : : program_options : : variables_map & vm )
{
m_net_server . set_threads_prefix ( " RPC " ) ;
bool r = handle_command_line ( vm ) ;
CHECK_AND_ASSERT_MES ( r , false , " Failed to process command line in core_rpc_server " ) ;
return epee : : http_server_impl_base < wallet_rpc_server , connection_context > : : init ( m_port , m_bind_ip ) ;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server : : on_getbalance ( const wallet_rpc : : COMMAND_RPC_GET_BALANCE : : request & req , wallet_rpc : : COMMAND_RPC_GET_BALANCE : : response & res , epee : : json_rpc : : error & er , connection_context & cntx )
{
try
{
res . balance = m_wallet . balance ( ) ;
res . unlocked_balance = m_wallet . unlocked_balance ( ) ;
}
catch ( std : : exception & e )
{
er . code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR ;
er . message = e . what ( ) ;
return false ;
}
return true ;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server : : on_transfer ( const wallet_rpc : : COMMAND_RPC_TRANSFER : : request & req , wallet_rpc : : COMMAND_RPC_TRANSFER : : response & res , epee : : json_rpc : : error & er , connection_context & cntx )
{
std : : vector < cryptonote : : tx_destination_entry > dsts ;
2014-04-29 16:26:45 +00:00
for ( auto it = req . destinations . begin ( ) ; it ! = req . destinations . end ( ) ; it + + )
2014-04-02 16:00:17 +00:00
{
cryptonote : : tx_destination_entry de ;
if ( ! get_account_address_from_str ( de . addr , it - > address ) )
{
er . code = WALLET_RPC_ERROR_CODE_WRONG_ADDRESS ;
er . message = std : : string ( " WALLET_RPC_ERROR_CODE_WRONG_ADDRESS: " ) + it - > address ;
return false ;
}
de . amount = it - > amount ;
dsts . push_back ( de ) ;
}
try
{
cryptonote : : transaction tx ;
2014-04-29 16:26:45 +00:00
m_wallet . transfer ( dsts , req . mixin , req . unlock_time , req . fee , std : : vector < uint8_t > ( ) , tx ) ;
2014-04-02 16:00:17 +00:00
res . tx_hash = boost : : lexical_cast < std : : string > ( cryptonote : : get_transaction_hash ( tx ) ) ;
return true ;
}
catch ( const tools : : error : : daemon_busy & e )
{
er . code = WALLET_RPC_ERROR_CODE_DAEMON_IS_BUSY ;
er . message = e . what ( ) ;
2014-04-29 16:26:45 +00:00
return false ;
2014-04-02 16:00:17 +00:00
}
catch ( const std : : exception & e )
{
er . code = WALLET_RPC_ERROR_CODE_GENERIC_TRANSFER_ERROR ;
er . message = e . what ( ) ;
2014-04-29 16:26:45 +00:00
return false ;
2014-04-02 16:00:17 +00:00
}
catch ( . . . )
{
er . code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR ;
er . message = " WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR " ;
2014-04-29 16:26:45 +00:00
return false ;
2014-04-02 16:00:17 +00:00
}
return true ;
}
//------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server : : on_store ( const wallet_rpc : : COMMAND_RPC_STORE : : request & req , wallet_rpc : : COMMAND_RPC_STORE : : response & res , epee : : json_rpc : : error & er , connection_context & cntx )
{
try
{
m_wallet . store ( ) ;
}
catch ( std : : exception & e )
{
er . code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR ;
er . message = e . what ( ) ;
return false ;
}
return true ;
}
//------------------------------------------------------------------------------------------------------------------------------
2014-04-29 16:26:45 +00:00
bool wallet_rpc_server : : on_get_payments ( const wallet_rpc : : COMMAND_RPC_GET_PAYMENTS : : request & req , wallet_rpc : : COMMAND_RPC_GET_PAYMENTS : : response & res , epee : : json_rpc : : error & er , connection_context & cntx )
{
crypto : : hash payment_id ;
cryptonote : : blobdata payment_id_blob ;
if ( ! epee : : string_tools : : parse_hexstr_to_binbuff ( req . payment_id , payment_id_blob ) )
{
er . code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID ;
er . message = " Payment ID has invald format " ;
return false ;
}
if ( sizeof ( payment_id ) ! = payment_id_blob . size ( ) )
{
er . code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID ;
er . message = " Payment ID has invalid size " ;
return false ;
}
payment_id = * reinterpret_cast < const crypto : : hash * > ( payment_id_blob . data ( ) ) ;
res . payments . clear ( ) ;
std : : list < wallet2 : : payment_details > payment_list ;
m_wallet . get_payments ( payment_id , payment_list ) ;
for ( auto payment : payment_list )
{
wallet_rpc : : payment_details rpc_payment ;
rpc_payment . tx_hash = epee : : string_tools : : pod_to_hex ( payment . m_tx_hash ) ;
rpc_payment . amount = payment . m_amount ;
rpc_payment . block_height = payment . m_block_height ;
rpc_payment . unlock_time = payment . m_unlock_time ;
res . payments . push_back ( rpc_payment ) ;
}
return true ;
}
//------------------------------------------------------------------------------------------------------------------------------
}