/* This file is part of TALER Copyright (C) 2015-2020 Taler Systems SA TALER is free software; you can redistribute it and/or modify it under the terms of the GNU Affero 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 Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with TALER; see the file COPYING. If not, see */ /** * @file include/taler_bank_service.h * @brief C interface of libtalerbank, a C library to use the Taler Wire gateway HTTP API * See https://docs.taler.net/core/api-wire.html * @author Christian Grothoff */ #ifndef _TALER_BANK_SERVICE_H #define _TALER_BANK_SERVICE_H #include #include #include "taler_util.h" #include "taler_error_codes.h" /** * Authentication method types. */ enum TALER_BANK_AuthenticationMethod { /** * No authentication. */ TALER_BANK_AUTH_NONE, /** * Basic authentication with cleartext username and password. */ TALER_BANK_AUTH_BASIC, }; /** * Information used to authenticate to the bank. */ struct TALER_BANK_AuthenticationData { /** * Base URL we use to talk to the wire gateway, * which talks to the bank for us. */ char *wire_gateway_url; /** * Which authentication method should we use? */ enum TALER_BANK_AuthenticationMethod method; /** * Further details as per @e method. */ union { /** * Details for #TALER_BANK_AUTH_BASIC. */ struct { /** * Username to use. */ char *username; /** * Password to use. */ char *password; } basic; } details; }; /* ********************* /admin/add-incoming *********************** */ /** * @brief A /admin/add-incoming Handle */ struct TALER_BANK_AdminAddIncomingHandle; /** * Callbacks of this type are used to return the result of submitting * a request to transfer funds to the exchange. * * @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 * @param timestamp time when the transaction was made. * @param json detailed response from the HTTPD, or NULL if reply was not in JSON */ typedef void (*TALER_BANK_AdminAddIncomingCallback) (void *cls, unsigned int http_status, enum TALER_ErrorCode ec, uint64_t serial_id, struct GNUNET_TIME_Absolute timestamp, const json_t *json); /** * Perform a wire transfer from some account to the exchange to fill a * reserve. Note that this API is usually only used for testing (with * fakebank and our Python bank) and thus may not be accessible in a * production setting. * * @param ctx curl context for the event loop * @param auth authentication data to send to the bank * @param reserve_pub wire transfer subject for the transfer * @param amount amount that is to be deposited * @param debit_account account to deposit from (payto URI, but used as 'payfrom') * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for the above callback * @return NULL * if the inputs are invalid (i.e. invalid amount) or internal errors. * In this case, the callback is not called. */ struct TALER_BANK_AdminAddIncomingHandle * TALER_BANK_admin_add_incoming ( struct GNUNET_CURL_Context *ctx, const struct TALER_BANK_AuthenticationData *auth, const struct TALER_ReservePublicKeyP *reserve_pub, const struct TALER_Amount *amount, const char *debit_account, TALER_BANK_AdminAddIncomingCallback res_cb, void *res_cb_cls); /** * Cancel an add incoming operation. This function cannot be used on a * request handle if a response is already served for it. * * @param aai the admin add incoming request handle */ void TALER_BANK_admin_add_incoming_cancel ( struct TALER_BANK_AdminAddIncomingHandle *aai); /* ********************* /transfer *********************** */ /** * Prepare for execution of a wire transfer from the exchange to some * merchant. * * @param destination_account_payto_uri payto:// URL identifying where to send the money * @param amount amount to transfer, already rounded * @param exchange_base_url base URL of this exchange (included in subject * to facilitate use of tracking API by merchant backend) * @param wtid wire transfer identifier to use * @param[out] buf set to transaction data to persist, NULL on error * @param[out] buf_size set to number of bytes in @a buf, 0 on error */ void TALER_BANK_prepare_transfer ( const char *destination_account_payto_uri, const struct TALER_Amount *amount, const char *exchange_base_url, const struct TALER_WireTransferIdentifierRawP *wtid, void **buf, size_t *buf_size); /** * Handle for active wire transfer. */ struct TALER_BANK_TransferHandle; /** * Function called with the result from the execute step. * * @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 */ typedef void (*TALER_BANK_TransferCallback)(void *cls, unsigned int response_code, enum TALER_ErrorCode ec, uint64_t row_id, struct GNUNET_TIME_Absolute timestamp); /** * Execute a wire transfer from the exchange to some merchant. * * @param ctx context for HTTP interaction * @param auth authentication data to authenticate with the bank * @param buf buffer with the prepared execution details * @param buf_size number of bytes in @a buf * @param cc function to call upon success * @param cc_cls closure for @a cc * @return NULL on error */ struct TALER_BANK_TransferHandle * TALER_BANK_transfer (struct GNUNET_CURL_Context *ctx, const struct TALER_BANK_AuthenticationData *auth, const void *buf, size_t buf_size, TALER_BANK_TransferCallback cc, void *cc_cls); /** * Abort execution of a wire transfer. For example, because we are shutting * down. Note that if an execution is aborted, it may or may not still * succeed. * * The caller MUST run #TALER_BANK_transfer() again for the same request as * soon as possilbe, to ensure that the request either ultimately succeeds or * ultimately fails. Until this has been done, the transaction is in limbo * (i.e. may or may not have been committed). * * This function cannot be used on a request handle if a response is already * served for it. * * @param th handle of the wire transfer request to cancel */ void TALER_BANK_transfer_cancel (struct TALER_BANK_TransferHandle *th); /* ********************* /history/incoming *********************** */ /** * Handle for querying the bank for transactions * made to the exchange. */ struct TALER_BANK_CreditHistoryHandle; /** * Details about a wire transfer to the exchange. */ struct TALER_BANK_CreditDetails { /** * Amount that was transferred */ struct TALER_Amount amount; /** * Time of the the transfer */ struct GNUNET_TIME_Absolute execution_date; /** * Reserve public key encoded in the wire * transfer subject. */ struct TALER_ReservePublicKeyP reserve_pub; /** * payto://-URL of the source account that * send the funds. */ const char *debit_account_url; /** * payto://-URL of the target account that * received the funds. */ const char *credit_account_url; }; /** * Callbacks of this type are used to serve the result of asking * the bank for the credit 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 */ typedef int (*TALER_BANK_CreditHistoryCallback) ( void *cls, unsigned int http_status, enum TALER_ErrorCode ec, uint64_t serial_id, const struct TALER_BANK_CreditDetails *details, const json_t *json); /** * Request the wire credit history of an exchange's bank account. * * @param ctx curl context for the event loop * @param auth authentication data to use * @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_CreditHistoryHandle * TALER_BANK_credit_history (struct GNUNET_CURL_Context *ctx, const struct TALER_BANK_AuthenticationData *auth, uint64_t start_row, int64_t num_results, TALER_BANK_CreditHistoryCallback hres_cb, void *hres_cb_cls); /** * Cancel an history request. This function cannot be used on a request * handle if the last response (anything with a status code other than * 200) is already served for it. * * @param hh the history request handle */ void TALER_BANK_credit_history_cancel (struct TALER_BANK_CreditHistoryHandle *hh); /* ********************* /history/outgoing *********************** */ /** * Handle for querying the bank for transactions * made from the exchange to merchants. */ struct TALER_BANK_DebitHistoryHandle; /** * Details about a wire transfer made by the exchange * to a merchant. */ struct TALER_BANK_DebitDetails { /** * Amount that was transferred */ struct TALER_Amount amount; /** * Time of the the transfer */ struct GNUNET_TIME_Absolute execution_date; /** * Wire transfer identifier used by the exchange. */ struct TALER_WireTransferIdentifierRawP wtid; /** * Exchange's base URL as given in the wire transfer. */ const char *exchange_base_url; /** * payto://-URL of the source account that * send the funds. */ const char *debit_account_url; /** * payto://-URL of the target account that * received the funds. */ const char *credit_account_url; }; /** * Callbacks of this type are used to serve the result of asking * the bank for the 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 */ typedef int (*TALER_BANK_DebitHistoryCallback) ( void *cls, unsigned int http_status, enum TALER_ErrorCode ec, uint64_t serial_id, const struct TALER_BANK_DebitDetails *details, const json_t *json); /** * Request the wire credit history of an exchange's bank account. * * @param ctx curl context for the event loop * @param auth authentication data to use * @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_DebitHistoryHandle * TALER_BANK_debit_history (struct GNUNET_CURL_Context *ctx, const struct TALER_BANK_AuthenticationData *auth, uint64_t start_row, int64_t num_results, TALER_BANK_DebitHistoryCallback hres_cb, void *hres_cb_cls); /** * Cancel an history request. This function cannot be used on a request * handle if the last response (anything with a status code other than * 200) is already served for it. * * @param hh the history request handle */ void TALER_BANK_debit_history_cancel (struct TALER_BANK_DebitHistoryHandle *hh); /* ******************** Convenience functions **************** */ /** * Convenience method for parsing configuration section with bank * authentication data. * * @param cfg configuration to parse * @param section the section with the configuration data * @param[out] auth set to the configuration data found * @return #GNUNET_OK on success */ int TALER_BANK_auth_parse_cfg (const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, struct TALER_BANK_AuthenticationData *auth); /** * Free memory inside of @a auth (but not @a auth itself). * Dual to #TALER_BANK_auth_parse_cfg(). * * @param auth authentication data to free */ void TALER_BANK_auth_free (struct TALER_BANK_AuthenticationData *auth); #endif /* _TALER_BANK_SERVICE_H */