adding support for transaction history to wire plugin API (#4959)
This commit is contained in:
parent
234dbcc7b7
commit
f4df63e448
@ -22,25 +22,22 @@ DB_CONN_STR = "postgres:///talercheck"
|
|||||||
# Change here to enable SEPA wire transfers.
|
# Change here to enable SEPA wire transfers.
|
||||||
ENABLE = NO
|
ENABLE = NO
|
||||||
|
|
||||||
[exchange-wire-incoming-sepa]
|
# Response for /wire
|
||||||
SEPA_RESPONSE_FILE = "sepa.json"
|
SEPA_RESPONSE_FILE = "sepa.json"
|
||||||
|
|
||||||
[exchange-wire-outgoing-sepa]
|
[exchange-wire-outgoing-sepa]
|
||||||
SEPA_RESPONSE_FILE = "sepa.json"
|
# TBD
|
||||||
|
|
||||||
[exchange-wire-sepa]
|
|
||||||
|
[exchange-wire-test]
|
||||||
|
# Change here to disable TEST wire transfers.
|
||||||
ENABLE = YES
|
ENABLE = YES
|
||||||
|
|
||||||
[exchange-wire-incoming-test]
|
# Response for /wire
|
||||||
|
TEST_RESPONSE_FILE = "test.json"
|
||||||
|
|
||||||
# What is the main website of the bank?
|
# What is the main website of the bank?
|
||||||
BANK_URI = "https://bank/"
|
BANK_URI = "https://bank/"
|
||||||
# Into which account at the 'bank' should incoming
|
# Into which account at the 'bank' should incoming
|
||||||
# wire transfers be made?
|
# wire transfers be made?
|
||||||
BANK_ACCOUNT_NUMBER = 2
|
BANK_ACCOUNT_NUMBER = 2
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
|
||||||
# What is the main website of the bank?
|
|
||||||
BANK_URI = "https://bank/"
|
|
||||||
# From which account at the 'bank' should outgoing
|
|
||||||
# wire transfers be made?
|
|
||||||
BANK_ACCOUNT_NUMBER = 2
|
|
||||||
|
@ -441,36 +441,24 @@ option @cite{currency} in section @cite{[taler]}.
|
|||||||
@section Bank account
|
@section Bank account
|
||||||
|
|
||||||
@menu
|
@menu
|
||||||
* Wireformat::
|
* Wiremethod-test::
|
||||||
* Incoming::
|
* Wiremethod-sepa::
|
||||||
* Outgoing::
|
|
||||||
|
|
||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
@node Wireformat
|
@node Wiremethod-test
|
||||||
@subsection Wireformat
|
@subsection Wiremethod-test
|
||||||
|
|
||||||
|
|
||||||
The wireformat is the protocol to be used between the exchange and the
|
|
||||||
banks. The option is @cite{wireformat}, under section
|
|
||||||
@cite{[exchange]}. The exchange currently supports the @cite{test}
|
|
||||||
wireformat. This wireformat is used for testing the system against a
|
|
||||||
fictional bank.
|
|
||||||
|
|
||||||
@cartouche
|
|
||||||
@quotation Note
|
|
||||||
The SEPA wireformat is work in progress.
|
|
||||||
@end quotation
|
|
||||||
@end cartouche
|
|
||||||
|
|
||||||
@node Incoming
|
|
||||||
@subsection Incoming
|
|
||||||
|
|
||||||
|
To enable the wire transfer method ``test'', you need to set
|
||||||
|
``ENABLE=YES'' in section @cite{[exchange-wire-test]}.
|
||||||
|
|
||||||
The bank account where the exchange gets money from customers is
|
The bank account where the exchange gets money from customers is
|
||||||
configured under the section @cite{[exchange-wire-incoming-X]}, where
|
configured under the section @cite{[exchange-wire-test]}. It must
|
||||||
@cite{X} matches the value given to the option @cite{wireformat}. This
|
contain the options ``EXCHANGE_ACCOUNT_NO'' and ``BANK_URI''.
|
||||||
section contains only one option: @cite{X_response_file}, which takes
|
For basic authentication, it must additionally contain the
|
||||||
|
``USERNAME'' and ``PASSWORD'' of the exchange's account at the bank.
|
||||||
|
|
||||||
|
For incoming transfers, the section must additional contain the
|
||||||
|
option: @cite{test_response_file}, which takes
|
||||||
the path to a text file containing the exchange's bank account details
|
the path to a text file containing the exchange's bank account details
|
||||||
in JSON format.
|
in JSON format.
|
||||||
|
|
||||||
@ -483,21 +471,47 @@ $ taler-exchange-wire -j '@{"name": "The Exchange", "account_number":
|
|||||||
test -o exchange.json
|
test -o exchange.json
|
||||||
@end example
|
@end example
|
||||||
|
|
||||||
|
Note that the value given to option @cite{-t} must match the value in
|
||||||
|
the JSON's field @code{"type"}.
|
||||||
|
|
||||||
|
The generated file will be echoed by the exchange when serving
|
||||||
|
/wire@footnote{https://api.taler.net/api-exchange.html#wire-req}
|
||||||
|
requests.
|
||||||
|
|
||||||
|
|
||||||
|
@node Wiremethod-sepa
|
||||||
|
@subsection Wiremethod-sepa
|
||||||
|
|
||||||
|
To enable the wire transfer method ``sepa'', you need to set
|
||||||
|
``ENABLE=YES'' in section @cite{[exchange-wire-sepa]}.
|
||||||
|
|
||||||
|
|
||||||
|
The bank account where the exchange gets money from customers is
|
||||||
|
configured under the section @cite{[exchange-wire-incoming-sepa]}. This
|
||||||
|
section contains only one option: @cite{sepa_response_file}, which takes
|
||||||
|
the path to a text file containing the exchange's bank account details
|
||||||
|
in JSON format.
|
||||||
|
|
||||||
|
The command line tool @cite{taler-exchange-wire} is used to create such a file.
|
||||||
|
For example, the utility may be invoked as follows:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ taler-exchange-wire -j '@{"name": "The Exchange", "account_number":
|
||||||
|
10, "bank_uri": "https://bank.demo.taler.net", "type": "sepa"@}' -t
|
||||||
|
sepa -o exchange.json
|
||||||
|
@end example
|
||||||
|
|
||||||
Note that the value given to option @cite{-t} must match the value in the JSON's field @code{"type"}.
|
Note that the value given to option @cite{-t} must match the value in the JSON's field @code{"type"}.
|
||||||
|
|
||||||
The generated file will be echoed by the exchange when serving
|
The generated file will be echoed by the exchange when serving
|
||||||
/wire@footnote{https://api.taler.net/api-exchange.html#wire-req}
|
/wire@footnote{https://api.taler.net/api-exchange.html#wire-req}
|
||||||
requests.
|
requests.
|
||||||
|
|
||||||
@node Outgoing
|
This exchange's outgoing bank account is used to give money to merchants, after
|
||||||
@subsection Outgoing
|
|
||||||
|
|
||||||
This exchange's bank account is used to give money to merchants, after
|
|
||||||
successful
|
successful
|
||||||
deposits@footnote{https://api.taler.net/api-exchange.html#deposit-par}
|
deposits@footnote{https://api.taler.net/api-exchange.html#deposit-par}
|
||||||
operations. If @cite{test} is the chosen wireformat, the outcoming
|
operations. The outgoing bank account is configured by the following
|
||||||
bank account is configured by the following options under
|
options under @cite{[exchange-wire-outgoing-sepa]}: (NOT YET SUPPORTED).
|
||||||
@cite{[exchange-wire-outcoming-test]}:
|
|
||||||
|
|
||||||
@quotation
|
@quotation
|
||||||
|
|
||||||
|
@ -16,7 +16,8 @@ libtalerbank_la_LDFLAGS = \
|
|||||||
|
|
||||||
libtalerbank_la_SOURCES = \
|
libtalerbank_la_SOURCES = \
|
||||||
bank_api_admin.c \
|
bank_api_admin.c \
|
||||||
bank_api_common.c bank_api_common.h
|
bank_api_common.c bank_api_common.h \
|
||||||
|
bank_api_history.c
|
||||||
|
|
||||||
libtalerbank_la_LIBADD = \
|
libtalerbank_la_LIBADD = \
|
||||||
$(top_builddir)/src/json/libtalerjson.la \
|
$(top_builddir)/src/json/libtalerjson.la \
|
||||||
|
@ -64,34 +64,6 @@ struct TALER_BANK_AdminAddIncomingHandle
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Obtain the URL to use for an API request.
|
|
||||||
*
|
|
||||||
* @param u base URL of the bank
|
|
||||||
* @param path Taler API path (i.e. "/reserve/withdraw")
|
|
||||||
* @return the full URI to use with cURL
|
|
||||||
*/
|
|
||||||
static char *
|
|
||||||
path_to_url (const char *u,
|
|
||||||
const char *path)
|
|
||||||
{
|
|
||||||
char *url;
|
|
||||||
|
|
||||||
if ( ('/' == path[0]) &&
|
|
||||||
(0 < strlen (u)) &&
|
|
||||||
('/' == u[strlen (u) - 1]) )
|
|
||||||
path++; /* avoid generating URL with "//" from concat */
|
|
||||||
GNUNET_asprintf (&url,
|
|
||||||
"%s%s",
|
|
||||||
u,
|
|
||||||
path);
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called when we're done processing the
|
* Function called when we're done processing the
|
||||||
* HTTP /admin/add/incoming request.
|
* HTTP /admin/add/incoming request.
|
||||||
@ -195,8 +167,8 @@ TALER_BANK_admin_add_incoming (struct GNUNET_CURL_Context *ctx,
|
|||||||
aai = GNUNET_new (struct TALER_BANK_AdminAddIncomingHandle);
|
aai = GNUNET_new (struct TALER_BANK_AdminAddIncomingHandle);
|
||||||
aai->cb = res_cb;
|
aai->cb = res_cb;
|
||||||
aai->cb_cls = res_cb_cls;
|
aai->cb_cls = res_cb_cls;
|
||||||
aai->request_url = path_to_url (bank_base_url,
|
aai->request_url = TALER_BANK_path_to_url_ (bank_base_url,
|
||||||
"/admin/add/incoming");
|
"/admin/add/incoming");
|
||||||
aai->authh = TALER_BANK_make_auth_header_ (auth);
|
aai->authh = TALER_BANK_make_auth_header_ (auth);
|
||||||
eh = curl_easy_init ();
|
eh = curl_easy_init ();
|
||||||
GNUNET_assert (NULL != (aai->json_enc =
|
GNUNET_assert (NULL != (aai->json_enc =
|
||||||
|
@ -85,4 +85,32 @@ TALER_BANK_make_auth_header_ (const struct TALER_BANK_AuthenticationData *auth)
|
|||||||
return authh;
|
return authh;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the URL to use for an API request.
|
||||||
|
*
|
||||||
|
* @param u base URL of the bank
|
||||||
|
* @param path Taler API path (i.e. "/history")
|
||||||
|
* @return the full URI to use with cURL
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
TALER_BANK_path_to_url_ (const char *u,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
char *url;
|
||||||
|
|
||||||
|
if ( ('/' == path[0]) &&
|
||||||
|
(0 < strlen (u)) &&
|
||||||
|
('/' == u[strlen (u) - 1]) )
|
||||||
|
path++; /* avoid generating URL with "//" from concat */
|
||||||
|
GNUNET_asprintf (&url,
|
||||||
|
"%s%s",
|
||||||
|
u,
|
||||||
|
path);
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* end of bank_api_common.c */
|
/* end of bank_api_common.c */
|
||||||
|
@ -39,4 +39,16 @@ struct curl_slist *
|
|||||||
TALER_BANK_make_auth_header_ (const struct TALER_BANK_AuthenticationData *auth);
|
TALER_BANK_make_auth_header_ (const struct TALER_BANK_AuthenticationData *auth);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtain the URL to use for an API request.
|
||||||
|
*
|
||||||
|
* @param u base URL of the bank
|
||||||
|
* @param path Taler API path (i.e. "/history")
|
||||||
|
* @return the full URI to use with cURL
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
TALER_BANK_path_to_url_ (const char *u,
|
||||||
|
const char *path);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
328
src/bank-lib/bank_api_history.c
Normal file
328
src/bank-lib/bank_api_history.c
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
/*
|
||||||
|
This file is part of TALER
|
||||||
|
Copyright (C) 2017 GNUnet e.V. & Inria
|
||||||
|
|
||||||
|
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/>
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @file bank-lib/bank_api_history.c
|
||||||
|
* @brief Implementation of the /history requests of the bank's HTTP API
|
||||||
|
* @author Christian Grothoff
|
||||||
|
*/
|
||||||
|
#include "platform.h"
|
||||||
|
#include "bank_api_common.h"
|
||||||
|
#include <microhttpd.h> /* just for HTTP status codes */
|
||||||
|
#include "taler_signatures.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief A /history Handle
|
||||||
|
*/
|
||||||
|
struct TALER_BANK_HistoryHandle
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The url for this request.
|
||||||
|
*/
|
||||||
|
char *request_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base URL of the bank.
|
||||||
|
*/
|
||||||
|
char *bank_base_url;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle for the request.
|
||||||
|
*/
|
||||||
|
struct GNUNET_CURL_Job *job;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HTTP authentication-related headers for the request.
|
||||||
|
*/
|
||||||
|
struct curl_slist *authh;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call with the result.
|
||||||
|
*/
|
||||||
|
TALER_BANK_HistoryResultCallback hcb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for @a cb.
|
||||||
|
*/
|
||||||
|
void *hcb_cls;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse history given in JSON format and invoke the callback on each item.
|
||||||
|
*
|
||||||
|
* @param hh handle to the account history request
|
||||||
|
* @param history JSON array with the history
|
||||||
|
* @return #GNUNET_OK if history was valid and @a rhistory and @a balance
|
||||||
|
* were set,
|
||||||
|
* #GNUNET_SYSERR if there was a protocol violation in @a history
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
parse_account_history (struct TALER_BANK_HistoryHandle *hh,
|
||||||
|
const json_t *history)
|
||||||
|
{
|
||||||
|
for (unsigned int i=0;i<json_array_size (history);i++)
|
||||||
|
{
|
||||||
|
struct TALER_BANK_TransferDetails td;
|
||||||
|
const char *sign;
|
||||||
|
uint64_t other_account;
|
||||||
|
uint64_t serial_id;
|
||||||
|
enum TALER_BANK_Direction direction;
|
||||||
|
struct GNUNET_JSON_Specification hist_spec[] = {
|
||||||
|
GNUNET_JSON_spec_string ("sign",
|
||||||
|
&sign),
|
||||||
|
TALER_JSON_spec_amount ("amount",
|
||||||
|
&td.amount),
|
||||||
|
GNUNET_JSON_spec_absolute_time ("date",
|
||||||
|
&td.execution_date),
|
||||||
|
GNUNET_JSON_spec_uint64 ("row_id",
|
||||||
|
&serial_id),
|
||||||
|
GNUNET_JSON_spec_string ("wire_subject",
|
||||||
|
&td.wire_transfer_subject),
|
||||||
|
GNUNET_JSON_spec_uint64 ("other_account",
|
||||||
|
&other_account),
|
||||||
|
GNUNET_JSON_spec_end()
|
||||||
|
};
|
||||||
|
json_t *transaction = json_array_get (history,
|
||||||
|
i);
|
||||||
|
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
GNUNET_JSON_parse (transaction,
|
||||||
|
hist_spec,
|
||||||
|
NULL, NULL))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
return GNUNET_SYSERR;
|
||||||
|
}
|
||||||
|
td.account_details = json_pack ("{s:s, s:s, s:I}",
|
||||||
|
"type", "test",
|
||||||
|
"bank_uri", hh->bank_base_url,
|
||||||
|
"account_number", (json_int_t) other_account);
|
||||||
|
direction = (0 == strcasecmp (sign,
|
||||||
|
"+"))
|
||||||
|
? TALER_BANK_DIRECTION_CREDIT
|
||||||
|
: TALER_BANK_DIRECTION_DEBIT;
|
||||||
|
hh->hcb (hh->hcb_cls,
|
||||||
|
MHD_HTTP_OK,
|
||||||
|
direction,
|
||||||
|
serial_id,
|
||||||
|
&td,
|
||||||
|
transaction);
|
||||||
|
GNUNET_JSON_parse_free (hist_spec);
|
||||||
|
json_decref (td.account_details);
|
||||||
|
}
|
||||||
|
return GNUNET_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called when we're done processing the
|
||||||
|
* HTTP /admin/add/incoming request.
|
||||||
|
*
|
||||||
|
* @param cls the `struct TALER_BANK_HistoryHandle`
|
||||||
|
* @param response_code HTTP response code, 0 on error
|
||||||
|
* @param json parsed JSON result, NULL on error
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
handle_history_finished (void *cls,
|
||||||
|
long response_code,
|
||||||
|
const json_t *json)
|
||||||
|
{
|
||||||
|
struct TALER_BANK_HistoryHandle *hh = cls;
|
||||||
|
|
||||||
|
hh->job = NULL;
|
||||||
|
switch (response_code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_OK:
|
||||||
|
if (GNUNET_OK !=
|
||||||
|
parse_account_history (hh,
|
||||||
|
json))
|
||||||
|
{
|
||||||
|
GNUNET_break_op (0);
|
||||||
|
response_code = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
response_code = MHD_HTTP_NO_CONTENT; /* signal end of list */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_NO_CONTENT:
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_BAD_REQUEST:
|
||||||
|
/* This should never happen, either us or the bank is buggy
|
||||||
|
(or API version conflict); just pass JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_FORBIDDEN:
|
||||||
|
/* Access denied */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_UNAUTHORIZED:
|
||||||
|
/* Nothing really to verify, bank says one of the signatures is
|
||||||
|
invalid; as we checked them, this should never happen, we
|
||||||
|
should pass the JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_NOT_FOUND:
|
||||||
|
/* Nothing really to verify, this should never
|
||||||
|
happen, we should pass the JSON reply to the application */
|
||||||
|
break;
|
||||||
|
case MHD_HTTP_INTERNAL_SERVER_ERROR:
|
||||||
|
/* Server had an internal issue; we should retry, but this API
|
||||||
|
leaves this to the application */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/* unexpected response code */
|
||||||
|
GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
|
||||||
|
"Unexpected response code %u\n",
|
||||||
|
(unsigned int) response_code);
|
||||||
|
GNUNET_break (0);
|
||||||
|
response_code = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
hh->hcb (hh->hcb_cls,
|
||||||
|
response_code,
|
||||||
|
TALER_BANK_DIRECTION_NONE,
|
||||||
|
0LLU,
|
||||||
|
NULL,
|
||||||
|
json);
|
||||||
|
TALER_BANK_history_cancel (hh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the wire transfer history of a bank account.
|
||||||
|
*
|
||||||
|
* @param ctx curl context for the event loop
|
||||||
|
* @param bank_base_url URL of the bank (used to execute this request)
|
||||||
|
* @param auth authentication data to use
|
||||||
|
* @param account_number which account number should we query
|
||||||
|
* @param direction what kinds of wire transfers should be returned
|
||||||
|
* @param start_row from which row on do we want to get results, use UINT64_MAX for the latest; exclusive
|
||||||
|
* @param num_results how many results do we want; negative numbers to go into the past,
|
||||||
|
* positive numbers to go into the future starting at @a start_row;
|
||||||
|
* must not be zero.
|
||||||
|
* @param hres_cb the callback to call with the transaction history
|
||||||
|
* @param hres_cb_cls closure for the above callback
|
||||||
|
* @return NULL
|
||||||
|
* if the inputs are invalid (i.e. zero value for @e num_results).
|
||||||
|
* In this case, the callback is not called.
|
||||||
|
*/
|
||||||
|
struct TALER_BANK_HistoryHandle *
|
||||||
|
TALER_BANK_history (struct GNUNET_CURL_Context *ctx,
|
||||||
|
const char *bank_base_url,
|
||||||
|
const struct TALER_BANK_AuthenticationData *auth,
|
||||||
|
uint64_t account_number,
|
||||||
|
enum TALER_BANK_Direction direction,
|
||||||
|
uint64_t start_row,
|
||||||
|
int64_t num_results,
|
||||||
|
TALER_BANK_HistoryResultCallback hres_cb,
|
||||||
|
void *hres_cb_cls)
|
||||||
|
{
|
||||||
|
struct TALER_BANK_HistoryHandle *hh;
|
||||||
|
CURL *eh;
|
||||||
|
char *url;
|
||||||
|
|
||||||
|
if (0 == num_results)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (TALER_BANK_DIRECTION_NONE == direction)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (UINT64_MAX == start_row)
|
||||||
|
{
|
||||||
|
if (TALER_BANK_DIRECTION_BOTH == direction)
|
||||||
|
GNUNET_asprintf (&url,
|
||||||
|
"/history?account_number=%llu&num_results=%lld",
|
||||||
|
(unsigned long long) account_number,
|
||||||
|
(long long) num_results);
|
||||||
|
else
|
||||||
|
GNUNET_asprintf (&url,
|
||||||
|
"/history?account_number=%llu&num_results=%lld&direction=%s",
|
||||||
|
(unsigned long long) account_number,
|
||||||
|
(long long) num_results,
|
||||||
|
(TALER_BANK_DIRECTION_CREDIT == direction) ? "credit" : "debit");
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (TALER_BANK_DIRECTION_BOTH == direction)
|
||||||
|
GNUNET_asprintf (&url,
|
||||||
|
"/history?account_number=%llu&num_results=%lld&start_row=%llu",
|
||||||
|
(unsigned long long) account_number,
|
||||||
|
(long long) num_results,
|
||||||
|
(unsigned long long) start_row);
|
||||||
|
else
|
||||||
|
GNUNET_asprintf (&url,
|
||||||
|
"/history?account_number=%llu&num_results=%lld&start_row=%llu&direction=%s",
|
||||||
|
(unsigned long long) account_number,
|
||||||
|
(long long) num_results,
|
||||||
|
(unsigned long long) start_row,
|
||||||
|
(TALER_BANK_DIRECTION_CREDIT == direction) ? "credit" : "debit");
|
||||||
|
}
|
||||||
|
|
||||||
|
hh = GNUNET_new (struct TALER_BANK_HistoryHandle);
|
||||||
|
hh->hcb = hres_cb;
|
||||||
|
hh->hcb_cls = hres_cb_cls;
|
||||||
|
hh->bank_base_url = GNUNET_strdup (bank_base_url);
|
||||||
|
hh->request_url = TALER_BANK_path_to_url_ (bank_base_url,
|
||||||
|
url);
|
||||||
|
GNUNET_free (url);
|
||||||
|
hh->authh = TALER_BANK_make_auth_header_ (auth);
|
||||||
|
eh = curl_easy_init ();
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_HTTPHEADER,
|
||||||
|
hh->authh));
|
||||||
|
GNUNET_assert (CURLE_OK ==
|
||||||
|
curl_easy_setopt (eh,
|
||||||
|
CURLOPT_URL,
|
||||||
|
hh->request_url));
|
||||||
|
hh->job = GNUNET_CURL_job_add (ctx,
|
||||||
|
eh,
|
||||||
|
GNUNET_NO,
|
||||||
|
&handle_history_finished,
|
||||||
|
hh);
|
||||||
|
return hh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel a history request. This function cannot be used on a request
|
||||||
|
* handle if a response is already served for it.
|
||||||
|
*
|
||||||
|
* @param hh the history request handle
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
TALER_BANK_history_cancel (struct TALER_BANK_HistoryHandle *hh)
|
||||||
|
{
|
||||||
|
if (NULL != hh->job)
|
||||||
|
{
|
||||||
|
GNUNET_CURL_job_cancel (hh->job);
|
||||||
|
hh->job = NULL;
|
||||||
|
}
|
||||||
|
curl_slist_free_all (hh->authh);
|
||||||
|
GNUNET_free (hh->request_url);
|
||||||
|
GNUNET_free (hh->bank_base_url);
|
||||||
|
GNUNET_free (hh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* end of bank_api_history.c */
|
@ -26,14 +26,12 @@ DB_CONN_STR = "postgres:///talercheck"
|
|||||||
# Enable 'test' for testing of the actual coin operations.
|
# Enable 'test' for testing of the actual coin operations.
|
||||||
ENABLE = YES
|
ENABLE = YES
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
|
||||||
# What is the main website of the bank?
|
# What is the main website of the bank?
|
||||||
# (Not used unless the aggregator is run.)
|
# (Not used unless the aggregator is run.)
|
||||||
BANK_URI = "http://localhost:8082/"
|
BANK_URI = "http://localhost:8082/"
|
||||||
# From which account at the 'bank' should outgoing wire transfers be made?
|
# From which account at the 'bank' should outgoing wire transfers be made?
|
||||||
BANK_ACCOUNT_NUMBER = 2
|
BANK_ACCOUNT_NUMBER = 2
|
||||||
|
|
||||||
[exchange-wire-incoming-test]
|
|
||||||
# This is the response we give out for the /wire request. It provides
|
# This is the response we give out for the /wire request. It provides
|
||||||
# wallets with the bank information for transfers to the exchange.
|
# wallets with the bank information for transfers to the exchange.
|
||||||
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
|
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
|
||||||
|
@ -30,6 +30,10 @@ DB_CONN_STR = "postgres:///talercheck"
|
|||||||
# Enable 'sepa' to test SEPA-specific routines.
|
# Enable 'sepa' to test SEPA-specific routines.
|
||||||
ENABLE = YES
|
ENABLE = YES
|
||||||
|
|
||||||
|
# This is the response we give out for the /wire request. It provides
|
||||||
|
# wallets with the bank information for transfers to the exchange.
|
||||||
|
SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json
|
||||||
|
|
||||||
# Fees for the forseeable future...
|
# Fees for the forseeable future...
|
||||||
# If you see this after 2017, update to match the next 10 years...
|
# If you see this after 2017, update to match the next 10 years...
|
||||||
WIRE-FEE-2017 = EUR:0.01
|
WIRE-FEE-2017 = EUR:0.01
|
||||||
@ -54,11 +58,6 @@ CLOSING-FEE-2024 = EUR:0.01
|
|||||||
CLOSING-FEE-2025 = EUR:0.01
|
CLOSING-FEE-2025 = EUR:0.01
|
||||||
CLOSING-FEE-2026 = EUR:0.01
|
CLOSING-FEE-2026 = EUR:0.01
|
||||||
|
|
||||||
[exchange-wire-incoming-sepa]
|
|
||||||
# This is the response we give out for the /wire request. It provides
|
|
||||||
# wallets with the bank information for transfers to the exchange.
|
|
||||||
SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/sepa.json
|
|
||||||
|
|
||||||
[exchange-wire-test]
|
[exchange-wire-test]
|
||||||
# Enable 'test' for testing of the actual coin operations.
|
# Enable 'test' for testing of the actual coin operations.
|
||||||
ENABLE = YES
|
ENABLE = YES
|
||||||
@ -87,17 +86,16 @@ CLOSING-FEE-2024 = EUR:0.01
|
|||||||
CLOSING-FEE-2025 = EUR:0.01
|
CLOSING-FEE-2025 = EUR:0.01
|
||||||
CLOSING-FEE-2026 = EUR:0.01
|
CLOSING-FEE-2026 = EUR:0.01
|
||||||
|
|
||||||
[exchange-wire-incoming-test]
|
|
||||||
# This is the response we give out for the /wire request. It provides
|
# This is the response we give out for the /wire request. It provides
|
||||||
# wallets with the bank information for transfers to the exchange.
|
# wallets with the bank information for transfers to the exchange.
|
||||||
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
|
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/test.json
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
|
||||||
# What is the main website of the bank?
|
# What is the main website of the bank?
|
||||||
BANK_URI = "http://localhost:8082/"
|
BANK_URI = "http://localhost:8082/"
|
||||||
# From which account at the 'bank' should outgoing wire transfers be made?
|
# From which account at the 'bank' should outgoing wire transfers be made?
|
||||||
BANK_ACCOUNT_NUMBER = 2
|
BANK_ACCOUNT_NUMBER = 2
|
||||||
|
|
||||||
|
|
||||||
[coin_eur_ct_1]
|
[coin_eur_ct_1]
|
||||||
value = EUR:0.01
|
value = EUR:0.01
|
||||||
duration_overlap = 5 minutes
|
duration_overlap = 5 minutes
|
||||||
|
@ -187,21 +187,21 @@ then
|
|||||||
# If possible, initialize outgoing wire account details ('test' method only)
|
# If possible, initialize outgoing wire account details ('test' method only)
|
||||||
if (test "test" = "$WMETHOD" -a ! -z "$ARG_BANK_URI")
|
if (test "test" = "$WMETHOD" -a ! -z "$ARG_BANK_URI")
|
||||||
then
|
then
|
||||||
$CS -s exchange-wire-outgoing-test -o BANK_URI -V "$ARG_BANK_URI" || exit 1
|
$CS -s exchange-wire-test -o BANK_URI -V "$ARG_BANK_URI" || exit 1
|
||||||
else
|
else
|
||||||
echo "Skipped generating outgoing wire account details for exchange"
|
echo "Skipped generating wire account details for exchange"
|
||||||
fi
|
fi
|
||||||
if (test "test" = "$ARG_W" -a ! -z "$ARG_EXCHANGE_BANK_ACCOUNT")
|
if (test "test" = "$ARG_W" -a ! -z "$ARG_EXCHANGE_BANK_ACCOUNT")
|
||||||
then
|
then
|
||||||
$CS -s exchange-wire-outgoing-test -o BANK_ACCOUNT_NUMBER -V "$ARG_EXCHANGE_BANK_ACCOUNT" || exit 1
|
$CS -s exchange-wire-test -o BANK_ACCOUNT_NUMBER -V "$ARG_EXCHANGE_BANK_ACCOUNT" || exit 1
|
||||||
else
|
else
|
||||||
echo "Skipped generating outgoing wire account details for exchange"
|
echo "Skipped generating wire account details for exchange"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# If possible, initialize /wire response from JSON (with signature)
|
# If possible, initialize /wire response from JSON (with signature)
|
||||||
if (test ! -z $ARG_JE)
|
if (test ! -z $ARG_JE)
|
||||||
then
|
then
|
||||||
JSONF=`$CS -s exchange-wire-incoming-${ARG_W} -o ${ARG_W}_RESPONSE_FILE -f`
|
JSONF=`$CS -s exchange-wire-${ARG_W} -o ${ARG_W}_RESPONSE_FILE -f`
|
||||||
# echo "Generating /wire response at $JSONF"
|
# echo "Generating /wire response at $JSONF"
|
||||||
mkdir -p `dirname $JSONF`
|
mkdir -p `dirname $JSONF`
|
||||||
taler-exchange-wire -c "$ARG_CONFIG" -t "$ARG_W" -j "$ARG_JE" -m "$MASTER_KEY" -o "$JSONF" || exit 1
|
taler-exchange-wire -c "$ARG_CONFIG" -t "$ARG_W" -j "$ARG_JE" -m "$MASTER_KEY" -o "$JSONF" || exit 1
|
||||||
|
@ -207,12 +207,10 @@ TEH_json_validate_wireformat (const json_t *wire,
|
|||||||
* Obtain JSON of the supported wire methods for a given
|
* Obtain JSON of the supported wire methods for a given
|
||||||
* account name prefix.
|
* account name prefix.
|
||||||
*
|
*
|
||||||
* @param prefix prefix for the account, the suffix will
|
|
||||||
* be determined by the name of the plugin
|
|
||||||
* @return JSON array with the supported validation methods
|
* @return JSON array with the supported validation methods
|
||||||
*/
|
*/
|
||||||
json_t *
|
json_t *
|
||||||
TEH_VALIDATION_get_wire_methods (const char *prefix)
|
TEH_VALIDATION_get_wire_methods ()
|
||||||
{
|
{
|
||||||
json_t *methods;
|
json_t *methods;
|
||||||
char *account_name;
|
char *account_name;
|
||||||
@ -227,8 +225,7 @@ TEH_VALIDATION_get_wire_methods (const char *prefix)
|
|||||||
json_t *fees;
|
json_t *fees;
|
||||||
|
|
||||||
GNUNET_asprintf (&account_name,
|
GNUNET_asprintf (&account_name,
|
||||||
"%s-%s",
|
"exchange-wire-%s",
|
||||||
prefix,
|
|
||||||
p->type);
|
p->type);
|
||||||
method = plugin->get_wire_details (plugin->cls,
|
method = plugin->get_wire_details (plugin->cls,
|
||||||
cfg,
|
cfg,
|
||||||
|
@ -61,12 +61,10 @@ TEH_json_validate_wireformat (const json_t *wire,
|
|||||||
* Obtain JSON of the supported wire methods for a given
|
* Obtain JSON of the supported wire methods for a given
|
||||||
* account name prefix.
|
* account name prefix.
|
||||||
*
|
*
|
||||||
* @param prefix prefix for the account, the suffix will
|
|
||||||
* be determined by the name of the plugin
|
|
||||||
* @return JSON array with the supported validation methods
|
* @return JSON array with the supported validation methods
|
||||||
*/
|
*/
|
||||||
json_t *
|
json_t *
|
||||||
TEH_VALIDATION_get_wire_methods (const char *prefix);
|
TEH_VALIDATION_get_wire_methods (void);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -143,7 +143,7 @@ TEH_WIRE_handler_wire (struct TEH_RequestHandler *rh,
|
|||||||
int
|
int
|
||||||
TEH_WIRE_init ()
|
TEH_WIRE_init ()
|
||||||
{
|
{
|
||||||
wire_methods = TEH_VALIDATION_get_wire_methods ("exchange-wire-incoming");
|
wire_methods = TEH_VALIDATION_get_wire_methods ();
|
||||||
if ( (NULL == wire_methods) ||
|
if ( (NULL == wire_methods) ||
|
||||||
(0 == json_object_size (wire_methods)) )
|
(0 == json_object_size (wire_methods)) )
|
||||||
{
|
{
|
||||||
|
@ -63,7 +63,6 @@ CLOSING-FEE-2025 = EUR:0.01
|
|||||||
CLOSING-FEE-2026 = EUR:0.01
|
CLOSING-FEE-2026 = EUR:0.01
|
||||||
|
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
|
||||||
# What is the main website of the bank?
|
# What is the main website of the bank?
|
||||||
BANK_URI = "http://localhost:8082/"
|
BANK_URI = "http://localhost:8082/"
|
||||||
|
|
||||||
|
@ -36,7 +36,6 @@ DB_CONN_STR = "postgres:///talercheck"
|
|||||||
# Enable 'test' for testing of the actual coin operations.
|
# Enable 'test' for testing of the actual coin operations.
|
||||||
ENABLE = YES
|
ENABLE = YES
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
|
||||||
# What is the main website of the bank?
|
# What is the main website of the bank?
|
||||||
BANK_URI = "http://localhost:8082/"
|
BANK_URI = "http://localhost:8082/"
|
||||||
|
|
||||||
|
@ -150,10 +150,15 @@ TALER_BANK_admin_add_incoming_cancel (struct TALER_BANK_AdminAddIncomingHandle *
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which types of transactions should be returned?
|
* Which types of transactions should be (or is being) returned?
|
||||||
*/
|
*/
|
||||||
enum TALER_BANK_Direction {
|
enum TALER_BANK_Direction {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base case, used to indicate errors or end of list.
|
||||||
|
*/
|
||||||
|
TALER_BANK_DIRECTION_NONE = 0,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transactions where the bank account receives money.
|
* Transactions where the bank account receives money.
|
||||||
*/
|
*/
|
||||||
@ -192,15 +197,10 @@ struct TALER_BANK_TransferDetails
|
|||||||
*/
|
*/
|
||||||
struct GNUNET_TIME_Absolute execution_date;
|
struct GNUNET_TIME_Absolute execution_date;
|
||||||
|
|
||||||
/**
|
|
||||||
* monotonically increasing counter corresponding to the transaction
|
|
||||||
*/
|
|
||||||
uint64_t serial_id;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* wire transfer subject
|
* wire transfer subject
|
||||||
*/
|
*/
|
||||||
char *wire_transfer_subject;
|
const char *wire_transfer_subject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* what was the other account that was involved
|
* what was the other account that was involved
|
||||||
@ -220,6 +220,7 @@ struct TALER_BANK_TransferDetails
|
|||||||
* last callback is always of this status (even if `abs(num_results)` were
|
* last callback is always of this status (even if `abs(num_results)` were
|
||||||
* already returned).
|
* already returned).
|
||||||
* @param dir direction of the transfer
|
* @param dir direction of the transfer
|
||||||
|
* @param serial_id monotonically increasing counter corresponding to the transaction
|
||||||
* @param details details about the wire transfer
|
* @param details details about the wire transfer
|
||||||
* @param json detailed response from the HTTPD, or NULL if reply was not in JSON
|
* @param json detailed response from the HTTPD, or NULL if reply was not in JSON
|
||||||
*/
|
*/
|
||||||
@ -227,22 +228,20 @@ typedef void
|
|||||||
(*TALER_BANK_HistoryResultCallback) (void *cls,
|
(*TALER_BANK_HistoryResultCallback) (void *cls,
|
||||||
unsigned int http_status,
|
unsigned int http_status,
|
||||||
enum TALER_BANK_Direction dir,
|
enum TALER_BANK_Direction dir,
|
||||||
|
uint64_t serial_id,
|
||||||
const struct TALER_BANK_TransferDetails *details,
|
const struct TALER_BANK_TransferDetails *details,
|
||||||
const json_t *json);
|
const json_t *json);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notify the bank that we have received an incoming transaction
|
* Request the wire transfer history of a bank account.
|
||||||
* which fills a reserve. Note that this API is an administrative
|
|
||||||
* API and thus not accessible to typical bank clients, but only
|
|
||||||
* to the operators of the bank.
|
|
||||||
*
|
*
|
||||||
* @param ctx curl context for the event loop
|
* @param ctx curl context for the event loop
|
||||||
* @param bank_base_url URL of the bank (used to execute this request)
|
* @param bank_base_url URL of the bank (used to execute this request)
|
||||||
* @param auth authentication data to use
|
* @param auth authentication data to use
|
||||||
* @param account_number which account number should we query
|
* @param account_number which account number should we query
|
||||||
* @param direction what kinds of wire transfers should be returned
|
* @param direction what kinds of wire transfers should be returned
|
||||||
* @param start_row from which row on do we want to get results, use UINT64_MAX for the latest
|
* @param start_row from which row on do we want to get results, use UINT64_MAX for the latest; exclusive
|
||||||
* @param num_results how many results do we want; negative numbers to go into the past,
|
* @param num_results how many results do we want; negative numbers to go into the past,
|
||||||
* positive numbers to go into the future starting at @a start_row;
|
* positive numbers to go into the future starting at @a start_row;
|
||||||
* must not be zero.
|
* must not be zero.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of TALER
|
This file is part of TALER
|
||||||
Copyright (C) 2016 GNUnet e.V.
|
Copyright (C) 2016, 2017 GNUnet e.V. & Inria
|
||||||
|
|
||||||
TALER is free software; you can redistribute it and/or modify it under the
|
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
|
terms of the GNU General Public License as published by the Free Software
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include <jansson.h>
|
#include <jansson.h>
|
||||||
#include "taler_util.h"
|
#include "taler_util.h"
|
||||||
#include "taler_error_codes.h"
|
#include "taler_error_codes.h"
|
||||||
|
#include "taler_bank_service.h" /* for `enum TALER_BANK_Direction` and `struct TALER_BANK_TransferDetails` */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,17 +41,47 @@ typedef void
|
|||||||
size_t buf_size);
|
size_t buf_size);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callbacks of this type are used to serve the result of asking
|
||||||
|
* the bank for the 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 dir direction of the transfer
|
||||||
|
* @param row_off identification of the position at which we are querying
|
||||||
|
* @param row_off_size number of bytes in @a row_off
|
||||||
|
* @param details details about the wire transfer
|
||||||
|
* @param json detailed response from the HTTPD, or NULL if reply was not in JSON
|
||||||
|
*/
|
||||||
|
typedef void
|
||||||
|
(*TALER_WIRE_HistoryResultCallback) (void *cls,
|
||||||
|
unsigned int http_status,
|
||||||
|
enum TALER_BANK_Direction dir,
|
||||||
|
const void *row_off,
|
||||||
|
size_t row_off_size,
|
||||||
|
const struct TALER_BANK_TransferDetails *details,
|
||||||
|
const json_t *json);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle returned for cancelling a preparation step.
|
* Handle returned for cancelling a preparation step.
|
||||||
*/
|
*/
|
||||||
struct TALER_WIRE_PrepareHandle;
|
struct TALER_WIRE_PrepareHandle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle returned for cancelling an execution step.
|
* Handle returned for cancelling an execution step.
|
||||||
*/
|
*/
|
||||||
struct TALER_WIRE_ExecuteHandle;
|
struct TALER_WIRE_ExecuteHandle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle returned for querying the transaction history.
|
||||||
|
*/
|
||||||
|
struct TALER_WIRE_HistoryHandle;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function called with the result from the execute step.
|
* Function called with the result from the execute step.
|
||||||
@ -217,6 +248,43 @@ struct TALER_WIRE_Plugin
|
|||||||
struct TALER_WIRE_ExecuteHandle *eh);
|
struct TALER_WIRE_ExecuteHandle *eh);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query transfer history of an account. We use the variable-size
|
||||||
|
* @a start_off to indicate which transfers we are interested in as
|
||||||
|
* different banking systems may have different ways to identify
|
||||||
|
* transfers. The @a start_off value must thus match the value of
|
||||||
|
* a `row_off` argument previously given to the @a hres_cb. Use
|
||||||
|
* NULL to query transfers from the beginning of time (with
|
||||||
|
* positive @a num_results) or from the latest committed transfers
|
||||||
|
* (with negative @a num_results).
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param direction what kinds of wire transfers should be returned
|
||||||
|
* @param start_off from which row on do we want to get results, use NULL for the latest; exclusive
|
||||||
|
* @param start_off_len number of bytes in @a start_off
|
||||||
|
* @param num_results how many results do we want; negative numbers to go into the past,
|
||||||
|
* positive numbers to go into the future starting at @a start_row;
|
||||||
|
* must not be zero.
|
||||||
|
* @param hres_cb the callback to call with the transaction history
|
||||||
|
* @param hres_cb_cls closure for the above callback
|
||||||
|
*/
|
||||||
|
struct TALER_WIRE_HistoryHandle *
|
||||||
|
(*get_history) (void *cls,
|
||||||
|
enum TALER_BANK_Direction direction,
|
||||||
|
const void *start_off,
|
||||||
|
size_t start_off_len,
|
||||||
|
int64_t num_results,
|
||||||
|
TALER_WIRE_HistoryResultCallback hres_cb,
|
||||||
|
void *hres_cb_cls);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel going over the account's history.
|
||||||
|
*
|
||||||
|
* @param whh operation to cancel
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
(*get_history_cancel) (struct TALER_WIRE_HistoryHandle *whh);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -735,6 +735,52 @@ sepa_execute_wire_transfer_cancel (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query transfer history of an account. We use the variable-size
|
||||||
|
* @a start_off to indicate which transfers we are interested in as
|
||||||
|
* different banking systems may have different ways to identify
|
||||||
|
* transfers. The @a start_off value must thus match the value of
|
||||||
|
* a `row_off` argument previously given to the @a hres_cb. Use
|
||||||
|
* NULL to query transfers from the beginning of time (with
|
||||||
|
* positive @a num_results) or from the latest committed transfers
|
||||||
|
* (with negative @a num_results).
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param direction what kinds of wire transfers should be returned
|
||||||
|
* @param start_off from which row on do we want to get results, use NULL for the latest; exclusive
|
||||||
|
* @param start_off_len number of bytes in @a start_off; must be `sizeof(uint64_t)`.
|
||||||
|
* @param num_results how many results do we want; negative numbers to go into the past,
|
||||||
|
* positive numbers to go into the future starting at @a start_row;
|
||||||
|
* must not be zero.
|
||||||
|
* @param hres_cb the callback to call with the transaction history
|
||||||
|
* @param hres_cb_cls closure for the above callback
|
||||||
|
*/
|
||||||
|
static struct TALER_WIRE_HistoryHandle *
|
||||||
|
sepa_get_history (void *cls,
|
||||||
|
enum TALER_BANK_Direction direction,
|
||||||
|
const void *start_off,
|
||||||
|
size_t start_off_len,
|
||||||
|
int64_t num_results,
|
||||||
|
TALER_WIRE_HistoryResultCallback hres_cb,
|
||||||
|
void *hres_cb_cls)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel going over the account's history.
|
||||||
|
*
|
||||||
|
* @param whh operation to cancel
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sepa_get_history_cancel (struct TALER_WIRE_HistoryHandle *whh)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize sepa-wire subsystem.
|
* Initialize sepa-wire subsystem.
|
||||||
*
|
*
|
||||||
@ -774,6 +820,8 @@ libtaler_plugin_wire_sepa_init (void *cls)
|
|||||||
plugin->prepare_wire_transfer_cancel = &sepa_prepare_wire_transfer_cancel;
|
plugin->prepare_wire_transfer_cancel = &sepa_prepare_wire_transfer_cancel;
|
||||||
plugin->execute_wire_transfer = &sepa_execute_wire_transfer;
|
plugin->execute_wire_transfer = &sepa_execute_wire_transfer;
|
||||||
plugin->execute_wire_transfer_cancel = &sepa_execute_wire_transfer_cancel;
|
plugin->execute_wire_transfer_cancel = &sepa_execute_wire_transfer_cancel;
|
||||||
|
plugin->get_history = &sepa_get_history;
|
||||||
|
plugin->get_history_cancel = &sepa_get_history_cancel;
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,6 +219,52 @@ template_execute_wire_transfer_cancel (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query transfer history of an account. We use the variable-size
|
||||||
|
* @a start_off to indicate which transfers we are interested in as
|
||||||
|
* different banking systems may have different ways to identify
|
||||||
|
* transfers. The @a start_off value must thus match the value of
|
||||||
|
* a `row_off` argument previously given to the @a hres_cb. Use
|
||||||
|
* NULL to query transfers from the beginning of time (with
|
||||||
|
* positive @a num_results) or from the latest committed transfers
|
||||||
|
* (with negative @a num_results).
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param direction what kinds of wire transfers should be returned
|
||||||
|
* @param start_off from which row on do we want to get results, use NULL for the latest; exclusive
|
||||||
|
* @param start_off_len number of bytes in @a start_off; must be `sizeof(uint64_t)`.
|
||||||
|
* @param num_results how many results do we want; negative numbers to go into the past,
|
||||||
|
* positive numbers to go into the future starting at @a start_row;
|
||||||
|
* must not be zero.
|
||||||
|
* @param hres_cb the callback to call with the transaction history
|
||||||
|
* @param hres_cb_cls closure for the above callback
|
||||||
|
*/
|
||||||
|
static struct TALER_WIRE_HistoryHandle *
|
||||||
|
template_get_history (void *cls,
|
||||||
|
enum TALER_BANK_Direction direction,
|
||||||
|
const void *start_off,
|
||||||
|
size_t start_off_len,
|
||||||
|
int64_t num_results,
|
||||||
|
TALER_WIRE_HistoryResultCallback hres_cb,
|
||||||
|
void *hres_cb_cls)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel going over the account's history.
|
||||||
|
*
|
||||||
|
* @param whh operation to cancel
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
template_get_history_cancel (struct TALER_WIRE_HistoryHandle *whh)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize template-wire subsystem.
|
* Initialize template-wire subsystem.
|
||||||
*
|
*
|
||||||
@ -270,6 +316,8 @@ libtaler_plugin_wire_template_init (void *cls)
|
|||||||
plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel;
|
plugin->prepare_wire_transfer_cancel = &template_prepare_wire_transfer_cancel;
|
||||||
plugin->execute_wire_transfer = &template_execute_wire_transfer;
|
plugin->execute_wire_transfer = &template_execute_wire_transfer;
|
||||||
plugin->execute_wire_transfer_cancel = &template_execute_wire_transfer_cancel;
|
plugin->execute_wire_transfer_cancel = &template_execute_wire_transfer_cancel;
|
||||||
|
plugin->get_history = &template_get_history;
|
||||||
|
plugin->get_history_cancel = &template_get_history_cancel;
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,9 +62,9 @@ struct TestClosure
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of the account that the exchange has at the bank for
|
* Number of the account that the exchange has at the bank for
|
||||||
* outgoing transfers.
|
* transfers.
|
||||||
*/
|
*/
|
||||||
unsigned long long exchange_account_outgoing_no;
|
unsigned long long exchange_account_no;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -731,7 +731,7 @@ test_execute_wire_transfer (void *cls,
|
|||||||
exchange_base_url,
|
exchange_base_url,
|
||||||
&bf.wtid,
|
&bf.wtid,
|
||||||
&amount,
|
&amount,
|
||||||
(uint64_t) tc->exchange_account_outgoing_no,
|
(uint64_t) tc->exchange_account_no,
|
||||||
(uint64_t) account_no,
|
(uint64_t) account_no,
|
||||||
&execute_cb,
|
&execute_cb,
|
||||||
eh);
|
eh);
|
||||||
@ -767,6 +767,166 @@ test_execute_wire_transfer_cancel (void *cls,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle for a #test_get_history() request.
|
||||||
|
*/
|
||||||
|
struct TALER_WIRE_HistoryHandle
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to call with results.
|
||||||
|
*/
|
||||||
|
TALER_WIRE_HistoryResultCallback hres_cb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closure for @e hres_cb.
|
||||||
|
*/
|
||||||
|
void *hres_cb_cls;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request to the bank.
|
||||||
|
*/
|
||||||
|
struct TALER_BANK_HistoryHandle *hh;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called with results from the bank about the transaction history.
|
||||||
|
*
|
||||||
|
* @param cls the `struct TALER_WIRE_HistoryHandle`
|
||||||
|
* @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 dir direction of the transfer
|
||||||
|
* @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
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
bhist_cb (void *cls,
|
||||||
|
unsigned int http_status,
|
||||||
|
enum TALER_BANK_Direction dir,
|
||||||
|
uint64_t serial_id,
|
||||||
|
const struct TALER_BANK_TransferDetails *details,
|
||||||
|
const json_t *json)
|
||||||
|
{
|
||||||
|
struct TALER_WIRE_HistoryHandle *whh = cls;
|
||||||
|
uint64_t bserial_id = GNUNET_htonll (serial_id);
|
||||||
|
|
||||||
|
whh->hres_cb (whh->hres_cb_cls,
|
||||||
|
http_status,
|
||||||
|
dir,
|
||||||
|
&bserial_id,
|
||||||
|
sizeof (bserial_id),
|
||||||
|
details,
|
||||||
|
json);
|
||||||
|
if (MHD_HTTP_OK != http_status)
|
||||||
|
{
|
||||||
|
whh->hh = NULL;
|
||||||
|
GNUNET_free (whh);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query transfer history of an account. We use the variable-size
|
||||||
|
* @a start_off to indicate which transfers we are interested in as
|
||||||
|
* different banking systems may have different ways to identify
|
||||||
|
* transfers. The @a start_off value must thus match the value of
|
||||||
|
* a `row_off` argument previously given to the @a hres_cb. Use
|
||||||
|
* NULL to query transfers from the beginning of time (with
|
||||||
|
* positive @a num_results) or from the latest committed transfers
|
||||||
|
* (with negative @a num_results).
|
||||||
|
*
|
||||||
|
* @param cls the @e cls of this struct with the plugin-specific state
|
||||||
|
* @param direction what kinds of wire transfers should be returned
|
||||||
|
* @param start_off from which row on do we want to get results, use NULL for the latest; exclusive
|
||||||
|
* @param start_off_len number of bytes in @a start_off; must be `sizeof(uint64_t)`.
|
||||||
|
* @param num_results how many results do we want; negative numbers to go into the past,
|
||||||
|
* positive numbers to go into the future starting at @a start_row;
|
||||||
|
* must not be zero.
|
||||||
|
* @param hres_cb the callback to call with the transaction history
|
||||||
|
* @param hres_cb_cls closure for the above callback
|
||||||
|
*/
|
||||||
|
static struct TALER_WIRE_HistoryHandle *
|
||||||
|
test_get_history (void *cls,
|
||||||
|
enum TALER_BANK_Direction direction,
|
||||||
|
const void *start_off,
|
||||||
|
size_t start_off_len,
|
||||||
|
int64_t num_results,
|
||||||
|
TALER_WIRE_HistoryResultCallback hres_cb,
|
||||||
|
void *hres_cb_cls)
|
||||||
|
{
|
||||||
|
struct TestClosure *tc = cls;
|
||||||
|
struct TALER_WIRE_HistoryHandle *whh;
|
||||||
|
const uint64_t *start_off_b64;
|
||||||
|
uint64_t start_row;
|
||||||
|
|
||||||
|
if (0 == num_results)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (TALER_BANK_DIRECTION_NONE == direction)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if ( (NULL != start_off) &&
|
||||||
|
(sizeof (uint64_t) != start_off_len) )
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (NULL == start_off)
|
||||||
|
{
|
||||||
|
start_row = (num_results > 0) ? 0 : UINT64_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
start_off_b64 = start_off;
|
||||||
|
start_row = GNUNET_ntohll (*start_off_b64);
|
||||||
|
}
|
||||||
|
|
||||||
|
whh = GNUNET_new (struct TALER_WIRE_HistoryHandle);
|
||||||
|
whh->hres_cb = hres_cb;
|
||||||
|
whh->hres_cb_cls = hres_cb_cls;
|
||||||
|
whh->hh = TALER_BANK_history (tc->ctx,
|
||||||
|
tc->bank_uri,
|
||||||
|
&tc->auth,
|
||||||
|
(uint64_t) tc->exchange_account_no,
|
||||||
|
direction,
|
||||||
|
start_row,
|
||||||
|
num_results,
|
||||||
|
&bhist_cb,
|
||||||
|
whh);
|
||||||
|
if (NULL == whh->hh)
|
||||||
|
{
|
||||||
|
GNUNET_break (0);
|
||||||
|
GNUNET_free (whh);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return whh;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel going over the account's history.
|
||||||
|
*
|
||||||
|
* @param whh operation to cancel
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
test_get_history_cancel (struct TALER_WIRE_HistoryHandle *whh)
|
||||||
|
{
|
||||||
|
TALER_BANK_history_cancel (whh->hh);
|
||||||
|
GNUNET_free (whh);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize test-wire subsystem.
|
* Initialize test-wire subsystem.
|
||||||
*
|
*
|
||||||
@ -787,24 +947,24 @@ libtaler_plugin_wire_test_init (void *cls)
|
|||||||
{
|
{
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"BANK_URI",
|
"BANK_URI",
|
||||||
&tc->bank_uri))
|
&tc->bank_uri))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"BANK_URI");
|
"BANK_URI");
|
||||||
GNUNET_free (tc);
|
GNUNET_free (tc);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_number (cfg,
|
GNUNET_CONFIGURATION_get_value_number (cfg,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"EXCHANGE_ACCOUNT_NUMBER",
|
"EXCHANGE_ACCOUNT_NUMBER",
|
||||||
&tc->exchange_account_outgoing_no))
|
&tc->exchange_account_no))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"EXCHANGE_ACCOUNT_NUMBER");
|
"EXCHANGE_ACCOUNT_NUMBER");
|
||||||
GNUNET_free (tc->bank_uri);
|
GNUNET_free (tc->bank_uri);
|
||||||
GNUNET_free (tc);
|
GNUNET_free (tc);
|
||||||
@ -825,12 +985,12 @@ libtaler_plugin_wire_test_init (void *cls)
|
|||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"USERNAME",
|
"USERNAME",
|
||||||
&user))
|
&user))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"USERNAME");
|
"USERNAME");
|
||||||
GNUNET_free (tc->bank_uri);
|
GNUNET_free (tc->bank_uri);
|
||||||
GNUNET_free (tc);
|
GNUNET_free (tc);
|
||||||
@ -838,12 +998,12 @@ libtaler_plugin_wire_test_init (void *cls)
|
|||||||
}
|
}
|
||||||
if (GNUNET_OK !=
|
if (GNUNET_OK !=
|
||||||
GNUNET_CONFIGURATION_get_value_string (cfg,
|
GNUNET_CONFIGURATION_get_value_string (cfg,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"PASSWORD",
|
"PASSWORD",
|
||||||
&pass))
|
&pass))
|
||||||
{
|
{
|
||||||
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR,
|
||||||
"exchange-wire-outgoing-test",
|
"exchange-wire-test",
|
||||||
"PASSWORD");
|
"PASSWORD");
|
||||||
GNUNET_free (tc->bank_uri);
|
GNUNET_free (tc->bank_uri);
|
||||||
GNUNET_free (tc);
|
GNUNET_free (tc);
|
||||||
@ -877,6 +1037,8 @@ libtaler_plugin_wire_test_init (void *cls)
|
|||||||
plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel;
|
plugin->prepare_wire_transfer_cancel = &test_prepare_wire_transfer_cancel;
|
||||||
plugin->execute_wire_transfer = &test_execute_wire_transfer;
|
plugin->execute_wire_transfer = &test_execute_wire_transfer;
|
||||||
plugin->execute_wire_transfer_cancel = &test_execute_wire_transfer_cancel;
|
plugin->execute_wire_transfer_cancel = &test_execute_wire_transfer_cancel;
|
||||||
|
plugin->get_history = &test_get_history;
|
||||||
|
plugin->get_history_cancel = &test_get_history_cancel;
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ TEST_RESPONSE_FILE = test_wire_plugin_test.json
|
|||||||
SEPA_RESPONSE_FILE = test_wire_plugin_sepa.json
|
SEPA_RESPONSE_FILE = test_wire_plugin_sepa.json
|
||||||
|
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
[exchange-wire-test]
|
||||||
# For transfers made by the exchange, we need to know
|
# For transfers made by the exchange, we need to know
|
||||||
# the URI of the bank (where the /admin/add/incoming API
|
# the URI of the bank (where the /admin/add/incoming API
|
||||||
# is avaialble).
|
# is avaialble).
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
# Set to "YES" to activate the 'sepa' plugin.
|
# Set to "YES" to activate the 'sepa' plugin.
|
||||||
ENABLE = NO
|
ENABLE = NO
|
||||||
|
|
||||||
[exchange-wire-incoming-sepa]
|
|
||||||
# This is the response we give out for the /wire request. It provides
|
# This is the response we give out for the /wire request. It provides
|
||||||
# wallets with the bank information for transfers to the exchange.
|
# wallets with the bank information for transfers to the exchange.
|
||||||
SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/exchange/wire/sepa.json
|
SEPA_RESPONSE_FILE = ${TALER_CONFIG_HOME}/exchange/wire/sepa.json
|
||||||
|
@ -6,19 +6,15 @@
|
|||||||
# Set to "YES" to activate the 'test' plugin.
|
# Set to "YES" to activate the 'test' plugin.
|
||||||
ENABLE = NO
|
ENABLE = NO
|
||||||
|
|
||||||
[exchange-wire-incoming-test]
|
|
||||||
# This is the response we give out for the /wire request. It provides
|
# This is the response we give out for the /wire request. It provides
|
||||||
# wallets with the bank information for transfers to the exchange.
|
# wallets with the bank information for transfers to the exchange.
|
||||||
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/exchange/wire/test.json
|
TEST_RESPONSE_FILE = ${TALER_CONFIG_HOME}/exchange/wire/test.json
|
||||||
|
|
||||||
[exchange-wire-outgoing-test]
|
# We need to know the exchange's account number at the bank.
|
||||||
# For outgoing transfers, we need to know the exchange's
|
|
||||||
# account number at the bank.
|
|
||||||
EXCHANGE_ACCOUNT_NUMBER = 2
|
EXCHANGE_ACCOUNT_NUMBER = 2
|
||||||
|
|
||||||
# For transfers made by the exchange, we need to know
|
# For accessing transfers, we need to know
|
||||||
# the URI of the bank (where the /admin/add/incoming API
|
# the URI of the bank (where the /history API is available).
|
||||||
# is avaialble).
|
|
||||||
# BANK_URI = https://bank.demo.taler.net/
|
# BANK_URI = https://bank.demo.taler.net/
|
||||||
|
|
||||||
# Authentication information for basic authentication
|
# Authentication information for basic authentication
|
||||||
|
Loading…
Reference in New Issue
Block a user