2017-12-14 15:33:10 +01:00
/*
This file is part of TALER
2021-08-05 21:23:29 +02:00
Copyright ( C ) 2017 - 2021 Taler Systems SA
2017-12-14 15:33:10 +01:00
TALER is free software ; you can redistribute it and / or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation ; either version 3 , or ( at your option ) any later version .
TALER is distributed in the hope that it will be useful , but WITHOUT ANY
WARRANTY ; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE . See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License along with
TALER ; see the file COPYING . If not , see < http : //www.gnu.org/licenses/>
*/
/**
2021-08-03 12:08:28 +02:00
* @ file taler - exchange - wire - gateway - client . c
2017-12-14 15:33:10 +01:00
* @ brief Execute wire transfer .
* @ author Christian Grothoff
*/
# include "platform.h"
# include <gnunet/gnunet_util_lib.h>
# include <gnunet/gnunet_json_lib.h>
# include <jansson.h>
# include "taler_bank_service.h"
2020-03-07 12:23:32 +01:00
/**
* If set to # GNUNET_YES , then we ' ll ask the bank for a list
* of incoming transactions from the account .
*/
static int incoming_history ;
/**
* If set to # GNUNET_YES , then we ' ll ask the bank for a list
* of outgoing transactions from the account .
*/
static int outgoing_history ;
2017-12-14 15:33:10 +01:00
/**
* Amount to transfer .
*/
static struct TALER_Amount amount ;
/**
2020-01-11 15:19:56 +01:00
* Credit account payto : //-URI.
2017-12-14 15:33:10 +01:00
*/
2020-01-11 15:19:56 +01:00
static char * credit_account ;
2017-12-14 15:33:10 +01:00
2020-03-07 12:23:32 +01:00
/**
* Debit account payto : //-URI.
*/
static char * debit_account ;
2017-12-14 15:33:10 +01:00
/**
* Wire transfer subject .
*/
static char * subject ;
2020-03-07 12:23:32 +01:00
/**
* Which config section has the credentials to access the bank .
*/
static char * account_section ;
/**
* Starting row .
*/
2021-08-07 17:50:53 +02:00
static unsigned long long start_row = UINT64_MAX ;
2020-03-07 12:23:32 +01:00
2017-12-14 15:33:10 +01:00
/**
2020-01-18 23:28:01 +01:00
* Authentication data .
2017-12-14 15:33:10 +01:00
*/
2020-03-07 12:23:32 +01:00
static struct TALER_BANK_AuthenticationData auth ;
2017-12-14 15:33:10 +01:00
/**
* Return value from main ( ) .
*/
2020-03-07 12:23:32 +01:00
static int global_ret = 1 ;
2017-12-14 15:33:10 +01:00
/**
* Main execution context for the main loop .
*/
static struct GNUNET_CURL_Context * ctx ;
2020-03-07 12:23:32 +01:00
/**
* Handle to ongoing credit history operation .
*/
static struct TALER_BANK_CreditHistoryHandle * chh ;
/**
* Handle to ongoing debit history operation .
*/
static struct TALER_BANK_DebitHistoryHandle * dhh ;
/**
* Handle for executing the wire transfer .
*/
static struct TALER_BANK_TransferHandle * eh ;
2017-12-14 15:33:10 +01:00
/**
* Handle to access the exchange .
*/
static struct TALER_BANK_AdminAddIncomingHandle * op ;
/**
* Context for running the CURL event loop .
*/
static struct GNUNET_CURL_RescheduleContext * rc ;
/**
* Function run when the test terminates ( good or bad ) .
* Cleans up our state .
*
* @ param cls NULL
*/
static void
do_shutdown ( void * cls )
{
2019-09-05 11:23:24 +02:00
( void ) cls ;
2017-12-14 15:33:10 +01:00
if ( NULL ! = op )
{
TALER_BANK_admin_add_incoming_cancel ( op ) ;
op = NULL ;
}
2020-03-07 12:23:32 +01:00
if ( NULL ! = chh )
{
TALER_BANK_credit_history_cancel ( chh ) ;
chh = NULL ;
}
if ( NULL ! = dhh )
{
TALER_BANK_debit_history_cancel ( dhh ) ;
dhh = NULL ;
}
if ( NULL ! = eh )
{
TALER_BANK_transfer_cancel ( eh ) ;
eh = NULL ;
}
2017-12-14 15:33:10 +01:00
if ( NULL ! = ctx )
{
GNUNET_CURL_fini ( ctx ) ;
ctx = NULL ;
}
if ( NULL ! = rc )
{
GNUNET_CURL_gnunet_rc_destroy ( rc ) ;
rc = NULL ;
}
2020-03-07 12:23:32 +01:00
TALER_BANK_auth_free ( & auth ) ;
}
/**
* Callback used to process ONE entry in the transaction
* history returned by the bank .
*
* @ param cls closure
* @ param http_status HTTP status code from server
* @ param ec taler error code
* @ param serial_id identification of the position at
* which we are returning data
* @ param details details about the wire transfer
* @ param json original full response from server
* @ return # GNUNET_OK to continue , # GNUNET_SYSERR to
* abort iteration
*/
2021-08-07 17:50:53 +02:00
static enum GNUNET_GenericReturnValue
2020-03-07 12:23:32 +01:00
credit_history_cb ( void * cls ,
unsigned int http_status ,
enum TALER_ErrorCode ec ,
uint64_t serial_id ,
const struct TALER_BANK_CreditDetails * details ,
const json_t * json )
{
( void ) cls ;
2021-08-03 14:31:31 +02:00
chh = NULL ;
2020-03-07 12:23:32 +01:00
if ( MHD_HTTP_OK ! = http_status )
{
if ( ( MHD_HTTP_NO_CONTENT ! = http_status ) | |
2021-11-19 11:47:52 +01:00
( TALER_EC_NONE ! = ec ) )
2020-03-07 12:23:32 +01:00
{
2021-08-03 14:08:45 +02:00
if ( 0 = = http_status )
{
fprintf ( stderr ,
" Failed to obtain HTTP reply from `%s' \n " ,
auth . wire_gateway_url ) ;
}
else
{
fprintf ( stderr ,
" Failed to obtain credit history from `%s': HTTP status %u (%s) \n " ,
auth . wire_gateway_url ,
http_status ,
TALER_ErrorCode_get_hint ( ec ) ) ;
}
2020-03-07 12:23:32 +01:00
if ( NULL ! = json )
json_dumpf ( json ,
stderr ,
JSON_INDENT ( 2 ) ) ;
global_ret = 2 ;
GNUNET_SCHEDULER_shutdown ( ) ;
return GNUNET_NO ;
}
fprintf ( stdout ,
" End of transactions list. \n " ) ;
global_ret = 0 ;
GNUNET_SCHEDULER_shutdown ( ) ;
return GNUNET_NO ;
}
/* If credit/debit accounts were specified, use as a filter */
if ( ( NULL ! = credit_account ) & &
( 0 ! = strcasecmp ( credit_account ,
2021-08-12 13:13:42 +02:00
details - > credit_account_uri ) ) )
2020-03-07 12:23:32 +01:00
return GNUNET_OK ;
if ( ( NULL ! = debit_account ) & &
( 0 ! = strcasecmp ( debit_account ,
2021-08-12 13:13:42 +02:00
details - > debit_account_uri ) ) )
2020-03-07 12:23:32 +01:00
return GNUNET_OK ;
fprintf ( stdout ,
" %llu: %s->%s (%s) over %s at %s \n " ,
( unsigned long long ) serial_id ,
2021-08-12 13:13:42 +02:00
details - > debit_account_uri ,
details - > credit_account_uri ,
2020-03-07 12:23:32 +01:00
TALER_B2S ( & details - > reserve_pub ) ,
TALER_amount2s ( & details - > amount ) ,
GNUNET_STRINGS_absolute_time_to_string ( details - > execution_date ) ) ;
return GNUNET_OK ;
}
/**
* Ask the bank the list of transactions for the bank account
* mentioned in the config section given by the user .
*/
static void
2021-01-07 20:52:11 +01:00
execute_credit_history ( void )
2020-03-07 12:23:32 +01:00
{
if ( NULL ! = subject )
{
fprintf ( stderr ,
" Specifying subject is not supported when inspecting credit history \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
chh = TALER_BANK_credit_history ( ctx ,
& auth ,
start_row ,
- 10 ,
2021-08-12 13:13:42 +02:00
GNUNET_TIME_UNIT_ZERO ,
2020-03-07 12:23:32 +01:00
& credit_history_cb ,
NULL ) ;
if ( NULL = = chh )
{
fprintf ( stderr ,
" Could not request the credit transaction history. \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
}
/**
* Function with the debit debit transaction history .
*
* @ param cls closure
* @ param http_status HTTP response code , # MHD_HTTP_OK ( 200 ) for successful status request
* 0 if the bank ' s reply is bogus ( fails to follow the protocol ) ,
* # MHD_HTTP_NO_CONTENT if there are no more results ; on success the
* last callback is always of this status ( even if ` abs ( num_results ) ` were
* already returned ) .
* @ param ec detailed error code
* @ param serial_id monotonically increasing counter corresponding to the transaction
* @ param details details about the wire transfer
* @ param json detailed response from the HTTPD , or NULL if reply was not in JSON
* @ return # GNUNET_OK to continue , # GNUNET_SYSERR to abort iteration
*/
2021-08-07 17:50:53 +02:00
static enum GNUNET_GenericReturnValue
2020-03-07 12:23:32 +01:00
debit_history_cb ( void * cls ,
unsigned int http_status ,
enum TALER_ErrorCode ec ,
uint64_t serial_id ,
const struct TALER_BANK_DebitDetails * details ,
const json_t * json )
{
( void ) cls ;
2021-08-03 14:08:45 +02:00
dhh = NULL ;
2020-03-07 12:23:32 +01:00
if ( MHD_HTTP_OK ! = http_status )
{
if ( ( MHD_HTTP_NO_CONTENT ! = http_status ) | |
2021-11-19 11:47:52 +01:00
( TALER_EC_NONE ! = ec ) )
2020-03-07 12:23:32 +01:00
{
2021-08-03 14:08:45 +02:00
if ( 0 = = http_status )
{
fprintf ( stderr ,
" Failed to obtain HTTP reply from `%s' \n " ,
auth . wire_gateway_url ) ;
}
else
{
fprintf ( stderr ,
" Failed to obtain debit history from `%s': HTTP status %u (%s) \n " ,
auth . wire_gateway_url ,
http_status ,
TALER_ErrorCode_get_hint ( ec ) ) ;
}
2020-03-07 12:23:32 +01:00
if ( NULL ! = json )
json_dumpf ( json ,
stderr ,
JSON_INDENT ( 2 ) ) ;
global_ret = 2 ;
GNUNET_SCHEDULER_shutdown ( ) ;
return GNUNET_NO ;
}
fprintf ( stdout ,
" End of transactions list. \n " ) ;
global_ret = 0 ;
GNUNET_SCHEDULER_shutdown ( ) ;
return GNUNET_NO ;
}
/* If credit/debit accounts were specified, use as a filter */
if ( ( NULL ! = credit_account ) & &
( 0 ! = strcasecmp ( credit_account ,
2021-08-12 13:13:42 +02:00
details - > credit_account_uri ) ) )
2020-03-07 12:23:32 +01:00
return GNUNET_OK ;
if ( ( NULL ! = debit_account ) & &
( 0 ! = strcasecmp ( debit_account ,
2021-08-12 13:13:42 +02:00
details - > debit_account_uri ) ) )
2020-03-07 12:23:32 +01:00
return GNUNET_OK ;
fprintf ( stdout ,
" %llu: %s->%s (%s) over %s at %s \n " ,
( unsigned long long ) serial_id ,
2021-08-12 13:13:42 +02:00
details - > debit_account_uri ,
details - > credit_account_uri ,
2020-03-07 12:23:32 +01:00
TALER_B2S ( & details - > wtid ) ,
TALER_amount2s ( & details - > amount ) ,
GNUNET_STRINGS_absolute_time_to_string ( details - > execution_date ) ) ;
return GNUNET_OK ;
}
/**
* Ask the bank the list of transactions for the bank account
* mentioned in the config section given by the user .
*/
static void
2021-01-07 20:52:11 +01:00
execute_debit_history ( void )
2020-03-07 12:23:32 +01:00
{
if ( NULL ! = subject )
{
fprintf ( stderr ,
" Specifying subject is not supported when inspecting debit history \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
dhh = TALER_BANK_debit_history ( ctx ,
& auth ,
start_row ,
- 10 ,
2021-08-12 13:13:42 +02:00
GNUNET_TIME_UNIT_ZERO ,
2020-03-07 12:23:32 +01:00
& debit_history_cb ,
NULL ) ;
if ( NULL = = dhh )
{
fprintf ( stderr ,
" Could not request the debit transaction history. \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
}
/**
* Callback that processes the outcome of a wire transfer
* execution .
*
* @ param cls closure
* @ param response_code HTTP status code
* @ param ec taler error code
* @ param row_id unique ID of the wire transfer in the bank ' s records
* @ param timestamp when did the transaction go into effect
*/
static void
confirmation_cb ( void * cls ,
unsigned int response_code ,
enum TALER_ErrorCode ec ,
uint64_t row_id ,
struct GNUNET_TIME_Absolute timestamp )
{
( void ) cls ;
2020-07-27 14:14:04 +02:00
eh = NULL ;
2020-03-07 12:23:32 +01:00
if ( MHD_HTTP_OK ! = response_code )
{
fprintf ( stderr ,
" The wire transfer didn't execute correctly (%u/%d). \n " ,
response_code ,
ec ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
fprintf ( stdout ,
" Wire transfer #%llu executed successfully at %s. \n " ,
( unsigned long long ) row_id ,
GNUNET_STRINGS_absolute_time_to_string ( timestamp ) ) ;
global_ret = 0 ;
GNUNET_SCHEDULER_shutdown ( ) ;
}
/**
* Ask the bank to execute a wire transfer .
*/
static void
2021-01-07 20:52:11 +01:00
execute_wire_transfer ( void )
2020-03-07 12:23:32 +01:00
{
struct TALER_WireTransferIdentifierRawP wtid ;
void * buf ;
size_t buf_size ;
2020-07-27 22:25:05 +02:00
char * params ;
2020-03-07 12:23:32 +01:00
if ( NULL ! = debit_account )
{
fprintf ( stderr ,
" Invalid option -C specified, conflicts with -D \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
2020-07-27 12:57:47 +02:00
2021-08-07 17:50:53 +02:00
/* See if subject was given as a payto-parameter. */
2020-07-27 12:57:47 +02:00
if ( NULL = = subject )
subject = TALER_payto_get_subject ( credit_account ) ;
2020-03-07 12:23:32 +01:00
if ( NULL ! = subject )
{
if ( GNUNET_OK ! =
GNUNET_STRINGS_string_to_data ( subject ,
strlen ( subject ) ,
& wtid ,
sizeof ( wtid ) ) )
{
fprintf ( stderr ,
" Error: wire transfer subject must be a WTID \n " ) ;
2021-08-07 17:50:53 +02:00
GNUNET_SCHEDULER_shutdown ( ) ;
2020-03-07 12:23:32 +01:00
return ;
}
}
else
{
/* pick one at random */
GNUNET_CRYPTO_random_block ( GNUNET_CRYPTO_QUALITY_NONCE ,
& wtid ,
sizeof ( wtid ) ) ;
}
2020-07-27 22:25:05 +02:00
params = strchr ( credit_account ,
( unsigned char ) ' & ' ) ;
if ( NULL ! = params )
2020-07-27 23:07:05 +02:00
* params = ' \0 ' ;
2020-03-07 12:23:32 +01:00
TALER_BANK_prepare_transfer ( credit_account ,
& amount ,
" http://exchange.example.com/ " ,
& wtid ,
& buf ,
& buf_size ) ;
eh = TALER_BANK_transfer ( ctx ,
& auth ,
buf ,
buf_size ,
& confirmation_cb ,
NULL ) ;
2021-11-19 20:56:53 +01:00
GNUNET_free ( buf ) ;
2020-03-07 12:23:32 +01:00
if ( NULL = = eh )
{
fprintf ( stderr ,
" Could not execute the wire transfer \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
2017-12-14 15:33:10 +01:00
}
/**
* Function called with the result of the operation .
*
* @ param cls closure
* @ param http_status HTTP response code , # MHD_HTTP_OK ( 200 ) for successful status request
* 0 if the bank ' s reply is bogus ( fails to follow the protocol )
* @ param ec detailed error code
* @ param serial_id unique ID of the wire transfer in the bank ' s records ; UINT64_MAX on error
2019-04-11 00:23:04 +02:00
* @ param timestamp timestamp when the transaction got settled at the bank .
2017-12-14 15:33:10 +01:00
* @ param json detailed response from the HTTPD , or NULL if reply was not in JSON
*/
static void
res_cb ( void * cls ,
unsigned int http_status ,
enum TALER_ErrorCode ec ,
2019-04-22 21:35:19 +02:00
uint64_t serial_id ,
2019-04-11 00:23:04 +02:00
struct GNUNET_TIME_Absolute timestamp ,
2017-12-14 15:33:10 +01:00
const json_t * json )
{
2019-09-05 11:23:24 +02:00
( void ) cls ;
( void ) timestamp ;
2017-12-14 15:33:10 +01:00
op = NULL ;
switch ( ec )
{
case TALER_EC_NONE :
global_ret = 0 ;
fprintf ( stdout ,
" %llu \n " ,
( unsigned long long ) serial_id ) ;
break ;
default :
fprintf ( stderr ,
2020-03-31 20:57:11 +02:00
" Operation failed with status code %u/%u \n " ,
2017-12-14 15:33:10 +01:00
( unsigned int ) ec ,
http_status ) ;
if ( NULL ! = json )
json_dumpf ( json ,
stderr ,
JSON_INDENT ( 2 ) ) ;
break ;
}
GNUNET_SCHEDULER_shutdown ( ) ;
}
2020-03-07 12:23:32 +01:00
/**
* Ask the bank to execute a wire transfer to the exchange .
*/
static void
2021-01-07 20:52:11 +01:00
execute_admin_transfer ( void )
2020-03-07 12:23:32 +01:00
{
struct TALER_ReservePublicKeyP reserve_pub ;
if ( NULL ! = subject )
{
if ( GNUNET_OK ! =
GNUNET_STRINGS_string_to_data ( subject ,
strlen ( subject ) ,
& reserve_pub ,
sizeof ( reserve_pub ) ) )
{
fprintf ( stderr ,
" Error: wire transfer subject must be a reserve public key \n " ) ;
return ;
}
}
else
{
/* pick one that is kind-of well-formed at random */
GNUNET_CRYPTO_random_block ( GNUNET_CRYPTO_QUALITY_NONCE ,
& reserve_pub ,
sizeof ( reserve_pub ) ) ;
}
op = TALER_BANK_admin_add_incoming ( ctx ,
& auth ,
& reserve_pub ,
& amount ,
2021-08-07 17:50:53 +02:00
debit_account ,
2020-03-07 12:23:32 +01:00
& res_cb ,
NULL ) ;
if ( NULL = = op )
{
fprintf ( stderr ,
" Could not execute the wire transfer to the exchange \n " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
}
2017-12-14 15:33:10 +01:00
/**
* Main function that will be run .
*
* @ param cls closure
* @ param args remaining command - line arguments
* @ param cfgfile name of the configuration file used ( for saving , can be NULL ! )
* @ param cfg configuration
*/
static void
run ( void * cls ,
char * const * args ,
const char * cfgfile ,
const struct GNUNET_CONFIGURATION_Handle * cfg )
{
2019-09-05 11:23:24 +02:00
( void ) cls ;
( void ) args ;
( void ) cfgfile ;
( void ) cfg ;
2020-01-11 15:19:56 +01:00
2020-03-07 12:23:32 +01:00
GNUNET_SCHEDULER_add_shutdown ( & do_shutdown ,
NULL ) ;
2017-12-14 15:33:10 +01:00
ctx = GNUNET_CURL_init ( & GNUNET_CURL_gnunet_scheduler_reschedule ,
& rc ) ;
GNUNET_assert ( NULL ! = ctx ) ;
rc = GNUNET_CURL_gnunet_rc_create ( ctx ) ;
2020-03-07 12:23:32 +01:00
if ( NULL ! = account_section )
{
2021-08-04 14:06:49 +02:00
if ( 0 ! = strncasecmp ( " exchange-accountcredentials- " ,
2021-08-04 14:05:13 +02:00
account_section ,
strlen ( " exchange-accountcredentials- " ) ) )
{
fprintf ( stderr ,
" Error: invalid section specified, must begin with `%s` \n " ,
" exchange-accountcredentials- " ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
2020-03-07 12:23:32 +01:00
if ( ( NULL ! = auth . wire_gateway_url ) | |
( NULL ! = auth . details . basic . username ) | |
( NULL ! = auth . details . basic . password ) )
{
fprintf ( stderr ,
2021-08-03 14:41:42 +02:00
" Error: Conflicting authentication options provided. Please only use one method. \n " ) ;
2020-03-07 12:23:32 +01:00
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
if ( GNUNET_OK ! =
TALER_BANK_auth_parse_cfg ( cfg ,
account_section ,
& auth ) )
{
fprintf ( stderr ,
2021-08-03 14:41:42 +02:00
" Error: Authentication information not found in configuration section `%s' \n " ,
2020-03-07 12:23:32 +01:00
account_section ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
}
else
{
if ( ( NULL ! = auth . wire_gateway_url ) & &
( NULL ! = auth . details . basic . username ) & &
( NULL ! = auth . details . basic . password ) )
{
auth . method = TALER_BANK_AUTH_BASIC ;
}
else if ( NULL = = auth . wire_gateway_url )
{
fprintf ( stderr ,
2021-08-03 14:41:42 +02:00
" Error: No account specified (use -b or -s options). \n " ) ;
2020-03-07 12:23:32 +01:00
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
}
2021-08-03 14:41:42 +02:00
if ( ( NULL = = auth . wire_gateway_url ) | |
( 0 = = strlen ( auth . wire_gateway_url ) ) | |
2021-08-05 21:23:29 +02:00
( 0 ! = strncasecmp ( " http " ,
auth . wire_gateway_url ,
strlen ( " http " ) ) ) )
2021-08-03 14:41:42 +02:00
{
fprintf ( stderr ,
" Error: Invalid wire gateway URL `%s' configured. \n " ,
auth . wire_gateway_url ) ;
GNUNET_SCHEDULER_shutdown ( ) ;
return ;
}
2020-03-07 12:23:32 +01:00
if ( ( GNUNET_YES = = incoming_history ) & &
2020-08-29 01:24:21 +02:00
( GNUNET_YES = = outgoing_history ) )
2020-03-07 12:23:32 +01:00
{
fprintf ( stderr ,
2021-08-03 14:41:42 +02:00
" Error: Please specify only -i or -o, but not both. \n " ) ;
2017-12-14 15:33:10 +01:00
GNUNET_SCHEDULER_shutdown ( ) ;
2020-03-07 12:23:32 +01:00
return ;
}
if ( GNUNET_YES = = incoming_history )
{
execute_credit_history ( ) ;
return ;
}
if ( GNUNET_YES = = outgoing_history )
{
execute_debit_history ( ) ;
return ;
}
if ( NULL ! = credit_account )
{
execute_wire_transfer ( ) ;
return ;
}
if ( NULL ! = debit_account )
{
execute_admin_transfer ( ) ;
return ;
}
GNUNET_log ( GNUNET_ERROR_TYPE_WARNING ,
" No operation specified. \n " ) ;
global_ret = 0 ;
GNUNET_SCHEDULER_shutdown ( ) ;
2017-12-14 15:33:10 +01:00
}
/**
2021-08-03 14:41:42 +02:00
* The main function of the taler - exchange - wire - gateway - client
2017-12-14 15:33:10 +01:00
*
* @ param argc number of arguments from the command line
* @ param argv command line arguments
* @ return 0 ok , 1 on error
*/
int
2020-03-07 12:23:32 +01:00
main ( int argc ,
char * const * argv )
2017-12-14 15:33:10 +01:00
{
const struct GNUNET_GETOPT_CommandLineOption options [ ] = {
2020-03-07 12:23:32 +01:00
TALER_getopt_get_amount ( ' a ' ,
" amount " ,
" VALUE " ,
" value to transfer " ,
& amount ) ,
GNUNET_GETOPT_option_string ( ' b ' ,
" bank " ,
" URL " ,
" Wire gateway URL to use to talk to the bank " ,
& auth . wire_gateway_url ) ,
GNUNET_GETOPT_option_string ( ' C ' ,
" credit " ,
" ACCOUNT " ,
" payto URI of the bank account to credit (when making outgoing transfers) " ,
& credit_account ) ,
GNUNET_GETOPT_option_string ( ' D ' ,
" debit " ,
" PAYTO-URL " ,
" payto URI of the bank account to debit (when making incoming transfers) " ,
& debit_account ) ,
GNUNET_GETOPT_option_flag ( ' i ' ,
" credit-history " ,
" Ask to get a list of 10 incoming transactions. " ,
& incoming_history ) ,
GNUNET_GETOPT_option_flag ( ' o ' ,
" debit-history " ,
" Ask to get a list of 10 outgoing transactions. " ,
& outgoing_history ) ,
GNUNET_GETOPT_option_string ( ' p ' ,
" pass " ,
" PASSPHRASE " ,
" passphrase to use for authentication " ,
& auth . details . basic . password ) ,
GNUNET_GETOPT_option_string ( ' s ' ,
" section " ,
" ACCOUNT-SECTION " ,
" Which config section has the credentials to access the bank. Conflicts with -b -u and -p options. \n " ,
& account_section ) ,
GNUNET_GETOPT_option_string ( ' S ' ,
" subject " ,
" SUBJECT " ,
" specifies the wire transfer subject " ,
& subject ) ,
GNUNET_GETOPT_option_string ( ' u ' ,
" user " ,
" USERNAME " ,
" username to use for authentication " ,
& auth . details . basic . username ) ,
GNUNET_GETOPT_option_ulong ( ' w ' ,
" since-when " ,
" ROW " ,
" When asking the bank for transactions history, this option commands that all the results should have IDs settled after SW. If not given, then the 10 youngest transactions are returned. " ,
& start_row ) ,
2017-12-14 15:33:10 +01:00
GNUNET_GETOPT_OPTION_END
} ;
2021-01-07 20:52:11 +01:00
enum GNUNET_GenericReturnValue ret ;
2017-12-14 15:33:10 +01:00
2021-01-07 20:52:11 +01:00
/* force linker to link against libtalerutil; if we do
not do this , the linker may " optimize " libtalerutil
away and skip # TALER_OS_init ( ) , which we do need */
( void ) TALER_project_data_default ( ) ;
2017-12-14 15:33:10 +01:00
if ( GNUNET_OK ! =
2021-01-07 20:52:11 +01:00
GNUNET_STRINGS_get_utf8_args ( argc , argv ,
& argc , & argv ) )
return 4 ;
global_ret = 1 ;
ret = GNUNET_PROGRAM_run (
argc , argv ,
" taler-wire-gateway-client " ,
gettext_noop ( " Client tool of the Taler Wire Gateway " ) ,
options ,
& run , NULL ) ;
GNUNET_free_nz ( ( void * ) argv ) ;
if ( GNUNET_SYSERR = = ret )
return 3 ;
if ( GNUNET_NO = = ret )
return 0 ;
2017-12-14 15:33:10 +01:00
return global_ret ;
}
2019-10-31 12:59:50 +01:00
2021-01-07 20:52:11 +01:00
/* end taler-wire-gateway-client.c */