diff options
Diffstat (limited to 'src/include/taler_exchange_service.h')
-rw-r--r-- | src/include/taler_exchange_service.h | 4066 |
1 files changed, 3132 insertions, 934 deletions
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h index e14f01ca2..0597799b5 100644 --- a/src/include/taler_exchange_service.h +++ b/src/include/taler_exchange_service.h @@ -1,6 +1,6 @@ /* This file is part of TALER - Copyright (C) 2014-2022 Taler Systems SA + Copyright (C) 2014-2024 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 @@ -16,8 +16,11 @@ /** * @file include/taler_exchange_service.h * @brief C interface of libtalerexchange, a C library to use exchange's HTTP API + * This library is not thread-safe, all APIs must only be used from a single thread. + * This library calls abort() if it runs out of memory. Be aware of these limitations. * @author Sree Harsha Totakura <sreeharsha@totakura.in> * @author Christian Grothoff + * @author Özgür Kesim */ #ifndef _TALER_EXCHANGE_SERVICE_H #define _TALER_EXCHANGE_SERVICE_H @@ -25,31 +28,17 @@ #include <jansson.h> #include "taler_util.h" #include "taler_error_codes.h" +#include "taler_kyclogic_lib.h" #include <gnunet/gnunet_curl_lib.h> -/* ********************* /keys *********************** */ - /** - * List of possible options to be passed to - * #TALER_EXCHANGE_connect(). + * Version of the Taler Exchange API, in hex. + * Thus 0.8.4-1 = 0x00080401. */ -enum TALER_EXCHANGE_Option -{ - /** - * Terminator (end of option list). - */ - TALER_EXCHANGE_OPTION_END = 0, +#define TALER_EXCHANGE_API_VERSION 0x00100000 - /** - * Followed by a "const json_t *" that was previously returned for - * this exchange URL by #TALER_EXCHANGE_serialize_data(). Used to - * resume a connection to an exchange without having to re-download - * /keys data (or at least only download the deltas). - */ - TALER_EXCHANGE_OPTION_DATA - -}; +/* ********************* /keys *********************** */ /** @@ -140,10 +129,18 @@ struct TALER_EXCHANGE_DenomPublicKey struct TALER_DenomFeeSet fees; /** + * Set to true if the private denomination key has been + * lost by the exchange and thus the key cannot be + * used for withdrawing at this time. + */ + bool lost; + + /** * Set to true if this denomination key has been * revoked by the exchange. */ bool revoked; + }; @@ -230,11 +227,6 @@ struct TALER_EXCHANGE_GlobalFee struct GNUNET_TIME_Relative purse_timeout; /** - * Accounts without KYC will be closed after this time. - */ - struct GNUNET_TIME_Relative kyc_timeout; - - /** * Account history is limited to this timeframe. */ struct GNUNET_TIME_Relative history_expiration; @@ -253,6 +245,183 @@ struct TALER_EXCHANGE_GlobalFee /** + * List sorted by @a start_date with fees to be paid for aggregate wire transfers. + */ +struct TALER_EXCHANGE_WireAggregateFees +{ + /** + * This is a linked list. + */ + struct TALER_EXCHANGE_WireAggregateFees *next; + + /** + * Fee to be paid whenever the exchange wires funds to the merchant. + */ + struct TALER_WireFeeSet fees; + + /** + * Time when this fee goes into effect (inclusive) + */ + struct GNUNET_TIME_Timestamp start_date; + + /** + * Time when this fee stops being in effect (exclusive). + */ + struct GNUNET_TIME_Timestamp end_date; + + /** + * Signature affirming the above fee structure. + */ + struct TALER_MasterSignatureP master_sig; +}; + + +/** + * Information about wire fees by wire method. + */ +struct TALER_EXCHANGE_WireFeesByMethod +{ + /** + * Wire method with the given @e fees. + */ + char *method; + + /** + * Linked list of wire fees the exchange charges for + * accounts of the wire @e method. + */ + struct TALER_EXCHANGE_WireAggregateFees *fees_head; + +}; + + +/** + * Type of an account restriction. + */ +enum TALER_EXCHANGE_AccountRestrictionType +{ + /** + * Invalid restriction. + */ + TALER_EXCHANGE_AR_INVALID = 0, + + /** + * Account must not be used for this operation. + */ + TALER_EXCHANGE_AR_DENY = 1, + + /** + * Other account must match given regular expression. + */ + TALER_EXCHANGE_AR_REGEX = 2 +}; + +/** + * Restrictions that apply to using a given exchange bank account. + */ +struct TALER_EXCHANGE_AccountRestriction +{ + + /** + * Type of the account restriction. + */ + enum TALER_EXCHANGE_AccountRestrictionType type; + + /** + * Restriction details depending on @e type. + */ + union + { + /** + * Details if type is #TALER_EXCHANGE_AR_REGEX. + */ + struct + { + /** + * Regular expression that the payto://-URI of the partner account must + * follow. The regular expression should follow posix-egrep, but + * without support for character classes, GNU extensions, + * back-references or intervals. See + * https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html + * for a description of the posix-egrep syntax. Applications may support + * regexes with additional features, but exchanges must not use such + * regexes. + */ + char *posix_egrep; + + /** + * Hint for a human to understand the restriction. + */ + char *human_hint; + + /** + * Internationalizations for the @e human_hint. Map from IETF BCP 47 + * language tax to localized human hints. + */ + json_t *human_hint_i18n; + } regex; + } details; + +}; + + +/** + * Information about a wire account of the exchange. + */ +struct TALER_EXCHANGE_WireAccount +{ + /** + * payto://-URI of the exchange. + */ + char *payto_uri; + + /** + * URL of a conversion service in case using this account is subject to + * currency conversion. NULL for no conversion needed. + */ + char *conversion_url; + + /** + * Array of restrictions that apply when crediting + * this account. + */ + struct TALER_EXCHANGE_AccountRestriction *credit_restrictions; + + /** + * Array of restrictions that apply when debiting + * this account. + */ + struct TALER_EXCHANGE_AccountRestriction *debit_restrictions; + + /** + * Length of the @e credit_restrictions array. + */ + unsigned int credit_restrictions_length; + + /** + * Length of the @e debit_restrictions array. + */ + unsigned int debit_restrictions_length; + + /** + * Signature of the exchange over the account (was checked by the API). + */ + struct TALER_MasterSignatureP master_sig; + + /** + * Display label for the account, can be NULL. + */ + char *bank_label; + + /** + * Priority for ordering the account in the display. + */ + int64_t priority; + +}; + + +/** * @brief Information about keys from the exchange. */ struct TALER_EXCHANGE_Keys @@ -264,6 +433,11 @@ struct TALER_EXCHANGE_Keys struct TALER_MasterPublicKeyP master_pub; /** + * Signature over extension configuration data, if any. + */ + struct TALER_MasterSignatureP extensions_sig; + + /** * Array of the exchange's online signing keys. */ struct TALER_EXCHANGE_SigningPublicKey *sign_keys; @@ -284,6 +458,11 @@ struct TALER_EXCHANGE_Keys struct TALER_EXCHANGE_GlobalFee *global_fees; /** + * Configuration data for extensions. + */ + json_t *extensions; + + /** * Supported Taler protocol version by the exchange. * String in the format current:revision:age using the * semantics of GNU libtool. See @@ -297,6 +476,41 @@ struct TALER_EXCHANGE_Keys char *currency; /** + * What is the base URL of the exchange that returned + * these keys? + */ + char *exchange_url; + + /** + * Asset type used by the exchange. Typical values + * are "fiat" or "crypto" or "regional" or "stock". + * Wallets should adjust their UI/UX based on this + * value. + */ + char *asset_type; + + /** + * Array of amounts a wallet is allowed to hold from + * this exchange before it must undergo further KYC checks. + */ + struct TALER_Amount *wallet_balance_limit_without_kyc; + + /** + * Array of accounts of the exchange. + */ + struct TALER_EXCHANGE_WireAccount *accounts; + + /** + * Array of wire fees by wire method. + */ + struct TALER_EXCHANGE_WireFeesByMethod *fees; + + /** + * Currency rendering specification for this exchange. + */ + struct TALER_CurrencySpecification cspec; + + /** * How long after a reserve went idle will the exchange close it? * This is an approximate number, not cryptographically signed by * the exchange (advisory-only, may change anytime). @@ -304,15 +518,14 @@ struct TALER_EXCHANGE_Keys struct GNUNET_TIME_Relative reserve_closing_delay; /** - * Maximum amount a wallet is allowed to hold from - * this exchange before it must undergo a KYC check. + * Timestamp indicating the /keys generation. */ - struct TALER_Amount wallet_balance_limit_without_kyc; + struct GNUNET_TIME_Timestamp list_issue_date; /** - * Timestamp indicating the /keys generation. + * When does this keys data expire? */ - struct GNUNET_TIME_Timestamp list_issue_date; + struct GNUNET_TIME_Timestamp key_data_expiration; /** * Timestamp indicating the creation time of the last @@ -327,6 +540,37 @@ struct TALER_EXCHANGE_Keys struct TALER_AgeMask age_mask; /** + * Absolute STEFAN parameter. + */ + struct TALER_Amount stefan_abs; + + /** + * Logarithmic STEFAN parameter. + */ + struct TALER_Amount stefan_log; + + /** + * Linear STEFAN parameter. + */ + double stefan_lin; + + /** + * Length of @e accounts array. + */ + unsigned int accounts_len; + + /** + * Length of @e fees array. + */ + unsigned int fees_len; + + /** + * Length of the @e wallet_balance_limit_without_kyc + * array. + */ + unsigned int wblwk_length; + + /** * Length of the @e global_fees array. */ unsigned int num_global_fees; @@ -356,6 +600,16 @@ struct TALER_EXCHANGE_Keys */ unsigned int denom_keys_size; + /** + * Reference counter for this structure. + * Freed when it reaches 0. + */ + unsigned int rc; + + /** + * Set to true if rewards are allowed at this exchange. + */ + bool rewards_allowed; }; @@ -423,6 +677,7 @@ struct TALER_EXCHANGE_HttpResponse * reply (too big, invalid JSON). */ const json_t *reply; + /** * Set to the human-readable 'hint' that is optionally * provided by the exchange together with errors. NULL @@ -451,151 +706,195 @@ struct TALER_EXCHANGE_HttpResponse /** + * Response from /keys. + */ +struct TALER_EXCHANGE_KeysResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on the HTTP status code. + */ + union + { + + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + /** + * Information about the various keys used by the exchange. + */ + const struct TALER_EXCHANGE_Keys *keys; + + /** + * Protocol compatibility information + */ + enum TALER_EXCHANGE_VersionCompatibility compat; + } ok; + } details; + +}; + + +/** * Function called with information about who is auditing * a particular exchange and what keys the exchange is using. + * The ownership over the @a keys object is passed to + * the callee, thus it is given explicitly and not + * (only) via @a kr. * * @param cls closure - * @param hr HTTP response data - * @param keys information about the various keys used - * by the exchange, NULL if /keys failed - * @param compat protocol compatibility information + * @param kr response from /keys + * @param[in] keys keys object passed to callback with + * reference counter of 1. Must be freed by callee + * using #TALER_EXCHANGE_keys_decref(). NULL on failure. */ typedef void -(*TALER_EXCHANGE_CertificationCallback) ( +(*TALER_EXCHANGE_GetKeysCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_Keys *keys, - enum TALER_EXCHANGE_VersionCompatibility compat); + const struct TALER_EXCHANGE_KeysResponse *kr, + struct TALER_EXCHANGE_Keys *keys); /** - * @brief Handle to the exchange. This is where we interact with - * a particular exchange and keep the per-exchange information. + * @brief Handle for a GET /keys request. */ -struct TALER_EXCHANGE_Handle; +struct TALER_EXCHANGE_GetKeysHandle; /** - * Initialise a connection to the exchange. Will connect to the - * exchange and obtain information about the exchange's master public - * key and the exchange's auditor. The respective information will - * be passed to the @a cert_cb once available, and all future - * interactions with the exchange will be checked to be signed - * (where appropriate) by the respective master key. + * Fetch the main /keys resources from an exchange. Does an incremental + * fetch if @a last_keys is given. The obtained information will be passed to + * the @a cert_cb (possibly after first merging it with @a last_keys to + * produce a full picture; expired keys (for deposit) will be removed from @a + * last_keys if there are any). * * @param ctx the context * @param url HTTP base URL for the exchange + * @param[in,out] last_keys previous keys object, NULL for none * @param cert_cb function to call with the exchange's certification information, * possibly called repeatedly if the information changes * @param cert_cb_cls closure for @a cert_cb - * @param ... list of additional arguments, terminated by #TALER_EXCHANGE_OPTION_END. * @return the exchange handle; NULL upon error */ -struct TALER_EXCHANGE_Handle * -TALER_EXCHANGE_connect (struct GNUNET_CURL_Context *ctx, - const char *url, - TALER_EXCHANGE_CertificationCallback cert_cb, - void *cert_cb_cls, - ...); +struct TALER_EXCHANGE_GetKeysHandle * +TALER_EXCHANGE_get_keys ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *last_keys, + TALER_EXCHANGE_GetKeysCallback cert_cb, + void *cert_cb_cls); /** - * Serialize the latest key data from @a exchange to be persisted - * on disk (to be used with #TALER_EXCHANGE_OPTION_DATA to more - * efficiently recover the state). + * Serialize the latest data from @a keys to be persisted + * (for example, to be used as @a last_keys later). * - * @param exchange which exchange's key and wire data should be serialized - * @return NULL on error (i.e. no current data available); otherwise - * json object owned by the caller + * @param kd the key data to serialize + * @return NULL on error; otherwise JSON object owned by the caller */ json_t * -TALER_EXCHANGE_serialize_data (struct TALER_EXCHANGE_Handle *exchange); +TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd); /** - * Disconnect from the exchange. + * Deserialize keys data stored in @a j. * - * @param exchange the exchange handle + * @param j JSON keys data previously returned from #TALER_EXCHANGE_keys_to_json() + * @return NULL on error (i.e. invalid JSON); otherwise + * keys object with reference counter 1 owned by the caller */ -void -TALER_EXCHANGE_disconnect (struct TALER_EXCHANGE_Handle *exchange); +struct TALER_EXCHANGE_Keys * +TALER_EXCHANGE_keys_from_json (const json_t *j); /** - * Obtain the keys from the exchange. + * Cancel GET /keys operation. * - * @param exchange the exchange handle - * @return the exchange's key set + * @param[in] gkh the GET /keys handle */ -const struct TALER_EXCHANGE_Keys * -TALER_EXCHANGE_get_keys (struct TALER_EXCHANGE_Handle *exchange); +void +TALER_EXCHANGE_get_keys_cancel (struct TALER_EXCHANGE_GetKeysHandle *gkh); /** - * Let the user set the last valid denomination time manually. + * Increment reference counter for @a keys * - * @param exchange the exchange handle. - * @param last_denom_new new last denomination time. + * @param[in,out] keys object to increment reference counter for + * @return keys, with incremented reference counter */ -void -TALER_EXCHANGE_set_last_denom (struct TALER_EXCHANGE_Handle *exchange, - struct GNUNET_TIME_Timestamp last_denom_new); +struct TALER_EXCHANGE_Keys * +TALER_EXCHANGE_keys_incref (struct TALER_EXCHANGE_Keys *keys); /** - * Flags for #TALER_EXCHANGE_check_keys_current(). + * Decrement reference counter for @a keys. + * Frees @a keys if reference counter becomes zero. + * + * @param[in,out] keys object to decrement reference counter for */ -enum TALER_EXCHANGE_CheckKeysFlags -{ - /** - * No special options. - */ - TALER_EXCHANGE_CKF_NONE, - - /** - * Force downloading /keys now, even if /keys is still valid - * (that is, the period advertised by the exchange for re-downloads - * has not yet expired). - */ - TALER_EXCHANGE_CKF_FORCE_DOWNLOAD = 1, - - /** - * Pull all keys again, resetting the client state to the original state. - * Using this flag disables the incremental download, and also prevents using - * the context until the re-download has completed. - */ - TALER_EXCHANGE_CKF_PULL_ALL_KEYS = 2, +void +TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys); - /** - * Force downloading all keys now. - */ - TALER_EXCHANGE_CKF_FORCE_ALL_NOW = TALER_EXCHANGE_CKF_FORCE_DOWNLOAD - | TALER_EXCHANGE_CKF_PULL_ALL_KEYS -}; +/** + * Use STEFAN curve in @a keys to convert @a brut to @a net. Computes the + * expected minimum (!) @a net amount that should for sure arrive in the + * target amount at cost of @a brut to the wallet. Note that STEFAN curves by + * design over-estimate actual fees and a wallet may be able to achieve the + * same @a net amount with less fees --- or if the available coins are + * abnormal in structure, it may take more. + * + * @param keys exchange key data + * @param brut gross amount (actual cost including fees) + * @param[out] net net amount (effective amount) + * @return #GNUNET_OK on success, #GNUNET_NO if the + * resulting @a net is zero (or lower) + */ +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_keys_stefan_b2n ( + const struct TALER_EXCHANGE_Keys *keys, + const struct TALER_Amount *brut, + struct TALER_Amount *net); /** - * Check if our current response for /keys is valid, and if - * not, trigger /keys download. + * Use STEFAN curve in @a keys to convert @a net to @a brut. Computes the + * expected maximum (!) @a brut amount that should be needed in the wallet to + * transfer @a net amount to the target account. Note that STEFAN curves by + * design over-estimate actual fees and a wallet may be able to achieve the + * same @a net amount with less fees --- or if the available coins are + * abnormal in structure, it may take more. * - * @param exchange exchange to check keys for - * @param flags options controlling when to download what - * @return until when the existing response is current, 0 if we are re-downloading now + * @param keys exchange key data + * @param net net amount (effective amount) + * @param[out] brut gross amount (actual cost including fees) + * @return #GNUNET_OK on success, #GNUNET_NO if the + * resulting @a brut is zero (only if @a net was zero) */ -struct GNUNET_TIME_Timestamp -TALER_EXCHANGE_check_keys_current (struct TALER_EXCHANGE_Handle *exchange, - enum TALER_EXCHANGE_CheckKeysFlags flags); +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_keys_stefan_n2b ( + const struct TALER_EXCHANGE_Keys *keys, + const struct TALER_Amount *net, + struct TALER_Amount *brut); /** - * Obtain the keys from the exchange in the raw JSON format. + * Round brutto or netto value computed via STEFAN + * curve to decimal places commonly used at the exchange. * - * @param exchange the exchange handle - * @return the exchange's keys in raw JSON + * @param keys exchange keys response data + * @param[in,out] val value to round */ -json_t * -TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange); +void +TALER_EXCHANGE_keys_stefan_round ( + const struct TALER_EXCHANGE_Keys *keys, + struct TALER_Amount *val); /** @@ -607,18 +906,9 @@ TALER_EXCHANGE_get_keys_raw (struct TALER_EXCHANGE_Handle *exchange); * @return #GNUNET_OK if @a pub is (according to /keys) a current signing key */ enum GNUNET_GenericReturnValue -TALER_EXCHANGE_test_signing_key (const struct TALER_EXCHANGE_Keys *keys, - const struct TALER_ExchangePublicKeyP *pub); - - -/** - * Get exchange's base URL. - * - * @param exchange exchange handle. - * @return the base URL from the handle. - */ -const char * -TALER_EXCHANGE_get_base_url (const struct TALER_EXCHANGE_Handle *exchange); +TALER_EXCHANGE_test_signing_key ( + const struct TALER_EXCHANGE_Keys *keys, + const struct TALER_ExchangePublicKeyP *pub); /** @@ -652,7 +942,8 @@ TALER_EXCHANGE_get_global_fee ( * Create a copy of a denomination public key. * * @param key key to copy - * @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key + * @returns a copy, must be freed with #TALER_EXCHANGE_destroy_denomination_key() + * @deprecated */ struct TALER_EXCHANGE_DenomPublicKey * TALER_EXCHANGE_copy_denomination_key ( @@ -661,9 +952,10 @@ TALER_EXCHANGE_copy_denomination_key ( /** * Destroy a denomination public key. - * Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key. + * Should only be called with keys created by #TALER_EXCHANGE_copy_denomination_key(). * * @param key key to destroy. + * @deprecated */ void TALER_EXCHANGE_destroy_denomination_key ( @@ -697,124 +989,36 @@ TALER_EXCHANGE_get_signing_key_info ( const struct TALER_ExchangePublicKeyP *exchange_pub); -/* ********************* /wire *********************** */ - - -/** - * Sorted list of fees to be paid for aggregate wire transfers. - */ -struct TALER_EXCHANGE_WireAggregateFees -{ - /** - * This is a linked list. - */ - struct TALER_EXCHANGE_WireAggregateFees *next; - - /** - * Fee to be paid whenever the exchange wires funds to the merchant. - */ - struct TALER_WireFeeSet fees; - - /** - * Time when this fee goes into effect (inclusive) - */ - struct GNUNET_TIME_Timestamp start_date; - - /** - * Time when this fee stops being in effect (exclusive). - */ - struct GNUNET_TIME_Timestamp end_date; - - /** - * Signature affirming the above fee structure. - */ - struct TALER_MasterSignatureP master_sig; -}; - - -/** - * Information about a wire account of the exchange. - */ -struct TALER_EXCHANGE_WireAccount -{ - /** - * payto://-URI of the exchange. - */ - const char *payto_uri; - - /** - * Signature of the exchange over the account (was checked by the API). - */ - struct TALER_MasterSignatureP master_sig; - - /** - * Linked list of wire fees the exchange charges for - * accounts of the wire method matching @e payto_uri. - */ - const struct TALER_EXCHANGE_WireAggregateFees *fees; - -}; - - -/** - * Callbacks of this type are used to serve the result of submitting a - * wire format inquiry request to a exchange. - * - * If the request fails to generate a valid response from the - * exchange, @a http_status will also be zero. - * - * @param cls closure - * @param hr HTTP response data - * @param accounts_len length of the @a accounts array - * @param accounts list of wire accounts of the exchange, NULL on error - */ -typedef void -(*TALER_EXCHANGE_WireCallback) ( - void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - unsigned int accounts_len, - const struct TALER_EXCHANGE_WireAccount *accounts); - - -/** - * @brief A Wire format inquiry handle - */ -struct TALER_EXCHANGE_WireHandle; +/* ********************* wire helpers *********************** */ /** - * Obtain information about a exchange's wire instructions. A - * exchange may provide wire instructions for creating a reserve. The - * wire instructions also indicate which wire formats merchants may - * use with the exchange. This API is typically used by a wallet for - * wiring funds, and possibly by a merchant to determine supported - * wire formats. + * Parse array of @a accounts of the exchange into @a was. * - * Note that while we return the (main) response verbatim to the - * caller for further processing, we do already verify that the - * response is well-formed (i.e. that signatures included in the - * response are all valid). If the exchange's reply is not - * well-formed, we return an HTTP status code of zero to @a cb. - * - * @param exchange the exchange handle; the exchange must be ready to operate - * @param wire_cb the callback to call when a reply for this request is available - * @param wire_cb_cls closure for the above callback - * @return a handle for this request + * @param master_pub master public key of the exchange, NULL to not verify signatures + * @param accounts array of accounts to parse + * @param[out] was where to write the result (already allocated) + * @param was_length length of the @a was array, must match the length of @a accounts + * @return #GNUNET_OK if parsing @a accounts succeeded */ -struct TALER_EXCHANGE_WireHandle * -TALER_EXCHANGE_wire (struct TALER_EXCHANGE_Handle *exchange, - TALER_EXCHANGE_WireCallback wire_cb, - void *wire_cb_cls); +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_parse_accounts ( + const struct TALER_MasterPublicKeyP *master_pub, + const json_t *accounts, + unsigned int was_length, + struct TALER_EXCHANGE_WireAccount was[static was_length]); /** - * Cancel a wire information request. This function cannot be used - * on a request handle if a response is already served for it. + * Free data within @a was, but not @a was itself. * - * @param wh the wire information request handle + * @param was array of wire account data + * @param was_len length of the @a was array */ void -TALER_EXCHANGE_wire_cancel (struct TALER_EXCHANGE_WireHandle *wh); +TALER_EXCHANGE_free_accounts ( + unsigned int was_len, + struct TALER_EXCHANGE_WireAccount was[static was_len]); /* ********************* /coins/$COIN_PUB/deposit *********************** */ @@ -867,18 +1071,16 @@ struct TALER_EXCHANGE_DepositContractDetail { /** - * Execution date, until which the merchant would like the exchange to - * settle the balance (advisory, the exchange cannot be forced to settle in - * the past or upon very short notice, but of course a well-behaved exchange - * will limit aggregation based on the advice received). + * Hash of the contact of the merchant with the customer (further details + * are never disclosed to the exchange) */ - struct GNUNET_TIME_Timestamp wire_deadline; + struct TALER_PrivateContractHashP h_contract_terms; /** - * The merchant’s account details, in the payto://-format supported by the - * exchange. + * The public key of the merchant (used to identify the merchant for refund + * requests). */ - const char *merchant_payto_uri; + struct TALER_MerchantPublicKeyP merchant_pub; /** * Salt used to hash the @e merchant_payto_uri. @@ -886,168 +1088,47 @@ struct TALER_EXCHANGE_DepositContractDetail struct TALER_WireSaltP wire_salt; /** - * Hash of the contact of the merchant with the customer (further details - * are never disclosed to the exchange) + * Hash over data provided by the wallet to customize the contract. + * All zero if not used. */ - struct TALER_PrivateContractHashP h_contract_terms; + struct GNUNET_HashCode wallet_data_hash; /** - * Extension-specific details about the deposit relevant to the exchange. + * Date until which the merchant can issue a refund to the customer via the + * exchange (can be zero if refunds are not allowed); must not be after the + * @e wire_deadline. */ - const json_t *extension_details; + struct GNUNET_TIME_Timestamp refund_deadline; /** - * Timestamp when the contract was finalized, must match approximately the - * current time of the exchange. + * Execution date, until which the merchant would like the exchange to + * settle the balance (advisory, the exchange cannot be forced to settle in + * the past or upon very short notice, but of course a well-behaved exchange + * will limit aggregation based on the advice received). */ - struct GNUNET_TIME_Timestamp timestamp; + struct GNUNET_TIME_Timestamp wire_deadline; /** - * The public key of the merchant (used to identify the merchant for refund - * requests). + * Timestamp when the contract was finalized, must match approximately the + * current time of the exchange. */ - struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Timestamp wallet_timestamp; /** - * Date until which the merchant can issue a refund to the customer via the - * exchange (can be zero if refunds are not allowed); must not be after the - * @e wire_deadline. + * The merchant’s account details, in the payto://-format supported by the + * exchange. */ - struct GNUNET_TIME_Timestamp refund_deadline; - -}; - - -/** - * @brief A Deposit Handle - */ -struct TALER_EXCHANGE_DepositHandle; - + const char *merchant_payto_uri; -/** - * Structure with information about a deposit - * operation's result. - */ -struct TALER_EXCHANGE_DepositResult -{ /** - * HTTP response data + * Policy extension specific details about the deposit relevant to the exchange. */ - struct TALER_EXCHANGE_HttpResponse hr; - - union - { - - /** - * Information returned if the HTTP status is - * #MHD_HTTP_OK. - */ - struct - { - /** - * Time when the exchange generated the deposit confirmation - */ - struct GNUNET_TIME_Timestamp deposit_timestamp; + const json_t *policy_details; - /** - * signature provided by the exchange - */ - const struct TALER_ExchangeSignatureP *exchange_sig; - - /** - * exchange key used to sign @a exchange_sig. - */ - const struct TALER_ExchangePublicKeyP *exchange_pub; - - /** - * Base URL for looking up wire transfers, or - * NULL to use the default base URL. - */ - const char *transaction_base_url; - - } success; - - /** - * Information returned if the HTTP status is - * #MHD_HTTP_CONFLICT. - */ - struct - { - /* TODO: returning full details is not implemented */ - } conflict; - - } details; }; /** - * Callbacks of this type are used to serve the result of submitting a - * deposit permission request to a exchange. - * - * @param cls closure - * @param dr deposit response details - */ -typedef void -(*TALER_EXCHANGE_DepositResultCallback) ( - void *cls, - const struct TALER_EXCHANGE_DepositResult *dr); - - -/** - * Submit a deposit permission to the exchange and get the exchange's - * response. This API is typically used by a merchant. Note that - * while we return the response verbatim to the caller for further - * processing, we do already verify that the response is well-formed - * (i.e. that signatures included in the response are all valid). If - * the exchange's reply is not well-formed, we return an HTTP status code - * of zero to @a cb. - * - * We also verify that the @a cdd.coin_sig is valid for this deposit - * request, and that the @a cdd.ub_sig is a valid signature for @a - * coin_pub. Also, the @a exchange must be ready to operate (i.e. have - * finished processing the /keys reply). If either check fails, we do - * NOT initiate the transaction with the exchange and instead return NULL. - * - * @param exchange the exchange handle; the exchange must be ready to operate - * @param dcd details about the contract the deposit is for - * @param cdd details about the coin to be deposited - * @param cb the callback to call when a reply for this request is available - * @param cb_cls closure for the above callback - * @param[out] ec if NULL is returned, set to the error code explaining why the operation failed - * @return a handle for this request; NULL if the inputs are invalid (i.e. - * signatures fail to verify). In this case, the callback is not called. - */ -struct TALER_EXCHANGE_DepositHandle * -TALER_EXCHANGE_deposit ( - struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DepositContractDetail *dcd, - const struct TALER_EXCHANGE_CoinDepositDetail *cdd, - TALER_EXCHANGE_DepositResultCallback cb, - void *cb_cls, - enum TALER_ErrorCode *ec); - - -/** - * Change the chance that our deposit confirmation will be given to the - * auditor to 100%. - * - * @param deposit the deposit permission request handle - */ -void -TALER_EXCHANGE_deposit_force_dc (struct TALER_EXCHANGE_DepositHandle *deposit); - - -/** - * Cancel a deposit permission request. This function cannot be used - * on a request handle if a response is already served for it. - * - * @param deposit the deposit permission request handle - */ -void -TALER_EXCHANGE_deposit_cancel (struct TALER_EXCHANGE_DepositHandle *deposit); - - -/** * @brief A Batch Deposit Handle */ struct TALER_EXCHANGE_BatchDepositHandle; @@ -1079,9 +1160,9 @@ struct TALER_EXCHANGE_BatchDepositResult struct GNUNET_TIME_Timestamp deposit_timestamp; /** - * Array of signatures provided by the exchange + * Deposit confirmation signature provided by the exchange */ - const struct TALER_ExchangeSignatureP *exchange_sigs; + const struct TALER_ExchangeSignatureP *exchange_sig; /** * exchange key used to sign @a exchange_sig. @@ -1094,12 +1175,7 @@ struct TALER_EXCHANGE_BatchDepositResult */ const char *transaction_base_url; - /** - * Length of the @e exchange_sigs array. - */ - unsigned int num_signatures; - - } success; + } ok; /** * Information returned if the HTTP status is @@ -1107,7 +1183,11 @@ struct TALER_EXCHANGE_BatchDepositResult */ struct { - /* TODO: returning full details is not implemented */ + /** + * The coin that had a conflict. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + } conflict; } details; @@ -1141,7 +1221,9 @@ typedef void * finished processing the /keys reply). If either check fails, we do * NOT initiate the transaction with the exchange and instead return NULL. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param dcd details about the contract the deposit is for * @param num_cdds length of the @a cdds array * @param cdds array with details about the coins to be deposited @@ -1153,10 +1235,12 @@ typedef void */ struct TALER_EXCHANGE_BatchDepositHandle * TALER_EXCHANGE_batch_deposit ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_EXCHANGE_DepositContractDetail *dcd, unsigned int num_cdds, - const struct TALER_EXCHANGE_CoinDepositDetail *cdds, + const struct TALER_EXCHANGE_CoinDepositDetail cdds[static num_cdds], TALER_EXCHANGE_BatchDepositResultCallback cb, void *cb_cls, enum TALER_ErrorCode *ec); @@ -1166,23 +1250,22 @@ TALER_EXCHANGE_batch_deposit ( * Change the chance that our deposit confirmation will be given to the * auditor to 100%. * - * @param deposit the batch deposit permission request handle + * @param[in,out] deposit the batch deposit permission request handle */ void -TALER_EXCHANGE_batch_deposit_force_dc (struct - TALER_EXCHANGE_BatchDepositHandle * - deposit); +TALER_EXCHANGE_batch_deposit_force_dc ( + struct TALER_EXCHANGE_BatchDepositHandle *deposit); /** * Cancel a batch deposit permission request. This function cannot be used * on a request handle if a response is already served for it. * - * @param deposit the deposit permission request handle + * @param[in] deposit the deposit permission request handle */ void -TALER_EXCHANGE_batch_deposit_cancel (struct - TALER_EXCHANGE_BatchDepositHandle *deposit); +TALER_EXCHANGE_batch_deposit_cancel ( + struct TALER_EXCHANGE_BatchDepositHandle *deposit); /* ********************* /coins/$COIN_PUB/refund *********************** */ @@ -1192,23 +1275,51 @@ TALER_EXCHANGE_batch_deposit_cancel (struct */ struct TALER_EXCHANGE_RefundHandle; +/** + * Response from the /refund API. + */ +struct TALER_EXCHANGE_RefundResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status code. + */ + union + { + /** + * Details on #MHD_HTTP_OK. + */ + struct + { + /** + * Exchange key used to sign. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * The actual signature + */ + struct TALER_ExchangeSignatureP exchange_sig; + } ok; + } details; +}; + /** * Callbacks of this type are used to serve the result of submitting a * refund request to an exchange. * * @param cls closure - * @param hr HTTP response data - * @param sign_key exchange key used to sign @a obj, or NULL - * @param signature the actual signature, or NULL on error + * @param rr refund response */ typedef void (*TALER_EXCHANGE_RefundCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ExchangePublicKeyP *sign_key, - const struct TALER_ExchangeSignatureP *signature); - + const struct TALER_EXCHANGE_RefundResponse *rr); /** * Submit a refund request to the exchange and get the exchange's response. @@ -1222,7 +1333,9 @@ typedef void * finished processing the /keys reply). If this check fails, we do * NOT initiate the transaction with the exchange and instead return NULL. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param amount the amount to be refunded; must be larger than the refund fee * (as that fee is still being subtracted), and smaller than the amount * (with deposit fee) of the original deposit contribution of this coin @@ -1239,15 +1352,17 @@ typedef void * signatures fail to verify). In this case, the callback is not called. */ struct TALER_EXCHANGE_RefundHandle * -TALER_EXCHANGE_refund (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_Amount *amount, - const struct - TALER_PrivateContractHashP *h_contract_terms, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - uint64_t rtransaction_id, - const struct TALER_MerchantPrivateKeyP *merchant_priv, - TALER_EXCHANGE_RefundCallback cb, - void *cb_cls); +TALER_EXCHANGE_refund ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, + const struct TALER_Amount *amount, + const struct TALER_PrivateContractHashP *h_contract_terms, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + uint64_t rtransaction_id, + const struct TALER_MerchantPrivateKeyP *merchant_priv, + TALER_EXCHANGE_RefundCallback cb, + void *cb_cls); /** @@ -1301,14 +1416,14 @@ struct TALER_EXCHANGE_CsRMeltResponse * respective coin's withdraw operation. */ const struct TALER_ExchangeWithdrawValues *alg_values; - } success; + } ok; /** * Details if the status is #MHD_HTTP_GONE. */ struct { - /* TODO: returning full details is not implemented */ + /* FIXME: returning full details is not implemented */ } gone; } details; @@ -1349,7 +1464,8 @@ struct TALER_EXCHANGE_NonceKey /** * Get a set of CS R values using a /csr-melt request. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL * @param rms master key used for the derivation of the CS values * @param nks_len length of the @a nks array * @param nks array of denominations and nonces @@ -1360,12 +1476,14 @@ struct TALER_EXCHANGE_NonceKey * In this case, the callback is not called. */ struct TALER_EXCHANGE_CsRMeltHandle * -TALER_EXCHANGE_csr_melt (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_RefreshMasterSecretP *rms, - unsigned int nks_len, - struct TALER_EXCHANGE_NonceKey *nks, - TALER_EXCHANGE_CsRMeltCallback res_cb, - void *res_cb_cls); +TALER_EXCHANGE_csr_melt ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_RefreshMasterSecretP *rms, + unsigned int nks_len, + struct TALER_EXCHANGE_NonceKey nks[static nks_len], + TALER_EXCHANGE_CsRMeltCallback res_cb, + void *res_cb_cls); /** @@ -1413,7 +1531,8 @@ struct TALER_EXCHANGE_CsRWithdrawResponse * respective coin's withdraw operation. */ struct TALER_ExchangeWithdrawValues alg_values; - } success; + + } ok; /** * Details if the status is #MHD_HTTP_GONE. @@ -1443,7 +1562,8 @@ typedef void /** * Get a CS R using a /csr-withdraw request. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param curl_ctx The curl context to use for the requests + * @param exchange_url Base-URL to the excnange * @param pk Which denomination key is the /csr request for * @param nonce client nonce for the request * @param res_cb the callback to call when the final result for this request is available @@ -1453,11 +1573,13 @@ typedef void * In this case, the callback is not called. */ struct TALER_EXCHANGE_CsRWithdrawHandle * -TALER_EXCHANGE_csr_withdraw (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct TALER_CsNonce *nonce, - TALER_EXCHANGE_CsRWithdrawCallback res_cb, - void *res_cb_cls); +TALER_EXCHANGE_csr_withdraw ( + struct GNUNET_CURL_Context *curl_ctx, + const char *exchange_url, + const struct TALER_EXCHANGE_DenomPublicKey *pk, + const struct GNUNET_CRYPTO_CsSessionNonce *nonce, + TALER_EXCHANGE_CsRWithdrawCallback res_cb, + void *res_cb_cls); /** @@ -1472,6 +1594,329 @@ TALER_EXCHANGE_csr_withdraw_cancel ( struct TALER_EXCHANGE_CsRWithdrawHandle *csrh); +/* ********************* GET /coins/$COIN_PUB *********************** */ + +/** + * Ways how a coin's balance may change. + */ +enum TALER_EXCHANGE_CoinTransactionType +{ + + /** + * Reserved for uninitialized / none. + */ + TALER_EXCHANGE_CTT_NONE, + + /** + * Deposit into a contract. + */ + TALER_EXCHANGE_CTT_DEPOSIT, + + /** + * Spent on melt. + */ + TALER_EXCHANGE_CTT_MELT, + + /** + * Refunded by merchant. + */ + TALER_EXCHANGE_CTT_REFUND, + + /** + * Debited in recoup (to reserve) operation. + */ + TALER_EXCHANGE_CTT_RECOUP, + + /** + * Debited in recoup-and-refresh operation. + */ + TALER_EXCHANGE_CTT_RECOUP_REFRESH, + + /** + * Credited in recoup-refresh. + */ + TALER_EXCHANGE_CTT_OLD_COIN_RECOUP, + + /** + * Deposited into purse. + */ + TALER_EXCHANGE_CTT_PURSE_DEPOSIT, + + /** + * Refund from purse. + */ + TALER_EXCHANGE_CTT_PURSE_REFUND, + + /** + * Reserve open payment operation. + */ + TALER_EXCHANGE_CTT_RESERVE_OPEN_DEPOSIT + +}; + + +/** + * @brief Entry in the coin's transaction history. + */ +struct TALER_EXCHANGE_CoinHistoryEntry +{ + + /** + * Type of the transaction. + */ + enum TALER_EXCHANGE_CoinTransactionType type; + + /** + * Amount transferred (in or out). + */ + struct TALER_Amount amount; + + /** + * Details depending on @e type. + */ + union + { + + struct + { + struct TALER_MerchantWireHashP h_wire; + struct TALER_PrivateContractHashP h_contract_terms; + struct TALER_ExtensionPolicyHashP h_policy; + bool no_h_policy; + struct GNUNET_HashCode wallet_data_hash; + bool no_wallet_data_hash; + struct GNUNET_TIME_Timestamp wallet_timestamp; + struct TALER_MerchantPublicKeyP merchant_pub; + struct GNUNET_TIME_Timestamp refund_deadline; + struct TALER_CoinSpendSignatureP sig; + struct TALER_AgeCommitmentHash hac; + bool no_hac; + struct TALER_Amount deposit_fee; + } deposit; + + struct + { + struct TALER_CoinSpendSignatureP sig; + struct TALER_RefreshCommitmentP rc; + struct TALER_AgeCommitmentHash h_age_commitment; + bool no_hac; + struct TALER_Amount melt_fee; + } melt; + + struct + { + struct TALER_PrivateContractHashP h_contract_terms; + struct TALER_MerchantPublicKeyP merchant_pub; + struct TALER_MerchantSignatureP sig; + struct TALER_Amount refund_fee; + struct TALER_Amount sig_amount; + uint64_t rtransaction_id; + } refund; + + struct + { + struct TALER_ReservePublicKeyP reserve_pub; + struct GNUNET_TIME_Timestamp timestamp; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_CoinSpendSignatureP coin_sig; + } recoup; + + struct + { + struct TALER_CoinSpendPublicKeyP old_coin_pub; + union GNUNET_CRYPTO_BlindingSecretP coin_bks; + struct GNUNET_TIME_Timestamp timestamp; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_CoinSpendSignatureP coin_sig; + } recoup_refresh; + + struct + { + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangeSignatureP exchange_sig; + struct TALER_CoinSpendPublicKeyP new_coin_pub; + struct GNUNET_TIME_Timestamp timestamp; + } old_coin_recoup; + + struct + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_CoinSpendSignatureP coin_sig; + const char *exchange_base_url; + bool refunded; + struct TALER_AgeCommitmentHash phac; + } purse_deposit; + + struct + { + struct TALER_PurseContractPublicKeyP purse_pub; + struct TALER_Amount refund_fee; + struct TALER_ExchangePublicKeyP exchange_pub; + struct TALER_ExchangeSignatureP exchange_sig; + } purse_refund; + + struct + { + struct TALER_ReserveSignatureP reserve_sig; + struct TALER_CoinSpendSignatureP coin_sig; + } reserve_open_deposit; + + } details; + +}; + + +/** + * @brief A /coins/$RID/history Handle + */ +struct TALER_EXCHANGE_CoinsHistoryHandle; + + +/** + * Parses and verifies a coin's transaction history as + * returned by the exchange. Note that in case of + * incremental histories, the client must first combine + * the incremental histories into one complete history. + * + * @param keys /keys data of the exchange + * @param dk denomination key of the coin + * @param history JSON array with the coin's history + * @param coin_pub public key of the coin + * @param[out] total_in set to total amount credited to the coin in @a history + * @param[out] total_out set to total amount debited to the coin in @a history + * @param rlen length of the @a rhistory array + * @param[out] rhistory array where to write the parsed @a history + * @return #GNUNET_OK if @a history is valid, + * #GNUNET_SYSERR if not + */ +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_parse_coin_history ( + const struct TALER_EXCHANGE_Keys *keys, + const struct TALER_EXCHANGE_DenomPublicKey *dk, + const json_t *history, + const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct TALER_Amount *total_in, + struct TALER_Amount *total_out, + unsigned int rlen, + struct TALER_EXCHANGE_CoinHistoryEntry rhistory[static rlen]); + + +/** + * Verify that @a coin_sig does NOT appear in the @a history of a coin's + * transactions and thus whatever transaction is authorized by @a coin_sig is + * a conflict with @a proof. + * + * @param history coin history to check + * @param coin_sig signature that must not be in @a history + * @return #GNUNET_OK if @a coin_sig is not in @a history + */ +enum GNUNET_GenericReturnValue +TALER_EXCHANGE_check_coin_signature_conflict ( + const json_t *history, + const struct TALER_CoinSpendSignatureP *coin_sig); + + +/** + * Response to a GET /coins/$COIN_PUB/history request. + */ +struct TALER_EXCHANGE_CoinHistory +{ + /** + * High-level HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on @e hr.http_status. + */ + union + { + + /** + * Information returned on success, if + * @e hr.http_status is #MHD_HTTP_OK + */ + struct + { + + /** + * Coin transaction history (possibly partial). + * Not yet validated, combine with other already + * known history data for this coin and then use + * #TALER_EXCHANGE_parse_coin_history() to validate + * the complete history and obtain it in binary + * format. + */ + const json_t *history; + + /** + * The hash of the coin denomination's public key + */ + struct TALER_DenominationHashP h_denom_pub; + + /** + * Coin balance. + */ + struct TALER_Amount balance; + + } ok; + + } details; + +}; + + +/** + * Signature of functions called with the result of + * a coin transaction history request. + * + * @param cls closure + * @param ch transaction history for the coin + */ +typedef void +(*TALER_EXCHANGE_CoinsHistoryCallback)( + void *cls, + const struct TALER_EXCHANGE_CoinHistory *ch); + + +/** + * Parses and verifies a coin's transaction history as + * returned by the exchange. Note that a client may + * have to combine multiple partial coin histories + * into one coherent history before calling this function. + * + * @param ctx context for managing request + * @param url base URL of the exchange + * @param coin_priv private key of the coin + * @param start_off offset from which on to request history + * @param cb function to call with results + * @param cb_cls closure for @a cb + * @return #GNUNET_OK if @a history is valid, + * #GNUNET_SYSERR if not + */ +struct TALER_EXCHANGE_CoinsHistoryHandle * +TALER_EXCHANGE_coins_history ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_CoinSpendPrivateKeyP *coin_priv, + uint64_t start_off, + TALER_EXCHANGE_CoinsHistoryCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_coins_history() operation. + * + * @param[in] rsh operation to cancel + */ +void +TALER_EXCHANGE_coins_history_cancel ( + struct TALER_EXCHANGE_CoinsHistoryHandle *rsh); + + /* ********************* GET /reserves/$RESERVE_PUB *********************** */ /** @@ -1491,6 +1936,11 @@ enum TALER_EXCHANGE_ReserveTransactionType TALER_EXCHANGE_RTT_WITHDRAWAL, /** + * Age-Withdrawal from the reserve. + */ + TALER_EXCHANGE_RTT_AGEWITHDRAWAL, + + /** * /recoup operation. */ TALER_EXCHANGE_RTT_RECOUP, @@ -1498,17 +1948,22 @@ enum TALER_EXCHANGE_ReserveTransactionType /** * Reserve closed operation. */ - TALER_EXCHANGE_RTT_CLOSE, + TALER_EXCHANGE_RTT_CLOSING, /** - * Reserve history request. + * Reserve purse merge operation. */ - TALER_EXCHANGE_RTT_HISTORY, + TALER_EXCHANGE_RTT_MERGE, /** - * Reserve purese merge operation. + * Reserve open request operation. */ - TALER_EXCHANGE_RTT_MERGE + TALER_EXCHANGE_RTT_OPEN, + + /** + * Reserve close request operation. + */ + TALER_EXCHANGE_RTT_CLOSE }; @@ -1576,6 +2031,28 @@ struct TALER_EXCHANGE_ReserveHistoryEntry } withdraw; /** + * Information about withdraw operation. + * @e type is #TALER_EXCHANGE_RTT_AGEWITHDRAWAL. + */ + struct + { + /** + * Signature authorizing the withdrawal for outgoing transaction. + */ + json_t *out_authorization_sig; + + /** + * Maximum age committed + */ + uint8_t max_age; + + /** + * Fee that was charged for the withdrawal. + */ + struct TALER_Amount fee; + } age_withdraw; + + /** * Information provided if the reserve was filled via /recoup. * @e type is #TALER_EXCHANGE_RTT_RECOUP. */ @@ -1612,7 +2089,7 @@ struct TALER_EXCHANGE_ReserveHistoryEntry struct { /** - * Receiver account information for the outgoing wire transfer. + * Receiver account information for the outgoing wire transfer as a payto://-URI. */ const char *receiver_account_details; @@ -1645,25 +2122,6 @@ struct TALER_EXCHANGE_ReserveHistoryEntry } close_details; /** - * Information about a history operation of the reserve. - * @e type is #TALER_EXCHANGE_RTT_HISTORY. - */ - struct - { - - /** - * When was the request made. - */ - struct GNUNET_TIME_Timestamp request_timestamp; - - /** - * Signature by the reserve approving the history request. - */ - struct TALER_ReserveSignatureP reserve_sig; - - } history_details; - - /** * Information about a merge operation on the reserve. * @e type is #TALER_EXCHANGE_RTT_MERGE. */ @@ -1723,6 +2181,71 @@ struct TALER_EXCHANGE_ReserveHistoryEntry } merge_details; + /** + * Information about an open request operation on the reserve. + * @e type is #TALER_EXCHANGE_RTT_OPEN. + */ + struct + { + + /** + * Signature by the reserve approving the open. + */ + struct TALER_ReserveSignatureP reserve_sig; + + /** + * Amount to be paid from the reserve balance to open + * the reserve. + */ + struct TALER_Amount reserve_payment; + + /** + * When was the request created. + */ + struct GNUNET_TIME_Timestamp request_timestamp; + + /** + * For how long should the reserve be kept open. + * (Determines amount to be paid.) + */ + struct GNUNET_TIME_Timestamp reserve_expiration; + + /** + * How many open purses should be included with the + * open reserve? + * (Determines amount to be paid.) + */ + uint32_t purse_limit; + + } open_request; + + /** + * Information about an close request operation on the reserve. + * @e type is #TALER_EXCHANGE_RTT_CLOSE. + */ + struct + { + + /** + * Signature by the reserve approving the close. + */ + struct TALER_ReserveSignatureP reserve_sig; + + /** + * When was the request created. + */ + struct GNUNET_TIME_Timestamp request_timestamp; + + /** + * Hash of the payto://-URI of the target account + * for the closure, or all zeros for the reserve + * origin account. + */ + struct TALER_PaytoHashP target_account_h_payto; + + } close_request; + + } details; }; @@ -1792,7 +2315,8 @@ typedef void * reply is not well-formed, we return an HTTP status code of zero to * @a cb. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL * @param reserve_pub public key of the reserve to inspect * @param timeout how long to wait for an affirmative reply * (enables long polling if the reserve does not yet exist) @@ -1803,7 +2327,8 @@ typedef void */ struct TALER_EXCHANGE_ReservesGetHandle * TALER_EXCHANGE_reserves_get ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, const struct TALER_ReservePublicKeyP *reserve_pub, struct GNUNET_TIME_Relative timeout, TALER_EXCHANGE_ReservesGetCallback cb, @@ -1822,15 +2347,15 @@ TALER_EXCHANGE_reserves_get_cancel ( /** - * @brief A /reserves/$RID/status Handle + * @brief A /reserves/$RID/history Handle */ -struct TALER_EXCHANGE_ReservesStatusHandle; +struct TALER_EXCHANGE_ReservesHistoryHandle; /** - * @brief Reserve status details. + * @brief Reserve history details. */ -struct TALER_EXCHANGE_ReserveStatus +struct TALER_EXCHANGE_ReserveHistory { /** @@ -1839,14 +2364,14 @@ struct TALER_EXCHANGE_ReserveStatus struct TALER_EXCHANGE_HttpResponse hr; /** - * Details depending on @e hr.http_status. + * Details depending on @e hr.http_history. */ union { /** * Information returned on success, if - * @e hr.http_status is #MHD_HTTP_OK + * @e hr.http_history is #MHD_HTTP_OK */ struct { @@ -1868,127 +2393,11 @@ struct TALER_EXCHANGE_ReserveStatus struct TALER_Amount total_out; /** - * Reserve history. + * Current etag / last entry in the history. + * Useful to filter requests by starting offset. + * Offsets are not necessarily contiguous. */ - const struct TALER_EXCHANGE_ReserveHistoryEntry *history; - - /** - * Length of the @e history array. - */ - unsigned int history_len; - - /** - * KYC passed? - */ - bool kyc_ok; - - } ok; - - } details; - -}; - - -/** - * Callbacks of this type are used to serve the result of submitting a - * reserve status request to a exchange. - * - * @param cls closure - * @param rs HTTP response data - */ -typedef void -(*TALER_EXCHANGE_ReservesStatusCallback) ( - void *cls, - const struct TALER_EXCHANGE_ReserveStatus *rs); - - -/** - * Submit a request to obtain the reserve status. - * - * @param exchange the exchange handle; the exchange must be ready to operate - * @param reserve_priv private key of the reserve to inspect - * @param cb the callback to call when a reply for this request is available - * @param cb_cls closure for the above callback - * @return a handle for this request; NULL if the inputs are invalid (i.e. - * signatures fail to verify). In this case, the callback is not called. - */ -struct TALER_EXCHANGE_ReservesStatusHandle * -TALER_EXCHANGE_reserves_status ( - struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_ReservePrivateKeyP *reserve_priv, - TALER_EXCHANGE_ReservesStatusCallback cb, - void *cb_cls); - - -/** - * Cancel a reserve status request. This function cannot be used - * on a request handle if a response is already served for it. - * - * @param rsh the reserve request handle - */ -void -TALER_EXCHANGE_reserves_status_cancel ( - struct TALER_EXCHANGE_ReservesStatusHandle *rsh); - - -/** - * @brief A /reserves/$RID/history Handle - */ -struct TALER_EXCHANGE_ReservesHistoryHandle; - - -/** - * @brief Reserve history details. - */ -struct TALER_EXCHANGE_ReserveHistory -{ - - /** - * High-level HTTP response details. - */ - struct TALER_EXCHANGE_HttpResponse hr; - - /** - * Timestamp of when we made the history request - * (client-side). - */ - struct GNUNET_TIME_Timestamp ts; - - /** - * Reserve signature affirming the history request - * (generated as part of the request). - */ - const struct TALER_ReserveSignatureP *reserve_sig; - - /** - * Details depending on @e hr.http_status. - */ - union - { - - /** - * Information returned on success, if - * @e hr.http_status is #MHD_HTTP_OK - */ - struct - { - - /** - * Reserve balance. May not be the difference between - * @e total_in and @e total_out because the @e may be truncated - * due to expiration. - */ - struct TALER_Amount balance; - - /** - * Total of all inbound transactions in @e history. - */ - struct TALER_Amount total_in; - - /** - * Total of all outbound transactions in @e history. - */ - struct TALER_Amount total_out; + uint64_t etag; /** * Reserve history. @@ -2023,8 +2432,11 @@ typedef void /** * Submit a request to obtain the reserve history. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param reserve_priv private key of the reserve to inspect + * @param start_off offset of the oldest history entry to exclude from the response * @param cb the callback to call when a reply for this request is available * @param cb_cls closure for the above callback * @return a handle for this request; NULL if the inputs are invalid (i.e. @@ -2032,8 +2444,11 @@ typedef void */ struct TALER_EXCHANGE_ReservesHistoryHandle * TALER_EXCHANGE_reserves_history ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_ReservePrivateKeyP *reserve_priv, + uint64_t start_off, TALER_EXCHANGE_ReservesHistoryCallback cb, void *cb_cls); @@ -2049,15 +2464,6 @@ TALER_EXCHANGE_reserves_history_cancel ( struct TALER_EXCHANGE_ReservesHistoryHandle *rsh); -/* ********************* POST /reserves/$RESERVE_PUB/withdraw *********************** */ - - -/** - * @brief A /reserves/$RESERVE_PUB/withdraw Handle - */ -struct TALER_EXCHANGE_WithdrawHandle; - - /** * Information input into the withdraw process per coin. */ @@ -2096,7 +2502,7 @@ struct TALER_EXCHANGE_PrivateCoinDetails * Value used to blind the key for the signature. * Needed for recoup operations. */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; /** * Signature over the coin. @@ -2112,109 +2518,6 @@ struct TALER_EXCHANGE_PrivateCoinDetails /** - * Details about a response for a withdraw request. - */ -struct TALER_EXCHANGE_WithdrawResponse -{ - /** - * HTTP response data. - */ - struct TALER_EXCHANGE_HttpResponse hr; - - /** - * Details about the response. - */ - union - { - /** - * Details if the status is #MHD_HTTP_OK. - */ - struct TALER_EXCHANGE_PrivateCoinDetails success; - - /** - * Details if the status is #MHD_HTTP_ACCEPTED. - */ - struct - { - /** - * Payment target that the merchant should use - * to check for its KYC status. - */ - uint64_t payment_target_uuid; - } accepted; - - /** - * Details if the status is #MHD_HTTP_CONFLICT. - */ - struct - { - /* TODO: returning full details is not implemented */ - } conflict; - - /** - * Details if the status is #MHD_HTTP_GONE. - */ - struct - { - /* TODO: returning full details is not implemented */ - } gone; - - } details; -}; - - -/** - * Callbacks of this type are used to serve the result of submitting a - * withdraw request to a exchange. - * - * @param cls closure - * @param wr response details - */ -typedef void -(*TALER_EXCHANGE_WithdrawCallback) ( - void *cls, - const struct TALER_EXCHANGE_WithdrawResponse *wr); - - -/** - * Withdraw a coin from the exchange using a /reserves/$RESERVE_PUB/withdraw - * request. This API is typically used by a wallet to withdraw from a - * reserve. - * - * Note that to ensure that no money is lost in case of hardware - * failures, the caller must have committed (most of) the arguments to - * disk before calling, and be ready to repeat the request with the - * same arguments in case of failures. - * - * @param exchange the exchange handle; the exchange must be ready to operate - * @param reserve_priv private key of the reserve to withdraw from - * @param wci inputs that determine the planchet - * @param res_cb the callback to call when the final result for this request is available - * @param res_cb_cls closure for @a res_cb - * @return NULL - * if the inputs are invalid (i.e. denomination key not with this exchange). - * In this case, the callback is not called. - */ -struct TALER_EXCHANGE_WithdrawHandle * -TALER_EXCHANGE_withdraw ( - struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_EXCHANGE_WithdrawCoinInput *wci, - TALER_EXCHANGE_WithdrawCallback res_cb, - void *res_cb_cls); - - -/** - * Cancel a withdraw status request. This function cannot be used - * on a request handle if a response is already served for it. - * - * @param wh the withdraw handle - */ -void -TALER_EXCHANGE_withdraw_cancel (struct TALER_EXCHANGE_WithdrawHandle *wh); - - -/** * @brief A /reserves/$RESERVE_PUB/batch-withdraw Handle */ struct TALER_EXCHANGE_BatchWithdrawHandle; @@ -2250,19 +2553,25 @@ struct TALER_EXCHANGE_BatchWithdrawResponse * Length of the @e coins array. */ unsigned int num_coins; - } success; + } ok; /** - * Details if the status is #MHD_HTTP_ACCEPTED. + * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. */ struct { + /** - * Payment target that the merchant should use - * to check for its KYC status. + * Hash of the payto-URI of the account to KYC; */ - uint64_t payment_target_uuid; - } accepted; + struct TALER_PaytoHashP h_payto; + + /** + * Legitimization requirement that the merchant should use + * to check for its KYC status, 0 if not known. + */ + uint64_t requirement_row; + } unavailable_for_legal_reasons; /** * Details if the status is #MHD_HTTP_CONFLICT. @@ -2300,17 +2609,20 @@ typedef void /** * Withdraw multiple coins from the exchange using a /reserves/$RESERVE_PUB/batch-withdraw * request. This API is typically used by a wallet to withdraw many coins from a - * reserve. + * reserve. The blind signatures are unblinded and verified before being returned + * to the caller at @a res_cb. * * Note that to ensure that no money is lost in case of hardware * failures, the caller must have committed (most of) the arguments to * disk before calling, and be ready to repeat the request with the * same arguments in case of failures. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param curl_ctx The curl context to use + * @param exchange_url The base-URL of the exchange + * @param keys The /keys material from the exchange * @param reserve_priv private key of the reserve to withdraw from - * @param wcis inputs that determine the planchets * @param wci_length number of entries in @a wcis + * @param wcis inputs that determine the planchets * @param res_cb the callback to call when the final result for this request is available * @param res_cb_cls closure for @a res_cb * @return NULL @@ -2319,10 +2631,12 @@ typedef void */ struct TALER_EXCHANGE_BatchWithdrawHandle * TALER_EXCHANGE_batch_withdraw ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *curl_ctx, + const char *exchange_url, + const struct TALER_EXCHANGE_Keys *keys, const struct TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_EXCHANGE_WithdrawCoinInput *wcis, unsigned int wci_length, + const struct TALER_EXCHANGE_WithdrawCoinInput wcis[static wci_length], TALER_EXCHANGE_BatchWithdrawCallback res_cb, void *res_cb_cls); @@ -2339,18 +2653,45 @@ TALER_EXCHANGE_batch_withdraw_cancel ( /** + * Response from a withdraw2 request. + */ +struct TALER_EXCHANGE_Withdraw2Response +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * blind signature over the coin + */ + struct TALER_BlindedDenominationSignature blind_sig; + } ok; + } details; + +}; + +/** * Callbacks of this type are used to serve the result of submitting a * withdraw request to a exchange without the (un)blinding factor. * * @param cls closure - * @param hr HTTP response data - * @param blind_sig blind signature over the coin, NULL on error + * @param w2r response data */ typedef void (*TALER_EXCHANGE_Withdraw2Callback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_BlindedDenominationSignature *blind_sig); + const struct TALER_EXCHANGE_Withdraw2Response *w2r); /** @@ -2366,14 +2707,20 @@ struct TALER_EXCHANGE_Withdraw2Handle; /** * Withdraw a coin from the exchange using a /reserves/$RESERVE_PUB/withdraw * request. This API is typically used by a merchant to withdraw a tip - * where the blinding factor is unknown to the merchant. + * where the blinding factor is unknown to the merchant. Note that unlike + * the #TALER_EXCHANGE_batch_withdraw() API, this API neither unblinds the signatures + * nor can it verify that the exchange signatures are valid, so these tasks + * are left to the caller. Wallets probably should use #TALER_EXCHANGE_batch_withdraw() + * which integrates these steps. * * Note that to ensure that no money is lost in case of hardware * failures, the caller must have committed (most of) the arguments to * disk before calling, and be ready to repeat the request with the * same arguments in case of failures. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param curl_ctx The curl-context to use + * @param exchange_url The base-URL of the exchange + * @param keys The /keys material from the exchange * @param pd planchet details of the planchet to withdraw * @param reserve_priv private key of the reserve to withdraw from * @param res_cb the callback to call when the final result for this request is available @@ -2383,11 +2730,14 @@ struct TALER_EXCHANGE_Withdraw2Handle; * In this case, the callback is not called. */ struct TALER_EXCHANGE_Withdraw2Handle * -TALER_EXCHANGE_withdraw2 (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_PlanchetDetail *pd, - const struct TALER_ReservePrivateKeyP *reserve_priv, - TALER_EXCHANGE_Withdraw2Callback res_cb, - void *res_cb_cls); +TALER_EXCHANGE_withdraw2 ( + struct GNUNET_CURL_Context *curl_ctx, + const char *exchange_url, + struct TALER_EXCHANGE_Keys *keys, + const struct TALER_PlanchetDetail *pd, + const struct TALER_ReservePrivateKeyP *reserve_priv, + TALER_EXCHANGE_Withdraw2Callback res_cb, + void *res_cb_cls); /** @@ -2401,20 +2751,67 @@ TALER_EXCHANGE_withdraw2_cancel (struct TALER_EXCHANGE_Withdraw2Handle *wh); /** + * Response from a batch-withdraw request (2nd variant). + */ +struct TALER_EXCHANGE_BatchWithdraw2Response +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * array of blind signatures over the coins. + */ + const struct TALER_BlindedDenominationSignature *blind_sigs; + + /** + * length of @e blind_sigs + */ + unsigned int blind_sigs_length; + + } ok; + + struct + { + /** + * Hash of the payto-URI of the account to KYC; + */ + struct TALER_PaytoHashP h_payto; + + /** + * ID identifying the KYC requirement to withdraw. + */ + uint64_t kyc_requirement_id; + + } unavailable_for_legal_reasons; + + } details; + +}; + + +/** * Callbacks of this type are used to serve the result of submitting a batch * withdraw request to a exchange without the (un)blinding factor. * * @param cls closure - * @param hr HTTP response data - * @param blind_sigs array of blind signatures over the coins, NULL on error - * @param blind_sigs_length length of @a blind_sigs + * @param bw2r response data */ typedef void (*TALER_EXCHANGE_BatchWithdraw2Callback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_BlindedDenominationSignature *blind_sigs, - unsigned int blind_sigs_length); + const struct TALER_EXCHANGE_BatchWithdraw2Response *bw2r); /** @@ -2437,7 +2834,9 @@ struct TALER_EXCHANGE_BatchWithdraw2Handle; * disk before calling, and be ready to repeat the request with the * same arguments in case of failures. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param curl_ctx The curl context to use + * @param exchange_url The base-URL of the exchange + * @param keys The /keys material from the exchange * @param pds array of planchet details of the planchet to withdraw * @param pds_length number of entries in the @a pds array * @param reserve_priv private key of the reserve to withdraw from @@ -2449,10 +2848,12 @@ struct TALER_EXCHANGE_BatchWithdraw2Handle; */ struct TALER_EXCHANGE_BatchWithdraw2Handle * TALER_EXCHANGE_batch_withdraw2 ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *curl_ctx, + const char *exchange_url, + const struct TALER_EXCHANGE_Keys *keys, const struct TALER_ReservePrivateKeyP *reserve_priv, - const struct TALER_PlanchetDetail *pds, unsigned int pds_length, + const struct TALER_PlanchetDetail pds[static pds_length], TALER_EXCHANGE_BatchWithdraw2Callback res_cb, void *res_cb_cls); @@ -2468,13 +2869,425 @@ TALER_EXCHANGE_batch_withdraw2_cancel ( struct TALER_EXCHANGE_BatchWithdraw2Handle *wh); +/* ********************* /reserve/$RESERVE_PUB/age-withdraw *************** */ + +/** + * @brief Information needed to withdraw (and reveal) age restricted coins. + */ +struct TALER_EXCHANGE_AgeWithdrawCoinInput +{ + /** + * The master secret from which we derive all other relevant values for + * the coin: private key, nonces (if applicable) and age restriction + */ + struct TALER_PlanchetMasterSecretP secrets[TALER_CNC_KAPPA]; + + /** + * The denomination of the coin. Must support age restriction, i.e + * its .keys.age_mask MUST not be 0 + */ + struct TALER_EXCHANGE_DenomPublicKey *denom_pub; +}; + + +/** + * All the details about a coin that are generated during age-withdrawal and + * that may be needed for future operations on the coin. + */ +struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails +{ + /** + * Private key of the coin. + */ + struct TALER_CoinSpendPrivateKeyP coin_priv; + + /** + * Hash of the public key of the coin. + */ + struct TALER_CoinPubHashP h_coin_pub; + + /** + * Value used to blind the key for the signature. + * Needed for recoup operations. + */ + union GNUNET_CRYPTO_BlindingSecretP blinding_key; + + /** + * The age commitment, proof for the coin, derived from the + * Master secret and maximum age in the originating request + */ + struct TALER_AgeCommitmentProof age_commitment_proof; + + /** + * The hash of the age commitment + */ + struct TALER_AgeCommitmentHash h_age_commitment; + + /** + * Values contributed from the exchange during the + * withdraw protocol. + */ + struct TALER_ExchangeWithdrawValues alg_values; + + /** + * The planchet constructed + */ + struct TALER_PlanchetDetail planchet; +}; + +/** + * @brief A handle to a /reserves/$RESERVE_PUB/age-withdraw request + */ +struct TALER_EXCHANGE_AgeWithdrawHandle; + +/** + * @brief Details about the response for a age withdraw request. + */ +struct TALER_EXCHANGE_AgeWithdrawResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details about the response + */ + union + { + /** + * Details if the status is #MHD_HTTP_OK. + */ + struct + { + /** + * Index that should not be revealed during the age-withdraw reveal + * phase. + */ + uint8_t noreveal_index; + + /** + * The commitment of the age-withdraw request, needed for the + * subsequent call to /age-withdraw/$ACH/reveal + */ + struct TALER_AgeWithdrawCommitmentHashP h_commitment; + + /** + * The number of elements in @e coins, each referring to + * TALER_CNC_KAPPA elements + */ + size_t num_coins; + + /** + * The computed details of the non-revealed @e num_coins coins to keep. + */ + const struct TALER_EXCHANGE_AgeWithdrawCoinPrivateDetails *coin_details; + + /** + * The array of blinded hashes of the non-revealed + * @e num_coins coins, needed for the reveal step; + */ + const struct TALER_BlindedCoinHashP *blinded_coin_hs; + + /** + * Key used by the exchange to sign the response. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + } ok; + } details; +}; + + +typedef void +(*TALER_EXCHANGE_AgeWithdrawCallback)( + void *cls, + const struct TALER_EXCHANGE_AgeWithdrawResponse *awr); + +/** + * Submit an age-withdraw request to the exchange and get the exchange's + * response. + * + * This API is typically used by a wallet. Note that to ensure that + * no money is lost in case of hardware failures, the provided + * argument @a rd should be committed to persistent storage + * prior to calling this function. + * + * @param curl_ctx The curl context + * @param exchange_url The base url of the exchange + * @param keys The denomination keys from the exchange + * @param reserve_priv The private key to the reserve + * @param num_coins The number of elements in @e coin_inputs + * @param coin_inputs The input for the coins to withdraw + * @param max_age The maximum age we commit to. + * @param res_cb A callback for the result, maybe NULL + * @param res_cb_cls A closure for @e res_cb, maybe NULL + * @return a handle for this request; NULL if the argument was invalid. + * In this case, the callback will not be called. + */ +struct TALER_EXCHANGE_AgeWithdrawHandle * +TALER_EXCHANGE_age_withdraw ( + struct GNUNET_CURL_Context *curl_ctx, + struct TALER_EXCHANGE_Keys *keys, + const char *exchange_url, + const struct TALER_ReservePrivateKeyP *reserve_priv, + size_t num_coins, + const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[static + num_coins], + uint8_t max_age, + TALER_EXCHANGE_AgeWithdrawCallback res_cb, + void *res_cb_cls); + +/** + * Cancel a age-withdraw request. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param awh the age-withdraw handle + */ +void +TALER_EXCHANGE_age_withdraw_cancel ( + struct TALER_EXCHANGE_AgeWithdrawHandle *awh); + + +/**++++++ age-withdraw with pre-blinded planchets ***************************/ + +/** + * @brief Information needed to withdraw (and reveal) age restricted coins. + */ +struct TALER_EXCHANGE_AgeWithdrawBlindedInput +{ + /** + * The denomination of the coin. Must support age restriction, i.e + * its .keys.age_mask MUST not be 0 + */ + const struct TALER_EXCHANGE_DenomPublicKey *denom_pub; + + /** + * Blinded Planchets + */ + struct TALER_PlanchetDetail planchet_details[TALER_CNC_KAPPA]; +}; + +/** + * Response from an age-withdraw request with pre-blinded planchets + */ +struct TALER_EXCHANGE_AgeWithdrawBlindedResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * Index that should not be revealed during the age-withdraw reveal phase. + * The struct TALER_PlanchetMasterSecretP * from the request + * with this index are the ones to keep. + */ + uint8_t noreveal_index; + + /** + * The commitment of the call to age-withdraw, needed for the subsequent + * call to /age-withdraw/$ACH/reveal. + */ + struct TALER_AgeWithdrawCommitmentHashP h_commitment; + + /** + * Key used by the exchange to sign the response. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + } ok; + } details; + +}; + + +/** + * Callbacks of this type are used to serve the result of submitting an + * age-withdraw request to a exchange with pre-blinded planchets + * without the (un)blinding factor. + * + * @param cls closure + * @param awbr response data + */ +typedef void +(*TALER_EXCHANGE_AgeWithdrawBlindedCallback) ( + void *cls, + const struct TALER_EXCHANGE_AgeWithdrawBlindedResponse *awbr); + + +/** + * @brief A /reserves/$RESERVE_PUB/age-withdraw Handle, 2nd variant with + * pre-blinded planchets. + * + * This variant does not do the blinding/unblinding and only + * fetches the blind signatures on the already blinded planchets. + * Used internally by the `struct TALER_EXCHANGE_BatchWithdrawHandle` + * implementation as well as for the reward logic of merchants. + */ +struct TALER_EXCHANGE_AgeWithdrawBlindedHandle; + +/** + * Withdraw age-restricted coins from the exchange using a + * /reserves/$RESERVE_PUB/age-withdraw request. This API is typically used + * by a merchant to withdraw a reward where the planchets are pre-blinded and + * the blinding factor is unknown to the merchant. + * + * Note that to ensure that no money is lost in case of hardware + * failures, the caller must have committed (most of) the arguments to + * disk before calling, and be ready to repeat the request with the + * same arguments in case of failures. + * + * @param curl_ctx The curl context to use + * @param exchange_url The base-URL of the exchange + * @param keys The /keys material from the exchange + * @param max_age The maximum age that the coins are committed to. + * @param num_input number of entries in the @a blinded_input array + * @param blinded_input array of planchet details of the planchet to withdraw + * @param reserve_priv private key of the reserve to withdraw from + * @param res_cb the callback to call when the final result for this request is available + * @param res_cb_cls closure for @a res_cb + * @return NULL + * if the inputs are invalid (i.e. denomination key not with this exchange). + * In this case, the callback is not called. + */ +struct TALER_EXCHANGE_AgeWithdrawBlindedHandle * +TALER_EXCHANGE_age_withdraw_blinded ( + struct GNUNET_CURL_Context *curl_ctx, + struct TALER_EXCHANGE_Keys *keys, + const char *exchange_url, + const struct TALER_ReservePrivateKeyP *reserve_priv, + uint8_t max_age, + unsigned int num_input, + const struct TALER_EXCHANGE_AgeWithdrawBlindedInput blinded_input[static + num_input], + TALER_EXCHANGE_AgeWithdrawBlindedCallback res_cb, + void *res_cb_cls); + + +/** + * Cancel an age-withdraw request. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param awbh the age-withdraw handle + */ +void +TALER_EXCHANGE_age_withdraw_blinded_cancel ( + struct TALER_EXCHANGE_AgeWithdrawBlindedHandle *awbh); + + +/* ********************* /age-withdraw/$ACH/reveal ************************ */ + +/** + * @brief A handle to a /age-withdraw/$ACH/reveal request + */ +struct TALER_EXCHANGE_AgeWithdrawRevealHandle; + +/** + * The response from a /age-withdraw/$ACH/reveal request + */ +struct TALER_EXCHANGE_AgeWithdrawRevealResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details about the response + */ + union + { + /** + * Details if the status is #MHD_HTTP_OK. + */ + struct + { + /** + * Number of signatures returned. + */ + unsigned int num_sigs; + + /** + * Array of @e num_coins blinded denomination signatures, giving each + * coin its value and validity. The array give these coins in the same + * order (and should have the same length) in which the original + * age-withdraw request specified the respective denomination keys. + */ + const struct TALER_BlindedDenominationSignature *blinded_denom_sigs; + + } ok; + } details; + +}; + +typedef void +(*TALER_EXCHANGE_AgeWithdrawRevealCallback)( + void *cls, + const struct TALER_EXCHANGE_AgeWithdrawRevealResponse *awr); + +/** + * Submit an age-withdraw-reveal request to the exchange and get the exchange's + * response. + * + * This API is typically used by a wallet. Note that to ensure that + * no money is lost in case of hardware failures, the provided + * argument @a rd should be committed to persistent storage + * prior to calling this function. + * + * @param curl_ctx The curl context + * @param exchange_url The base url of the exchange + * @param num_coins The number of elements in @e coin_inputs and @e alg_values + * @param coin_inputs The input for the coins to withdraw, same as in the previous call to /age-withdraw + * @param noreveal_index The index into each of the kappa coin candidates, that should not be revealed to the exchange + * @param h_commitment The commmitment from the previous call to /age-withdraw + * @param reserve_pub The public key of the reserve the original call to /age-withdraw was made to + * @param res_cb A callback for the result, maybe NULL + * @param res_cb_cls A closure for @e res_cb, maybe NULL + * @return a handle for this request; NULL if the argument was invalid. + * In this case, the callback will not be called. + */ +struct TALER_EXCHANGE_AgeWithdrawRevealHandle * +TALER_EXCHANGE_age_withdraw_reveal ( + struct GNUNET_CURL_Context *curl_ctx, + const char *exchange_url, + size_t num_coins, + const struct TALER_EXCHANGE_AgeWithdrawCoinInput coin_inputs[static + num_coins], + uint8_t noreveal_index, + const struct TALER_AgeWithdrawCommitmentHashP *h_commitment, + const struct TALER_ReservePublicKeyP *reserve_pub, + TALER_EXCHANGE_AgeWithdrawRevealCallback res_cb, + void *res_cb_cls); + + +/** + * @brief Cancel an age-withdraw-reveal request + * + * @param awrh Handle to an age-withdraw-reqveal request + */ +void +TALER_EXCHANGE_age_withdraw_reveal_cancel ( + struct TALER_EXCHANGE_AgeWithdrawRevealHandle *awrh); + + /* ********************* /refresh/melt+reveal ***************************** */ /** * Information needed to melt (partially spent) coins to obtain fresh coins * that are unlinkable to the original coin(s). Note that melting more than - * one coin in a single request will make those coins linkable, so we only melt one coin at a time. + * one coin in a single request will make those coins linkable, so we only melt + * one coin at a time. */ struct TALER_EXCHANGE_RefreshData { @@ -2483,11 +3296,16 @@ struct TALER_EXCHANGE_RefreshData */ struct TALER_CoinSpendPrivateKeyP melt_priv; - /* - * age commitment and proof and its hash that went into the original coin, + /** + * age commitment and proof that went into the original coin, * might be NULL. */ const struct TALER_AgeCommitmentProof *melt_age_commitment_proof; + + /** + * Hash of age commitment and proof that went into the original coin, + * might be NULL. + */ const struct TALER_AgeCommitmentHash *melt_h_age_commitment; /** @@ -2583,7 +3401,7 @@ struct TALER_EXCHANGE_MeltResponse * Gamma value chosen by the exchange. */ uint32_t noreveal_index; - } success; + } ok; } details; }; @@ -2613,7 +3431,9 @@ typedef void * argument @a rd should be committed to persistent storage * prior to calling this function. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param rms the fresh secret that defines the refresh operation * @param rd the refresh data specifying the characteristics of the operation * @param melt_cb the callback to call with the result @@ -2622,11 +3442,14 @@ typedef void * In this case, neither callback will be called. */ struct TALER_EXCHANGE_MeltHandle * -TALER_EXCHANGE_melt (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_RefreshMasterSecretP *rms, - const struct TALER_EXCHANGE_RefreshData *rd, - TALER_EXCHANGE_MeltCallback melt_cb, - void *melt_cb_cls); +TALER_EXCHANGE_melt ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, + const struct TALER_RefreshMasterSecretP *rms, + const struct TALER_EXCHANGE_RefreshData *rd, + TALER_EXCHANGE_MeltCallback melt_cb, + void *melt_cb_cls); /** @@ -2661,12 +3484,12 @@ struct TALER_EXCHANGE_RevealedCoinInfo * Age commitment and its hash of the coin, might be NULL. */ struct TALER_AgeCommitmentProof *age_commitment_proof; - struct TALER_AgeCommitmentHash *h_age_commitment; + struct TALER_AgeCommitmentHash h_age_commitment; /** * Blinding keys used to blind the fresh coin. */ - union TALER_DenominationBlindingKeyP bks; + union GNUNET_CRYPTO_BlindingSecretP bks; /** * Signature affirming the validity of the coin. @@ -2709,7 +3532,7 @@ struct TALER_EXCHANGE_RevealResult * Number of coins returned. */ unsigned int num_coins; - } success; + } ok; } details; @@ -2746,7 +3569,8 @@ struct TALER_EXCHANGE_RefreshesRevealHandle; * arguments should have been committed to persistent storage * prior to calling this function. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL * @param rms the fresh secret that defines the refresh operation * @param rd the refresh data that characterizes the refresh operation * @param num_coins number of fresh coins to be created, length of the @a exchange_vals array, must match value in @a rd @@ -2761,11 +3585,12 @@ struct TALER_EXCHANGE_RefreshesRevealHandle; */ struct TALER_EXCHANGE_RefreshesRevealHandle * TALER_EXCHANGE_refreshes_reveal ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, const struct TALER_RefreshMasterSecretP *rms, const struct TALER_EXCHANGE_RefreshData *rd, unsigned int num_coins, - const struct TALER_ExchangeWithdrawValues *alg_values, + const struct TALER_ExchangeWithdrawValues alg_values[static num_coins], uint32_t noreveal_index, TALER_EXCHANGE_RefreshesRevealCallback reveal_cb, void *reveal_cb_cls); @@ -2802,10 +3627,11 @@ struct TALER_EXCHANGE_LinkedCoinInfo struct TALER_CoinSpendPrivateKeyP coin_priv; /** - * Age commitment and its hash, if applicable. Might be NULL. + * Age commitment and its hash, if applicable. */ - struct TALER_AgeCommitmentProof *age_commitment_proof; - struct TALER_AgeCommitmentHash *h_age_commitment; + bool has_age_commitment; + struct TALER_AgeCommitmentProof age_commitment_proof; + struct TALER_AgeCommitmentHash h_age_commitment; /** * Master secret of this coin. @@ -2855,7 +3681,7 @@ struct TALER_EXCHANGE_LinkResult * Number of coins returned. */ unsigned int num_coins; - } success; + } ok; } details; @@ -2883,7 +3709,8 @@ typedef void * This API is typically not used by anyone, it is more a threat against those * trying to receive a funds transfer by abusing the refresh protocol. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx CURL context + * @param url exchange base URL * @param coin_priv private key to request link data for * @param age_commitment_proof age commitment to the corresponding coin, might be NULL * @param link_cb the callback to call with the useful result of the @@ -2893,7 +3720,8 @@ typedef void */ struct TALER_EXCHANGE_LinkHandle * TALER_EXCHANGE_link ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, const struct TALER_CoinSpendPrivateKeyP *coin_priv, const struct TALER_AgeCommitmentProof *age_commitment_proof, TALER_EXCHANGE_LinkCallback link_cb, @@ -2968,25 +3796,52 @@ struct TALER_EXCHANGE_TransferData /** + * Response for a GET /transfers request. + */ +struct TALER_EXCHANGE_TransfersGetResponse +{ + /** + * HTTP response. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on HTTP status code. + */ + union + { + /** + * Details if status code is #MHD_HTTP_OK. + */ + struct + { + struct TALER_EXCHANGE_TransferData td; + } ok; + + } details; +}; + + +/** * Function called with detailed wire transfer data, including all * of the coin transactions that were combined into the wire transfer. * * @param cls closure - * @param hr HTTP response data - * @param ta transfer data, (set only if @a http_status is #MHD_HTTP_OK, otherwise NULL) + * @param tgr response data */ typedef void (*TALER_EXCHANGE_TransfersGetCallback)( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_TransferData *ta); + const struct TALER_EXCHANGE_TransfersGetResponse *tgr); /** * Query the exchange about which transactions were combined * to create a wire transfer. * - * @param exchange exchange to query + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param wtid raw wire transfer identifier to get information about * @param cb callback to call * @param cb_cls closure for @a cb @@ -2994,7 +3849,9 @@ typedef void */ struct TALER_EXCHANGE_TransfersGetHandle * TALER_EXCHANGE_transfers_get ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_WireTransferIdentifierRawP *wtid, TALER_EXCHANGE_TransfersGetCallback cb, void *cb_cls); @@ -3071,12 +3928,7 @@ struct TALER_EXCHANGE_GetDepositResponse */ struct TALER_Amount coin_contribution; - /** - * Payment target that the merchant should use - * to check for its KYC status. - */ - uint64_t payment_target_uuid; - } success; + } ok; /** * Response if the status was #MHD_HTTP_ACCEPTED @@ -3090,10 +3942,16 @@ struct TALER_EXCHANGE_GetDepositResponse struct GNUNET_TIME_Timestamp execution_time; /** - * Payment target that the merchant should use - * to check for its KYC status. + * KYC legitimization requirement that the merchant should use to check + * for its KYC status. + */ + uint64_t requirement_row; + + /** + * Current AML state for the account. May explain why transfers are + * not happening. */ - uint64_t payment_target_uuid; + enum TALER_AmlDecisionState aml_decision; /** * Set to 'true' if the KYC check is already finished and @@ -3123,22 +3981,28 @@ typedef void * which aggregate wire transfer the deposit operation identified by @a coin_pub, * @a merchant_priv and @a h_contract_terms contributed to. * - * @param exchange the exchange to query + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param merchant_priv the merchant's private key * @param h_wire hash of merchant's wire transfer details * @param h_contract_terms hash of the proposal data * @param coin_pub public key of the coin + * @param timeout timeout to use for long-polling, 0 for no long polling * @param cb function to call with the result * @param cb_cls closure for @a cb * @return handle to abort request */ struct TALER_EXCHANGE_DepositGetHandle * TALER_EXCHANGE_deposits_get ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_MerchantPrivateKeyP *merchant_priv, const struct TALER_MerchantWireHashP *h_wire, const struct TALER_PrivateContractHashP *h_contract_terms, const struct TALER_CoinSpendPublicKeyP *coin_pub, + struct GNUNET_TIME_Relative timeout, TALER_EXCHANGE_DepositGetCallback cb, void *cb_cls); @@ -3154,72 +4018,44 @@ TALER_EXCHANGE_deposits_get_cancel ( struct TALER_EXCHANGE_DepositGetHandle *dwh); -/** - * Convenience function. Verifies a coin's transaction history as - * returned by the exchange. - * - * @param dk fee structure for the coin - * @param coin_pub public key of the coin - * @param history history of the coin in json encoding - * @param[out] total how much of the coin has been spent according to @a history - * @return #GNUNET_OK if @a history is valid, #GNUNET_SYSERR if not - */ -enum GNUNET_GenericReturnValue -TALER_EXCHANGE_verify_coin_history ( - const struct TALER_EXCHANGE_DenomPublicKey *dk, - const struct TALER_CoinSpendPublicKeyP *coin_pub, - json_t *history, - struct TALER_Amount *total); +/* ********************* /recoup *********************** */ /** - * Parse history given in JSON format and return it in binary - * format. - * - * @param exchange connection to the exchange we can use - * @param history JSON array with the history - * @param reserve_pub public key of the reserve to inspect - * @param currency currency we expect the balance to be in - * @param[out] total_in set to value of credits to reserve - * @param[out] total_out set to value of debits from reserve - * @param history_length number of entries in @a history - * @param[out] rhistory array of length @a history_length, set to the - * parsed history entries - * @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 + * @brief A /recoup Handle */ -enum GNUNET_GenericReturnValue -TALER_EXCHANGE_parse_reserve_history ( - struct TALER_EXCHANGE_Handle *exchange, - const json_t *history, - const struct TALER_ReservePublicKeyP *reserve_pub, - const char *currency, - struct TALER_Amount *total_in, - struct TALER_Amount *total_out, - unsigned int history_length, - struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory); +struct TALER_EXCHANGE_RecoupHandle; /** - * Free memory (potentially) allocated by #TALER_EXCHANGE_parse_reserve_history(). - * - * @param rhistory result to free - * @param len number of entries in @a rhistory + * Response from a recoup request. */ -void -TALER_EXCHANGE_free_reserve_history ( - struct TALER_EXCHANGE_ReserveHistoryEntry *rhistory, - unsigned int len); - +struct TALER_EXCHANGE_RecoupResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; -/* ********************* /recoup *********************** */ + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * public key of the reserve receiving the recoup + */ + struct TALER_ReservePublicKeyP reserve_pub; + } ok; + } details; -/** - * @brief A /recoup Handle - */ -struct TALER_EXCHANGE_RecoupHandle; +}; /** @@ -3229,14 +4065,12 @@ struct TALER_EXCHANGE_RecoupHandle; * reserve that was credited. * * @param cls closure - * @param hr HTTP response data - * @param reserve_pub public key of the reserve receiving the recoup + * @param rr response data */ typedef void (*TALER_EXCHANGE_RecoupResultCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_ReservePublicKeyP *reserve_pub); + const struct TALER_EXCHANGE_RecoupResponse *rr); /** @@ -3244,7 +4078,9 @@ typedef void * the emergency recoup protocol for a given denomination. The value * of the coin will be refunded to the original customer (without fees). * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param pk kind of coin to pay back * @param denom_sig signature over the coin by the exchange using @a pk * @param exchange_vals contribution from the exchange on the withdraw @@ -3256,13 +4092,16 @@ typedef void * In this case, the callback is not called. */ struct TALER_EXCHANGE_RecoupHandle * -TALER_EXCHANGE_recoup (struct TALER_EXCHANGE_Handle *exchange, - const struct TALER_EXCHANGE_DenomPublicKey *pk, - const struct TALER_DenominationSignature *denom_sig, - const struct TALER_ExchangeWithdrawValues *exchange_vals, - const struct TALER_PlanchetMasterSecretP *ps, - TALER_EXCHANGE_RecoupResultCallback recoup_cb, - void *recoup_cb_cls); +TALER_EXCHANGE_recoup ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, + const struct TALER_EXCHANGE_DenomPublicKey *pk, + const struct TALER_DenominationSignature *denom_sig, + const struct TALER_ExchangeWithdrawValues *exchange_vals, + const struct TALER_PlanchetMasterSecretP *ps, + TALER_EXCHANGE_RecoupResultCallback recoup_cb, + void *recoup_cb_cls); /** @@ -3285,18 +4124,47 @@ struct TALER_EXCHANGE_RecoupRefreshHandle; /** + * Response from a /recoup-refresh request. + */ +struct TALER_EXCHANGE_RecoupRefreshResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * public key of the dirty coin that was credited + */ + struct TALER_CoinSpendPublicKeyP old_coin_pub; + + } ok; + } details; + +}; + + +/** * Callbacks of this type are used to return the final result of * submitting a recoup-refresh request to a exchange. * * @param cls closure - * @param hr HTTP response data - * @param old_coin_pub public key of the dirty coin that was credited + * @param rrr response data */ typedef void (*TALER_EXCHANGE_RecoupRefreshResultCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_CoinSpendPublicKeyP *old_coin_pub); + const struct TALER_EXCHANGE_RecoupRefreshResponse *rrr); /** @@ -3306,7 +4174,9 @@ typedef void * revoked coin was refreshed from. The original coin is then * considered a zombie. * - * @param exchange the exchange handle; the exchange must be ready to operate + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param pk kind of coin to pay back * @param denom_sig signature over the coin by the exchange using @a pk * @param exchange_vals contribution from the exchange on the withdraw @@ -3321,7 +4191,9 @@ typedef void */ struct TALER_EXCHANGE_RecoupRefreshHandle * TALER_EXCHANGE_recoup_refresh ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_EXCHANGE_DenomPublicKey *pk, const struct TALER_DenominationSignature *denom_sig, const struct TALER_ExchangeWithdrawValues *exchange_vals, @@ -3376,6 +4248,11 @@ struct TALER_EXCHANGE_KycStatus { /** + * Details about which KYC check(s) were passed. + */ + const json_t *kyc_details; + + /** * Time of the affirmation. */ struct GNUNET_TIME_Timestamp timestamp; @@ -3392,14 +4269,45 @@ struct TALER_EXCHANGE_KycStatus */ struct TALER_ExchangeSignatureP exchange_sig; - } kyc_ok; + /** + * AML status for the account. + */ + enum TALER_AmlDecisionState aml_status; + + } ok; /** - * URL the user should open in a browser if - * the KYC process is to be run. Returned if - * @e http_status is #MHD_HTTP_ACCEPTED. + * KYC is required. */ - const char *kyc_url; + struct + { + + /** + * URL the user should open in a browser if + * the KYC process is to be run. Returned if + * @e http_status is #MHD_HTTP_ACCEPTED. + */ + const char *kyc_url; + + /** + * AML status for the account. + */ + enum TALER_AmlDecisionState aml_status; + + } accepted; + + /** + * KYC is OK, but account needs positive AML decision. + */ + struct + { + + /** + * AML status for the account. + */ + enum TALER_AmlDecisionState aml_status; + + } unavailable_for_legal_reasons; } details; @@ -3421,21 +4329,28 @@ typedef void * Run interaction with exchange to check KYC status * of a merchant. * - * @param eh exchange handle to use - * @param payment_target number identifying the target + * @param ctx CURL context + * @param url exchange base URL + * @param keys keys of the exchange + * @param requirement_row number identifying the KYC requirement * @param h_payto hash of the payto:// URI at @a payment_target + * @param ut type of the entity performing the KYC check * @param timeout how long to wait for a positive KYC status * @param cb function to call with the result * @param cb_cls closure for @a cb * @return NULL on error */ struct TALER_EXCHANGE_KycCheckHandle * -TALER_EXCHANGE_kyc_check (struct TALER_EXCHANGE_Handle *eh, - uint64_t payment_target, - const struct TALER_PaytoHashP *h_payto, - struct GNUNET_TIME_Relative timeout, - TALER_EXCHANGE_KycStatusCallback cb, - void *cb_cls); +TALER_EXCHANGE_kyc_check ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, + uint64_t requirement_row, + const struct TALER_PaytoHashP *h_payto, + enum TALER_KYCLOGIC_KycUserType ut, + struct GNUNET_TIME_Relative timeout, + TALER_EXCHANGE_KycStatusCallback cb, + void *cb_cls); /** @@ -3498,21 +4413,25 @@ struct TALER_EXCHANGE_KycProofHandle; /** * Run interaction with exchange to provide proof of KYC status. * - * @param eh exchange handle to use + * @param ctx CURL context + * @param url exchange base URL * @param h_payto hash of payto URI identifying the target account - * @param code OAuth 2.0 code argument - * @param state OAuth 2.0 state argument + * @param logic name of the KYC logic to run + * @param args additional args to pass, can be NULL + * or a string to append to the URL. Must then begin with '&'. * @param cb function to call with the result * @param cb_cls closure for @a cb * @return NULL on error */ struct TALER_EXCHANGE_KycProofHandle * -TALER_EXCHANGE_kyc_proof (struct TALER_EXCHANGE_Handle *eh, - const struct TALER_PaytoHashP *h_payto, - const char *code, - const char *state, - TALER_EXCHANGE_KycProofCallback cb, - void *cb_cls); +TALER_EXCHANGE_kyc_proof ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_PaytoHashP *h_payto, + const char *logic, + const char *args, + TALER_EXCHANGE_KycProofCallback cb, + void *cb_cls); /** @@ -3547,10 +4466,29 @@ struct TALER_EXCHANGE_WalletKycResponse enum TALER_ErrorCode ec; /** - * Wallet's payment target UUID. Only valid if - * @e http_status is #MHD_HTTP_OK + * Variants depending on @e http_status. */ - uint64_t payment_target_uuid; + union + { + + /** + * In case @e http_status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. + */ + struct + { + /** + * Wallet's KYC requirement row. + */ + uint64_t requirement_row; + + /** + * Hash of the payto-URI identifying the wallet to KYC. + */ + struct TALER_PaytoHashP h_payto; + + } unavailable_for_legal_reasons; + + } details; }; @@ -3571,17 +4509,22 @@ typedef void * Run interaction with exchange to find out the wallet's KYC * identifier. * - * @param eh exchange handle to use + * @param ctx CURL context + * @param url exchange base URL * @param reserve_priv wallet private key to check + * @param balance balance (or balance threshold) crossed by the wallet * @param cb function to call with the result * @param cb_cls closure for @a cb * @return NULL on error */ struct TALER_EXCHANGE_KycWalletHandle * -TALER_EXCHANGE_kyc_wallet (struct TALER_EXCHANGE_Handle *eh, - const struct TALER_ReservePrivateKeyP *reserve_priv, - TALER_EXCHANGE_KycWalletCallback cb, - void *cb_cls); +TALER_EXCHANGE_kyc_wallet ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_ReservePrivateKeyP *reserve_priv, + const struct TALER_Amount *balance, + TALER_EXCHANGE_KycWalletCallback cb, + void *cb_cls); /** @@ -3746,18 +4689,47 @@ struct TALER_EXCHANGE_FutureKeys /** + * Response from a /management/keys request. + */ +struct TALER_EXCHANGE_ManagementGetKeysResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Response details depending on the HTTP status. + */ + union + { + /** + * Details if HTTP status is #MHD_HTTP_OK. + */ + struct + { + /** + * information about the various keys used + * by the exchange + */ + struct TALER_EXCHANGE_FutureKeys keys; + + } ok; + } details; + +}; + + +/** * Function called with information about future keys. * * @param cls closure - * @param hr HTTP response data - * @param keys information about the various keys used - * by the exchange, NULL if /management/keys failed + * @param mgr HTTP response data */ typedef void (*TALER_EXCHANGE_ManagementGetKeysCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr, - const struct TALER_EXCHANGE_FutureKeys *keys); + const struct TALER_EXCHANGE_ManagementGetKeysResponse *mgr); /** @@ -3777,10 +4749,11 @@ struct TALER_EXCHANGE_ManagementGetKeysHandle; * @return the request handle; NULL upon error */ struct TALER_EXCHANGE_ManagementGetKeysHandle * -TALER_EXCHANGE_get_management_keys (struct GNUNET_CURL_Context *ctx, - const char *url, - TALER_EXCHANGE_ManagementGetKeysCallback cb, - void *cb_cls); +TALER_EXCHANGE_get_management_keys ( + struct GNUNET_CURL_Context *ctx, + const char *url, + TALER_EXCHANGE_ManagementGetKeysCallback cb, + void *cb_cls); /** @@ -3860,15 +4833,28 @@ struct TALER_EXCHANGE_ManagementPostKeysData /** + * Response from a POST /management/keys request. + */ +struct TALER_EXCHANGE_ManagementPostKeysResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + +/** * Function called with information about the post keys operation result. * * @param cls closure - * @param hr HTTP response data + * @param mr response data */ typedef void (*TALER_EXCHANGE_ManagementPostKeysCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementPostKeysResponse *mr); /** @@ -3914,10 +4900,24 @@ TALER_EXCHANGE_post_management_keys_cancel ( */ struct TALER_EXCHANGE_ManagementPostExtensionsData { - json_t *extensions; + const json_t *extensions; struct TALER_MasterSignatureP extensions_sig; }; + +/** + * Response from a POST /management/extensions request. + */ +struct TALER_EXCHANGE_ManagementPostExtensionsResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + /** * Function called with information about the post extensions operation result. * @@ -3927,7 +4927,7 @@ struct TALER_EXCHANGE_ManagementPostExtensionsData typedef void (*TALER_EXCHANGE_ManagementPostExtensionsCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementPostExtensionsResponse *hr); /** * @brief Handle for a POST /management/extensions request. @@ -3950,7 +4950,7 @@ struct TALER_EXCHANGE_ManagementPostExtensionsHandle * TALER_EXCHANGE_management_post_extensions ( struct GNUNET_CURL_Context *ctx, const char *url, - struct TALER_EXCHANGE_ManagementPostExtensionsData *ped, + const struct TALER_EXCHANGE_ManagementPostExtensionsData *ped, TALER_EXCHANGE_ManagementPostExtensionsCallback cb, void *cb_cls); @@ -3966,6 +4966,19 @@ TALER_EXCHANGE_management_post_extensions_cancel ( /** + * Response from a POST /management/drain request. + */ +struct TALER_EXCHANGE_ManagementDrainResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + +/** * Function called with information about the drain profits result. * * @param cls closure @@ -3974,7 +4987,7 @@ TALER_EXCHANGE_management_post_extensions_cancel ( typedef void (*TALER_EXCHANGE_ManagementDrainProfitsCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementDrainResponse *hr); /** @@ -4023,6 +5036,19 @@ TALER_EXCHANGE_management_drain_profits_cancel ( /** + * Response from a POST /management/denominations/$DENOM/revoke request. + */ +struct TALER_EXCHANGE_ManagementRevokeDenominationResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + + +/** * Function called with information about the post revocation operation result. * * @param cls closure @@ -4031,7 +5057,7 @@ TALER_EXCHANGE_management_drain_profits_cancel ( typedef void (*TALER_EXCHANGE_ManagementRevokeDenominationKeyCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementRevokeDenominationResponse *hr); /** @@ -4072,6 +5098,18 @@ TALER_EXCHANGE_management_revoke_denomination_key_cancel ( /** + * Response from a POST /management/signkeys/$SK/revoke request. + */ +struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + +/** * Function called with information about the post revocation operation result. * * @param cls closure @@ -4080,7 +5118,7 @@ TALER_EXCHANGE_management_revoke_denomination_key_cancel ( typedef void (*TALER_EXCHANGE_ManagementRevokeSigningKeyCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementRevokeSigningKeyResponse *hr); /** @@ -4121,15 +5159,515 @@ TALER_EXCHANGE_management_revoke_signing_key_cancel ( /** - * Function called with information about the auditor setup operation result. + * Response from a POST /management/aml-officers request. + */ +struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse +{ + /** + * HTTP response data + */ + struct TALER_EXCHANGE_HttpResponse hr; + +}; + +/** + * Function called with information about the change to + * an AML officer status. * * @param cls closure * @param hr HTTP response data */ typedef void +(*TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback) ( + void *cls, + const struct TALER_EXCHANGE_ManagementUpdateAmlOfficerResponse *hr); + + +/** + * @brief Handle for a POST /management/aml-officers/$OFFICER_PUB request. + */ +struct TALER_EXCHANGE_ManagementUpdateAmlOfficer; + + +/** + * Inform the exchange that the status of an AML officer has changed. + * + * @param ctx the context + * @param url HTTP base URL for the exchange + * @param officer_pub the public signing key of the officer + * @param officer_name name of the officer + * @param change_date when to affect the status change + * @param is_active true to enable the officer + * @param read_only true to only allow read-only access + * @param master_sig signature affirming the change + * @param cb function to call with the exchange's result + * @param cb_cls closure for @a cb + * @return the request handle; NULL upon error + */ +struct TALER_EXCHANGE_ManagementUpdateAmlOfficer * +TALER_EXCHANGE_management_update_aml_officer ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_AmlOfficerPublicKeyP *officer_pub, + const char *officer_name, + struct GNUNET_TIME_Timestamp change_date, + bool is_active, + bool read_only, + const struct TALER_MasterSignatureP *master_sig, + TALER_EXCHANGE_ManagementUpdateAmlOfficerCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_management_update_aml_officer() operation. + * + * @param rh handle of the operation to cancel + */ +void +TALER_EXCHANGE_management_update_aml_officer_cancel ( + struct TALER_EXCHANGE_ManagementUpdateAmlOfficer *rh); + + +/** + * Summary data about an AML decision. + */ +struct TALER_EXCHANGE_AmlDecisionSummary +{ + /** + * What is the current monthly threshold. + */ + struct TALER_Amount threshold; + + /** + * Account the decision was made for. + */ + struct TALER_PaytoHashP h_payto; + + /** + * RowID of this decision. + */ + uint64_t rowid; + + /** + * Current decision state. + */ + enum TALER_AmlDecisionState current_state; +}; + + +/** + * Information about AML decisions returned by the exchange. + */ +struct TALER_EXCHANGE_AmlDecisionsResponse +{ + /** + * HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on the HTTP response code. + */ + union + { + + /** + * Information returned on success (#MHD_HTTP_OK). + */ + struct + { + + /** + * Array of AML decision summaries returned by the exchange. + */ + const struct TALER_EXCHANGE_AmlDecisionSummary *decisions; + + /** + * Length of the @e decisions array. + */ + unsigned int decisions_length; + + } ok; + + } details; +}; + + +/** + * Function called with summary information about + * AML decisions. + * + * @param cls closure + * @param adr response data + */ +typedef void +(*TALER_EXCHANGE_LookupAmlDecisionsCallback) ( + void *cls, + const struct TALER_EXCHANGE_AmlDecisionsResponse *adr); + + +/** + * @brief Handle for a POST /aml/$OFFICER_PUB/decisions/$STATUS request. + */ +struct TALER_EXCHANGE_LookupAmlDecisions; + + +/** + * Inform the exchange that an AML decision has been taken. + * + * @param ctx the context + * @param exchange_url HTTP base URL for the exchange + * @param start row number starting point (exclusive rowid) + * @param delta number of records to return, negative for descending, positive for ascending from start + * @param state type of AML decisions to return + * @param officer_priv private key of the deciding AML officer + * @param cb function to call with the exchange's result + * @param cb_cls closure for @a cb + * @return the request handle; NULL upon error + */ +struct TALER_EXCHANGE_LookupAmlDecisions * +TALER_EXCHANGE_lookup_aml_decisions ( + struct GNUNET_CURL_Context *ctx, + const char *exchange_url, + uint64_t start, + int delta, + enum TALER_AmlDecisionState state, + const struct TALER_AmlOfficerPrivateKeyP *officer_priv, + TALER_EXCHANGE_LookupAmlDecisionsCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_lookup_aml_decisions() operation. + * + * @param lh handle of the operation to cancel + */ +void +TALER_EXCHANGE_lookup_aml_decisions_cancel ( + struct TALER_EXCHANGE_LookupAmlDecisions *lh); + + +/** + * Detailed data about an AML decision. + */ +struct TALER_EXCHANGE_AmlDecisionDetail +{ + /** + * When was the decision made. + */ + struct GNUNET_TIME_Timestamp decision_time; + + /** + * New threshold set by this decision. + */ + struct TALER_Amount new_threshold; + + /** + * Who made the decision? + */ + struct TALER_AmlOfficerPublicKeyP decider_pub; + + /** + * Justification given for the decision. + */ + const char *justification; + + /** + * New decision state. + */ + enum TALER_AmlDecisionState new_state; +}; + + +/** + * Detailed data collected during a KYC process for the account. + */ +struct TALER_EXCHANGE_KycHistoryDetail +{ + /** + * Configuration section name of the KYC provider that contributed the data. + */ + const char *provider_section; + + /** + * The collected KYC data. + */ + const json_t *attributes; + + /** + * When was the data collection made. + */ + struct GNUNET_TIME_Timestamp collection_time; + +}; + + +/** + * Information about AML decision details returned by the exchange. + */ +struct TALER_EXCHANGE_AmlDecisionResponse +{ + /** + * HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on the HTTP response code. + */ + union + { + + /** + * Information returned on success (#MHD_HTTP_OK). + */ + struct + { + + /** + * Array of AML decision details returned by the exchange. + */ + const struct TALER_EXCHANGE_AmlDecisionDetail *aml_history; + + /** + * Length of the @e aml_history array. + */ + unsigned int aml_history_length; + + /** + * Array of KYC data collections returned by the exchange. + */ + const struct TALER_EXCHANGE_KycHistoryDetail *kyc_attributes; + + /** + * Length of the @e kyc_attributes array. + */ + unsigned int kyc_attributes_length; + + } ok; + + } details; +}; + + +/** + * Function called with summary information about + * AML decisions. + * + * @param cls closure + * @param adr response data + */ +typedef void +(*TALER_EXCHANGE_LookupAmlDecisionCallback) ( + void *cls, + const struct TALER_EXCHANGE_AmlDecisionResponse *adr); + + +/** + * @brief Handle for a POST /aml/$OFFICER_PUB/decision/$H_PAYTO request. + */ +struct TALER_EXCHANGE_LookupAmlDecision; + + +/** + * Inform the exchange that an AML decision has been taken. + * + * @param ctx the context + * @param exchange_url HTTP base URL for the exchange + * @param h_payto which account to return the decision history for + * @param officer_priv private key of the deciding AML officer + * @param history true to return the full history, otherwise only the last decision + * @param cb function to call with the exchange's result + * @param cb_cls closure for @a cb + * @return the request handle; NULL upon error + */ +struct TALER_EXCHANGE_LookupAmlDecision * +TALER_EXCHANGE_lookup_aml_decision ( + struct GNUNET_CURL_Context *ctx, + const char *exchange_url, + const struct TALER_PaytoHashP *h_payto, + const struct TALER_AmlOfficerPrivateKeyP *officer_priv, + bool history, + TALER_EXCHANGE_LookupAmlDecisionCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_lookup_aml_decision() operation. + * + * @param rh handle of the operation to cancel + */ +void +TALER_EXCHANGE_lookup_aml_decision_cancel ( + struct TALER_EXCHANGE_LookupAmlDecision *rh); + + +/** + * @brief Handle for a POST /aml-decision/$OFFICER_PUB request. + */ +struct TALER_EXCHANGE_AddAmlDecision; + + +/** + * Response when making an AML decision. + */ +struct TALER_EXCHANGE_AddAmlDecisionResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + + +/** + * Function called with information about storing an + * an AML decision. + * + * @param cls closure + * @param adr response data + */ +typedef void +(*TALER_EXCHANGE_AddAmlDecisionCallback) ( + void *cls, + const struct TALER_EXCHANGE_AddAmlDecisionResponse *adr); + +/** + * Inform the exchange that an AML decision has been taken. + * + * @param ctx the context + * @param url HTTP base URL for the exchange + * @param justification human-readable justification + * @param decision_time when was the decision made + * @param new_threshold at what monthly amount threshold + * should a revision be triggered + * @param h_payto payto URI hash of the account the + * decision is about + * @param new_state updated AML state + * @param kyc_requirements JSON array of KYC requirements being imposed, NULL for none + * @param officer_priv private key of the deciding AML officer + * @param cb function to call with the exchange's result + * @param cb_cls closure for @a cb + * @return the request handle; NULL upon error + */ +struct TALER_EXCHANGE_AddAmlDecision * +TALER_EXCHANGE_add_aml_decision ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const char *justification, + struct GNUNET_TIME_Timestamp decision_time, + const struct TALER_Amount *new_threshold, + const struct TALER_PaytoHashP *h_payto, + enum TALER_AmlDecisionState new_state, + const json_t *kyc_requirements, + const struct TALER_AmlOfficerPrivateKeyP *officer_priv, + TALER_EXCHANGE_AddAmlDecisionCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_add_aml_decision() operation. + * + * @param rh handle of the operation to cancel + */ +void +TALER_EXCHANGE_add_aml_decision_cancel ( + struct TALER_EXCHANGE_AddAmlDecision *rh); + + +/** + * Response when adding a partner exchange. + */ +struct TALER_EXCHANGE_ManagementAddPartnerResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + +/** + * Function called with information about the change to + * an AML officer status. + * + * @param cls closure + * @param apr response data + */ +typedef void +(*TALER_EXCHANGE_ManagementAddPartnerCallback) ( + void *cls, + const struct TALER_EXCHANGE_ManagementAddPartnerResponse *apr); + + +/** + * @brief Handle for a POST /management/partners/$PARTNER_PUB request. + */ +struct TALER_EXCHANGE_ManagementAddPartner; + + +/** + * Inform the exchange that the status of a partnering + * exchange was defined. + * + * @param ctx the context + * @param url HTTP base URL for the exchange + * @param partner_pub the offline signing key of the partner + * @param start_date validity period start + * @param end_date validity period end + * @param wad_frequency how often will we do wad transfers to this partner + * @param wad_fee what is the wad fee to this partner + * @param partner_base_url what is the base URL of the @a partner_pub exchange + * @param master_sig the signature the signature + * @param cb function to call with the exchange's result + * @param cb_cls closure for @a cb + * @return the request handle; NULL upon error + */ +struct TALER_EXCHANGE_ManagementAddPartner * +TALER_EXCHANGE_management_add_partner ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_MasterPublicKeyP *partner_pub, + struct GNUNET_TIME_Timestamp start_date, + struct GNUNET_TIME_Timestamp end_date, + struct GNUNET_TIME_Relative wad_frequency, + const struct TALER_Amount *wad_fee, + const char *partner_base_url, + const struct TALER_MasterSignatureP *master_sig, + TALER_EXCHANGE_ManagementAddPartnerCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_management_add_partner() operation. + * + * @param rh handle of the operation to cancel + */ +void +TALER_EXCHANGE_management_add_partner_cancel ( + struct TALER_EXCHANGE_ManagementAddPartner *rh); + + +/** + * Response when enabling an auditor. + */ +struct TALER_EXCHANGE_ManagementAuditorEnableResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + +/** + * Function called with information about the auditor setup operation result. + * + * @param cls closure + * @param aer response data + */ +typedef void (*TALER_EXCHANGE_ManagementAuditorEnableCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementAuditorEnableResponse *aer); /** @@ -4174,17 +5712,27 @@ void TALER_EXCHANGE_management_enable_auditor_cancel ( struct TALER_EXCHANGE_ManagementAuditorEnableHandle *ah); +/** + * Response when disabling an auditor. + */ +struct TALER_EXCHANGE_ManagementAuditorDisableResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; /** * Function called with information about the auditor disable operation result. * * @param cls closure - * @param hr HTTP response data + * @param adr HTTP response data */ typedef void (*TALER_EXCHANGE_ManagementAuditorDisableCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementAuditorDisableResponse *adr); /** @@ -4227,15 +5775,27 @@ TALER_EXCHANGE_management_disable_auditor_cancel ( /** + * Response from an exchange account/enable operation. + */ +struct TALER_EXCHANGE_ManagementWireEnableResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + + +/** * Function called with information about the wire enable operation result. * * @param cls closure - * @param hr HTTP response data + * @param wer HTTP response data */ typedef void (*TALER_EXCHANGE_ManagementWireEnableCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementWireEnableResponse *wer); /** @@ -4250,11 +5810,16 @@ struct TALER_EXCHANGE_ManagementWireEnableHandle; * @param ctx the context * @param url HTTP base URL for the exchange * @param payto_uri RFC 8905 URI of the exchange's bank account + * @param conversion_url URL of the conversion service, or NULL if none + * @param debit_restrictions JSON encoding of debit restrictions on the account; see AccountRestriction in the spec + * @param credit_restrictions JSON encoding of credit restrictions on the account; see AccountRestriction in the spec * @param validity_start when was this decided? * @param master_sig1 signature affirming the wire addition * of purpose #TALER_SIGNATURE_MASTER_ADD_WIRE * @param master_sig2 signature affirming the validity of the account for clients; * of purpose #TALER_SIGNATURE_MASTER_WIRE_DETAILS. + * @param bank_label label to use when showing the account, can be NULL + * @param priority priority for ordering the bank accounts * @param cb function to call with the exchange's result * @param cb_cls closure for @a cb * @return the request handle; NULL upon error @@ -4264,9 +5829,14 @@ TALER_EXCHANGE_management_enable_wire ( struct GNUNET_CURL_Context *ctx, const char *url, const char *payto_uri, + const char *conversion_url, + const json_t *debit_restrictions, + const json_t *credit_restrictions, struct GNUNET_TIME_Timestamp validity_start, const struct TALER_MasterSignatureP *master_sig1, const struct TALER_MasterSignatureP *master_sig2, + const char *bank_label, + int64_t priority, TALER_EXCHANGE_ManagementWireEnableCallback cb, void *cb_cls); @@ -4282,15 +5852,26 @@ TALER_EXCHANGE_management_enable_wire_cancel ( /** + * Response from an exchange account/disable operation. + */ +struct TALER_EXCHANGE_ManagementWireDisableResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + +/** * Function called with information about the wire disable operation result. * * @param cls closure - * @param hr HTTP response data + * @param wdr response data */ typedef void (*TALER_EXCHANGE_ManagementWireDisableCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementWireDisableResponse *wdr); /** @@ -4334,15 +5915,26 @@ TALER_EXCHANGE_management_disable_wire_cancel ( /** + * Response when setting wire fees. + */ +struct TALER_EXCHANGE_ManagementSetWireFeeResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + +/** * Function called with information about the wire enable operation result. * * @param cls closure - * @param hr HTTP response data + * @param wfr response data */ typedef void (*TALER_EXCHANGE_ManagementSetWireFeeCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementSetWireFeeResponse *wfr); /** @@ -4390,15 +5982,27 @@ TALER_EXCHANGE_management_set_wire_fees_cancel ( /** + * Response when setting global fees. + */ +struct TALER_EXCHANGE_ManagementSetGlobalFeeResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + + +/** * Function called with information about the global fee setting operation result. * * @param cls closure - * @param hr HTTP response data + * @param gfr HTTP response data */ typedef void (*TALER_EXCHANGE_ManagementSetGlobalFeeCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_ManagementSetGlobalFeeResponse *gfr); /** @@ -4416,7 +6020,6 @@ struct TALER_EXCHANGE_ManagementSetGlobalFeeHandle; * @param validity_end end date for the provided wire fees * @param fees the wire fees for this time period * @param purse_timeout when do purses time out - * @param kyc_timeout when do reserves without KYC time out * @param history_expiration how long are account histories preserved * @param purse_account_limit how many purses are free per account * @param master_sig signature affirming the wire fees; @@ -4433,7 +6036,6 @@ TALER_EXCHANGE_management_set_global_fees ( struct GNUNET_TIME_Timestamp validity_end, const struct TALER_GlobalFeeSet *fees, struct GNUNET_TIME_Relative purse_timeout, - struct GNUNET_TIME_Relative kyc_timeout, struct GNUNET_TIME_Relative history_expiration, uint32_t purse_account_limit, const struct TALER_MasterSignatureP *master_sig, @@ -4452,16 +6054,28 @@ TALER_EXCHANGE_management_set_global_fees_cancel ( /** + * Response when adding denomination signature by auditor. + */ +struct TALER_EXCHANGE_AuditorAddDenominationResponse +{ + /** + * HTTP response data. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + + +/** * Function called with information about the POST * /auditor/$AUDITOR_PUB/$H_DENOM_PUB operation result. * * @param cls closure - * @param hr HTTP response data + * @param adr HTTP response data */ typedef void (*TALER_EXCHANGE_AuditorAddDenominationCallback) ( void *cls, - const struct TALER_EXCHANGE_HttpResponse *hr); + const struct TALER_EXCHANGE_AuditorAddDenominationResponse *adr); /** @@ -4543,7 +6157,7 @@ struct TALER_EXCHANGE_ContractGetResponse */ size_t econtract_size; - } success; + } ok; } details; @@ -4570,7 +6184,8 @@ struct TALER_EXCHANGE_ContractsGetHandle; /** * Request information about a contract from the exchange. * - * @param exchange exchange handle + * @param ctx CURL context + * @param url exchange base URL * @param contract_priv private key of the contract * @param cb function to call with the exchange's result * @param cb_cls closure for @a cb @@ -4578,7 +6193,8 @@ struct TALER_EXCHANGE_ContractsGetHandle; */ struct TALER_EXCHANGE_ContractsGetHandle * TALER_EXCHANGE_contract_get ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, const struct TALER_ContractDiffiePrivateP *contract_priv, TALER_EXCHANGE_ContractGetCallback cb, void *cb_cls); @@ -4614,6 +6230,7 @@ struct TALER_EXCHANGE_PurseGetResponse */ struct { + /** * Time when the purse was merged (or zero if it * was not merged). @@ -4633,7 +6250,12 @@ struct TALER_EXCHANGE_PurseGetResponse */ struct TALER_Amount balance; - } success; + /** + * Time when the purse will expire. + */ + struct GNUNET_TIME_Timestamp purse_expiration; + + } ok; } details; @@ -4661,7 +6283,9 @@ struct TALER_EXCHANGE_PurseGetHandle; /** * Request information about a purse from the exchange. * - * @param exchange exchange handle + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param purse_pub public key of the purse * @param timeout how long to wait for a change to happen * @param wait_for_merge true to wait for a merge event, otherwise wait for a deposit event @@ -4671,7 +6295,9 @@ struct TALER_EXCHANGE_PurseGetHandle; */ struct TALER_EXCHANGE_PurseGetHandle * TALER_EXCHANGE_purse_get ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_PurseContractPublicKeyP *purse_pub, struct GNUNET_TIME_Relative timeout, bool wait_for_merge, @@ -4723,7 +6349,7 @@ struct TALER_EXCHANGE_PurseCreateDepositResponse struct TALER_ExchangeSignatureP exchange_sig; - } success; + } ok; } details; @@ -4749,7 +6375,7 @@ struct TALER_EXCHANGE_PurseCreateDepositHandle; /** - * Information about a coin to be deposited into a purse. + * Information about a coin to be deposited into a purse or reserve. */ struct TALER_EXCHANGE_PurseDeposit { @@ -4785,7 +6411,9 @@ struct TALER_EXCHANGE_PurseDeposit * Inform the exchange that a purse should be created * and coins deposited into it. * - * @param exchange the exchange to interact with + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param purse_priv private key of the purse * @param merge_priv the merge credential * @param contract_priv key needed to obtain and decrypt the contract @@ -4801,13 +6429,15 @@ struct TALER_EXCHANGE_PurseDeposit */ struct TALER_EXCHANGE_PurseCreateDepositHandle * TALER_EXCHANGE_purse_create_with_deposit ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_PurseContractPrivateKeyP *purse_priv, const struct TALER_PurseMergePrivateKeyP *merge_priv, const struct TALER_ContractDiffiePrivateP *contract_priv, const json_t *contract_terms, unsigned int num_deposits, - const struct TALER_EXCHANGE_PurseDeposit *deposits, + const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits], bool upload_contract, TALER_EXCHANGE_PurseCreateDepositCallback cb, void *cb_cls); @@ -4824,6 +6454,67 @@ TALER_EXCHANGE_purse_create_with_deposit_cancel ( /** + * Response generated for a purse deletion request. + */ +struct TALER_EXCHANGE_PurseDeleteResponse +{ + /** + * Full HTTP response. + */ + struct TALER_EXCHANGE_HttpResponse hr; +}; + + +/** + * Function called with information about the deletion + * of a purse. + * + * @param cls closure + * @param pdr HTTP response data + */ +typedef void +(*TALER_EXCHANGE_PurseDeleteCallback) ( + void *cls, + const struct TALER_EXCHANGE_PurseDeleteResponse *pdr); + + +/** + * @brief Handle for a DELETE /purses/$PID request. + */ +struct TALER_EXCHANGE_PurseDeleteHandle; + + +/** + * Asks the exchange to delete a purse. Will only succeed if + * the purse was not yet merged and did not yet time out. + * + * @param ctx CURL context + * @param url exchange base URL + * @param purse_priv private key of the purse + * @param cb function to call with the exchange's result + * @param cb_cls closure for @a cb + * @return the request handle; NULL upon error + */ +struct TALER_EXCHANGE_PurseDeleteHandle * +TALER_EXCHANGE_purse_delete ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_PurseContractPrivateKeyP *purse_priv, + TALER_EXCHANGE_PurseDeleteCallback cb, + void *cb_cls); + + +/** + * Cancel #TALER_EXCHANGE_purse_delete() operation. + * + * @param pdh handle of the operation to cancel + */ +void +TALER_EXCHANGE_purse_delete_cancel ( + struct TALER_EXCHANGE_PurseDeleteHandle *pdh); + + +/** * Response generated for an account merge request. */ struct TALER_EXCHANGE_AccountMergeResponse @@ -4863,7 +6554,19 @@ struct TALER_EXCHANGE_AccountMergeResponse */ struct GNUNET_TIME_Timestamp etime; - } success; + } ok; + + /** + * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. + */ + struct + { + /** + * Requirement row target that the merchant should use + * to check for its KYC status. + */ + uint64_t requirement_row; + } unavailable_for_legal_reasons; } details; @@ -4892,7 +6595,9 @@ struct TALER_EXCHANGE_AccountMergeHandle; * Inform the exchange that a purse should be merged * with a reserve. * - * @param exchange the exchange hosting the purse + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param reserve_exchange_url base URL of the exchange with the reserve * @param reserve_priv private key of the reserve to merge into * @param purse_pub public key of the purse to merge @@ -4908,7 +6613,9 @@ struct TALER_EXCHANGE_AccountMergeHandle; */ struct TALER_EXCHANGE_AccountMergeHandle * TALER_EXCHANGE_account_merge ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const char *reserve_exchange_url, const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_PurseContractPublicKeyP *purse_pub, @@ -4954,12 +6661,25 @@ struct TALER_EXCHANGE_PurseCreateMergeResponse union { /** - * Detailed returned on #MHD_HTTP_OK. + * Details returned on #MHD_HTTP_OK. */ struct { - } success; + } ok; + + /** + * Details if the status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. + */ + struct + { + /** + * Requirement row that the merchant should use + * to check for its KYC status. + */ + uint64_t requirement_row; + } unavailable_for_legal_reasons; + } details; }; @@ -4987,7 +6707,9 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle; * Inform the exchange that a purse should be created * and merged with a reserve. * - * @param exchange the exchange hosting the reserve + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param reserve_priv private key of the reserve * @param purse_priv private key of the purse * @param merge_priv private key of the merge capability @@ -5002,7 +6724,9 @@ struct TALER_EXCHANGE_PurseCreateMergeHandle; */ struct TALER_EXCHANGE_PurseCreateMergeHandle * TALER_EXCHANGE_purse_create_with_merge ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const struct TALER_ReservePrivateKeyP *reserve_priv, const struct TALER_PurseContractPrivateKeyP *purse_priv, const struct TALER_PurseMergePrivateKeyP *merge_priv, @@ -5066,7 +6790,7 @@ struct TALER_EXCHANGE_PurseDepositResponse */ struct TALER_PrivateContractHashP h_contract_terms; - } success; + } ok; } details; }; @@ -5094,7 +6818,9 @@ struct TALER_EXCHANGE_PurseDepositHandle; * Inform the exchange that a deposit should be made into * a purse. * - * @param exchange the exchange that issued the coins + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys * @param purse_exchange_url base URL of the exchange hosting the purse * @param purse_pub public key of the purse to merge * @param min_age minimum age we need to prove for the purse @@ -5106,12 +6832,14 @@ struct TALER_EXCHANGE_PurseDepositHandle; */ struct TALER_EXCHANGE_PurseDepositHandle * TALER_EXCHANGE_purse_deposit ( - struct TALER_EXCHANGE_Handle *exchange, + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, const char *purse_exchange_url, const struct TALER_PurseContractPublicKeyP *purse_pub, uint8_t min_age, unsigned int num_deposits, - const struct TALER_EXCHANGE_PurseDeposit *deposits, + const struct TALER_EXCHANGE_PurseDeposit deposits[static num_deposits], TALER_EXCHANGE_PurseDepositCallback cb, void *cb_cls); @@ -5126,4 +6854,474 @@ TALER_EXCHANGE_purse_deposit_cancel ( struct TALER_EXCHANGE_PurseDepositHandle *amh); +/* ********************* /reserves/$RID/open *********************** */ + + +/** + * @brief A /reserves/$RID/open Handle + */ +struct TALER_EXCHANGE_ReservesOpenHandle; + + +/** + * @brief Reserve open result details. + */ +struct TALER_EXCHANGE_ReserveOpenResult +{ + + /** + * High-level HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on @e hr.http_status. + */ + union + { + + /** + * Information returned on success, if + * @e hr.http_status is #MHD_HTTP_OK + */ + struct + { + /** + * New expiration time + */ + struct GNUNET_TIME_Timestamp expiration_time; + + /** + * Actual cost of the open operation. + */ + struct TALER_Amount open_cost; + + } ok; + + + /** + * Information returned if the payment provided is insufficient, if + * @e hr.http_status is #MHD_HTTP_PAYMENT_REQUIRED + */ + struct + { + /** + * Current expiration time of the reserve. + */ + struct GNUNET_TIME_Timestamp expiration_time; + + /** + * Actual cost of the open operation that should have been paid. + */ + struct TALER_Amount open_cost; + + } payment_required; + + /** + * Information returned if status is + * #MHD_HTTP_CONFLICT. + */ + struct + { + /** + * Public key of the coin that caused the conflict. + */ + struct TALER_CoinSpendPublicKeyP coin_pub; + + } conflict; + + /** + * Information returned if KYC is required to proceed, set if + * @e hr.http_status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. + */ + struct + { + /** + * Requirement row that the merchant should use + * to check for its KYC status. + */ + uint64_t requirement_row; + + /** + * Hash of the payto-URI of the account to KYC; + */ + struct TALER_PaytoHashP h_payto; + + } unavailable_for_legal_reasons; + + } details; + +}; + + +/** + * Callbacks of this type are used to serve the result of submitting a + * reserve open request to a exchange. + * + * @param cls closure + * @param ror HTTP response data + */ +typedef void +(*TALER_EXCHANGE_ReservesOpenCallback) ( + void *cls, + const struct TALER_EXCHANGE_ReserveOpenResult *ror); + + +/** + * Submit a request to open a reserve. + * + * @param ctx curl context + * @param url exchange base URL + * @param keys exchange keys + * @param reserve_priv private key of the reserve to open + * @param reserve_contribution amount to pay from the reserve's balance for the operation + * @param coin_payments_length length of the @a coin_payments array + * @param coin_payments array of coin payments to use for opening the reserve + * @param expiration_time desired new expiration time for the reserve + * @param min_purses minimum number of purses to allow being concurrently opened per reserve + * @param cb the callback to call when a reply for this request is available + * @param cb_cls closure for the above callback + * @return a handle for this request; NULL if the inputs are invalid (i.e. + * signatures fail to verify). In this case, the callback is not called. + */ +struct TALER_EXCHANGE_ReservesOpenHandle * +TALER_EXCHANGE_reserves_open ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, + const struct TALER_ReservePrivateKeyP *reserve_priv, + const struct TALER_Amount *reserve_contribution, + unsigned int coin_payments_length, + const struct TALER_EXCHANGE_PurseDeposit coin_payments[ + static coin_payments_length], + struct GNUNET_TIME_Timestamp expiration_time, + uint32_t min_purses, + TALER_EXCHANGE_ReservesOpenCallback cb, + void *cb_cls); + + +/** + * Cancel a reserve status request. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param[in] roh the reserve open request handle + */ +void +TALER_EXCHANGE_reserves_open_cancel ( + struct TALER_EXCHANGE_ReservesOpenHandle *roh); + + +/* ********************* /reserves/$RID/attest *********************** */ + + +/** + * @brief A Get /reserves/$RID/attest Handle + */ +struct TALER_EXCHANGE_ReservesGetAttestHandle; + + +/** + * @brief Reserve GET attest result details. + */ +struct TALER_EXCHANGE_ReserveGetAttestResult +{ + + /** + * High-level HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on @e hr.http_status. + */ + union + { + + /** + * Information returned on success, if + * @e hr.http_status is #MHD_HTTP_OK + */ + struct + { + + /** + * Length of the @e attributes array. + */ + unsigned int attributes_length; + + /** + * Array of attributes available about the user. + */ + const char **attributes; + + } ok; + + } details; + +}; + + +/** + * Callbacks of this type are used to serve the result of submitting a + * reserve attest request to a exchange. + * + * @param cls closure + * @param ror HTTP response data + */ +typedef void +(*TALER_EXCHANGE_ReservesGetAttestCallback) ( + void *cls, + const struct TALER_EXCHANGE_ReserveGetAttestResult *ror); + + +/** + * Submit a request to get the list of attestable attributes for a reserve. + * + * @param ctx CURL context + * @param url exchange base URL + * @param reserve_pub public key of the reserve to get available attributes for + * @param cb the callback to call when a reply for this request is available + * @param cb_cls closure for the above callback + * @return a handle for this request; NULL if the inputs are invalid (i.e. + * signatures fail to verify). In this case, the callback is not called. + */ +struct TALER_EXCHANGE_ReservesGetAttestHandle * +TALER_EXCHANGE_reserves_get_attestable ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_ReservePublicKeyP *reserve_pub, + TALER_EXCHANGE_ReservesGetAttestCallback cb, + void *cb_cls); + + +/** + * Cancel a request to get attestable attributes. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param rgah the reserve get attestable request handle + */ +void +TALER_EXCHANGE_reserves_get_attestable_cancel ( + struct TALER_EXCHANGE_ReservesGetAttestHandle *rgah); + + +/** + * @brief A POST /reserves/$RID/attest Handle + */ +struct TALER_EXCHANGE_ReservesPostAttestHandle; + + +/** + * @brief Reserve attest result details. + */ +struct TALER_EXCHANGE_ReservePostAttestResult +{ + + /** + * High-level HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on @e hr.http_status. + */ + union + { + + /** + * Information returned on success, if + * @e hr.http_status is #MHD_HTTP_OK + */ + struct + { + /** + * Time when the exchange made the signature. + */ + struct GNUNET_TIME_Timestamp exchange_time; + + /** + * Expiration time of the attested attributes. + */ + struct GNUNET_TIME_Timestamp expiration_time; + + /** + * Signature by the exchange affirming the attributes. + */ + struct TALER_ExchangeSignatureP exchange_sig; + + /** + * Online signing key used by the exchange. + */ + struct TALER_ExchangePublicKeyP exchange_pub; + + /** + * Attributes being confirmed by the exchange. + */ + const json_t *attributes; + + } ok; + + } details; + +}; + + +/** + * Callbacks of this type are used to serve the result of submitting a + * reserve attest request to a exchange. + * + * @param cls closure + * @param ror HTTP response data + */ +typedef void +(*TALER_EXCHANGE_ReservesPostAttestCallback) ( + void *cls, + const struct TALER_EXCHANGE_ReservePostAttestResult *ror); + + +/** + * Submit a request to attest attributes about the owner of a reserve. + * + * @param ctx CURL context + * @param url exchange base URL + * @param keys exchange key data + * @param reserve_priv private key of the reserve to attest + * @param attributes_length length of the @a attributes array + * @param attributes array of names of attributes to get attestations for + * @param cb the callback to call when a reply for this request is available + * @param cb_cls closure for the above callback + * @return a handle for this request; NULL if the inputs are invalid (i.e. + * signatures fail to verify). In this case, the callback is not called. + */ +struct TALER_EXCHANGE_ReservesAttestHandle * +TALER_EXCHANGE_reserves_attest ( + struct GNUNET_CURL_Context *ctx, + const char *url, + struct TALER_EXCHANGE_Keys *keys, + const struct TALER_ReservePrivateKeyP *reserve_priv, + unsigned int attributes_length, + const char *attributes[const static attributes_length], + TALER_EXCHANGE_ReservesPostAttestCallback cb, + void *cb_cls); + + +/** + * Cancel a reserve attestation request. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param rah the reserve attest request handle + */ +void +TALER_EXCHANGE_reserves_attest_cancel ( + struct TALER_EXCHANGE_ReservesAttestHandle *rah); + + +/* ********************* /reserves/$RID/close *********************** */ + + +/** + * @brief A /reserves/$RID/close Handle + */ +struct TALER_EXCHANGE_ReservesCloseHandle; + + +/** + * @brief Reserve close result details. + */ +struct TALER_EXCHANGE_ReserveCloseResult +{ + + /** + * High-level HTTP response details. + */ + struct TALER_EXCHANGE_HttpResponse hr; + + /** + * Details depending on @e hr.http_status. + */ + union + { + + /** + * Information returned on success, if + * @e hr.http_status is #MHD_HTTP_OK + */ + struct + { + + /** + * Amount wired to the target account. + */ + struct TALER_Amount wire_amount; + } ok; + + /** + * Information returned if KYC is required to proceed, set if + * @e hr.http_status is #MHD_HTTP_UNAVAILABLE_FOR_LEGAL_REASONS. + */ + struct + { + /** + * Requirement row that the merchant should use + * to check for its KYC status. + */ + uint64_t requirement_row; + + /** + * Hash of the payto-URI of the account to KYC; + */ + struct TALER_PaytoHashP h_payto; + + } unavailable_for_legal_reasons; + + } details; + +}; + + +/** + * Callbacks of this type are used to serve the result of submitting a + * reserve close request to a exchange. + * + * @param cls closure + * @param ror HTTP response data + */ +typedef void +(*TALER_EXCHANGE_ReservesCloseCallback) ( + void *cls, + const struct TALER_EXCHANGE_ReserveCloseResult *ror); + + +/** + * Submit a request to close a reserve. + * + * @param ctx curl context + * @param url exchange base URL + * @param reserve_priv private key of the reserve to close + * @param target_payto_uri where to send the payment, NULL to send to reserve origin + * @param cb the callback to call when a reply for this request is available + * @param cb_cls closure for the above callback + * @return a handle for this request; NULL if the inputs are invalid (i.e. + * signatures fail to verify). In this case, the callback is not called. + */ +struct TALER_EXCHANGE_ReservesCloseHandle * +TALER_EXCHANGE_reserves_close ( + struct GNUNET_CURL_Context *ctx, + const char *url, + const struct TALER_ReservePrivateKeyP *reserve_priv, + const char *target_payto_uri, + TALER_EXCHANGE_ReservesCloseCallback cb, + void *cb_cls); + + +/** + * Cancel a reserve status request. This function cannot be used + * on a request handle if a response is already served for it. + * + * @param rch the reserve request handle + */ +void +TALER_EXCHANGE_reserves_close_cancel ( + struct TALER_EXCHANGE_ReservesCloseHandle *rch); + #endif /* _TALER_EXCHANGE_SERVICE_H */ |