aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/exchange/taler-exchange-httpd.c35
-rw-r--r--src/exchange/taler-exchange-httpd.h9
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c15
-rw-r--r--src/exchangedb/perf_get_link_data.c23
-rw-r--r--src/include/taler_exchange_service.h91
-rw-r--r--src/include/taler_json_lib.h11
-rw-r--r--src/include/taler_kyclogic_lib.h38
-rw-r--r--src/json/json_helper.c4
-rw-r--r--src/json/json_pack.c41
-rw-r--r--src/kyclogic/Makefile.am2
-rw-r--r--src/kyclogic/kyclogic_api.c72
-rw-r--r--src/lib/Makefile.am2
-rw-r--r--src/lib/exchange_api_add_aml_decision.c5
-rw-r--r--src/lib/exchange_api_handle.c82
-rw-r--r--src/lib/exchange_api_kyc_check.c7
15 files changed, 272 insertions, 165 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index 7fa8885e7..36c567ebd 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -156,16 +156,6 @@ struct TALER_AttributeEncryptionKeyP TEH_attribute_key;
struct TALER_EXCHANGEDB_Plugin *TEH_plugin;
/**
- * Maximum amount per individual transaction. Invalid amount if unlimited.
- */
-struct TALER_Amount TEH_transaction_limit;
-
-/**
- * Maximum amount per refund. Invalid amount if unlimited.
- */
-struct TALER_Amount TEH_refund_limit;
-
-/**
* Absolute STEFAN parameter.
*/
struct TALER_Amount TEH_stefan_abs;
@@ -181,6 +171,11 @@ struct TALER_Amount TEH_stefan_log;
float TEH_stefan_lin;
/**
+ * JSON array with hard limits for /keys response.
+ */
+json_t *TEH_hard_limits;
+
+/**
* Where to redirect users from "/"?
*/
static char *toplevel_redirect_url;
@@ -2144,6 +2139,8 @@ exchange_serve_process_config (const char *cfg_fn)
GNUNET_break (0);
return GNUNET_SYSERR;
}
+ TEH_hard_limits
+ = TALER_KYCLOGIC_get_hard_limits ();
if (GNUNET_OK !=
GNUNET_CONFIGURATION_get_value_number (TEH_cfg,
"exchange",
@@ -2217,24 +2214,6 @@ exchange_serve_process_config (const char *cfg_fn)
}
/* currency parser must provide default spec for main currency */
GNUNET_assert (NULL != TEH_cspec);
- if (GNUNET_SYSERR ==
- TALER_config_get_amount (TEH_cfg,
- "exchange",
- "TRANSACTION_LIMIT",
- &TEH_transaction_limit))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
- if (GNUNET_SYSERR ==
- TALER_config_get_amount (TEH_cfg,
- "exchange",
- "REFUND_LIMIT",
- &TEH_refund_limit))
- {
- GNUNET_break (0);
- return GNUNET_SYSERR;
- }
GNUNET_assert (GNUNET_OK ==
TALER_amount_set_zero (TEH_currency,
&TEH_stefan_abs));
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
index 6f86fa39c..d6350c897 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -98,14 +98,9 @@ extern struct TALER_AttributeEncryptionKeyP TEH_attribute_key;
extern struct TALER_EXCHANGEDB_Plugin *TEH_plugin;
/**
- * Maximum amount per individual transaction. Invalid amount if unlimited.
+ * JSON array with hard limits for /keys response.
*/
-extern struct TALER_Amount TEH_transaction_limit;
-
-/**
- * Maximum amount per refund. Invalid amount if unlimited.
- */
-extern struct TALER_Amount TEH_refund_limit;
+extern json_t *TEH_hard_limits;
/**
* Absolute STEFAN parameter.
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 107e77961..e57e7d4f5 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -2413,18 +2413,9 @@ create_krd (struct TEH_KeyStateHandle *ksh,
GNUNET_JSON_pack_object_steal (
"currency_specification",
TALER_CONFIG_currency_specs_to_json (TEH_cspec)),
- GNUNET_JSON_pack_allow_null (
- TALER_JSON_pack_amount ("transaction_amount_limit",
- GNUNET_OK ==
- TALER_amount_is_valid (&TEH_transaction_limit)
- ? &TEH_transaction_limit
- : NULL)),
- GNUNET_JSON_pack_allow_null (
- TALER_JSON_pack_amount ("refund_amount_limit",
- GNUNET_OK ==
- TALER_amount_is_valid (&TEH_refund_limit)
- ? &TEH_refund_limit
- : NULL)),
+ GNUNET_JSON_pack_array_incref (
+ "hard_limits",
+ TEH_hard_limits),
TALER_JSON_pack_amount ("stefan_abs",
&TEH_stefan_abs),
TALER_JSON_pack_amount ("stefan_log",
diff --git a/src/exchangedb/perf_get_link_data.c b/src/exchangedb/perf_get_link_data.c
index 817789afc..f2c612e16 100644
--- a/src/exchangedb/perf_get_link_data.c
+++ b/src/exchangedb/perf_get_link_data.c
@@ -28,24 +28,25 @@
* Report line of error if @a cond is true, and jump to label "drop".
*/
#define FAILIF(cond) \
- do { \
- if (! (cond)) {break;} \
- GNUNET_break (0); \
- goto drop; \
- } while (0)
+ do { \
+ if (! (cond)) {break;} \
+ GNUNET_break (0); \
+ goto drop; \
+ } while (0)
/**
* Initializes @a ptr with random data.
*/
#define RND_BLK(ptr) \
- GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (*ptr))
+ GNUNET_CRYPTO_random_block (GNUNET_CRYPTO_QUALITY_WEAK, ptr, sizeof (* \
+ ptr))
/**
* Initializes @a ptr with zeros.
*/
#define ZR_BLK(ptr) \
- memset (ptr, 0, sizeof (*ptr))
+ memset (ptr, 0, sizeof (*ptr))
#define CURRENCY "EUR"
#define RSA_KEY_SIZE 1024
@@ -58,7 +59,6 @@
* Database plugin under test.
*/
static struct TALER_EXCHANGEDB_Plugin *plugin;
-static struct TALER_DenomFeeSet fees;
/**
* Denomination keys used for fresh coins in melt test.
*/
@@ -215,6 +215,7 @@ run (void *cls)
struct TALER_ExchangeWithdrawValues alg_values = {
.blinding_inputs = &bi
};
+ struct TALER_DenomFeeSet fees;
ref = GNUNET_new_array (ROUNDS + 1,
struct TALER_EXCHANGEDB_Refund);
@@ -307,10 +308,10 @@ run (void *cls)
struct TALER_EXCHANGEDB_RefreshRevealedCoin *revealed_coin =
&revealed_coins[p];
struct TALER_BlindedPlanchet *bp = &revealed_coin->blinded_planchet;
- bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage);
- struct GNUNET_CRYPTO_RsaBlindedMessage *rp =
- &bp->blinded_message->details.rsa_blinded_message;
+ struct GNUNET_CRYPTO_RsaBlindedMessage *rp;
+ bp->blinded_message = GNUNET_new (struct GNUNET_CRYPTO_BlindedMessage);
+ rp = &bp->blinded_message->details.rsa_blinded_message;
/* h_coin_ev must be unique, but we only have MELT_NEW_COINS created
above for NUM_ROWS iterations; instead of making "all new" coins,
we simply randomize the hash here as nobody is checking for consistency
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index b778fcceb..e845f5ed8 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -422,6 +422,39 @@ struct TALER_EXCHANGE_WireAccount
/**
+ * Applicable limits for an account (or wallet). Exceeding these limits may
+ * trigger additional KYC requirements or be categorically verboten.
+ */
+struct TALER_EXCHANGE_AccountLimit
+{
+
+ /**
+ * Operation type for which the restriction applies.
+ */
+ enum TALER_KYCLOGIC_KycTriggerEvent operation_type;
+
+ /**
+ * Timeframe over which the @e threshold is computed.
+ */
+ struct GNUNET_TIME_Relative timeframe;
+
+ /**
+ * The maximum amount transacted within the given @e timeframe for the
+ * specified @e operation_type.
+ */
+ struct TALER_Amount threshold;
+
+ /**
+ * True if this is a soft limit and passing KYC checks
+ * or AML reviews may raise this limit. False if this
+ * is a hard limit that the exchange will not permit
+ * the client to exceed.
+ */
+ bool soft_limit;
+};
+
+
+/**
* @brief Information about keys from the exchange.
*/
struct TALER_EXCHANGE_Keys
@@ -502,6 +535,12 @@ struct TALER_EXCHANGE_Keys
struct TALER_EXCHANGE_WireAccount *accounts;
/**
+ * Array of hard limits that apply at this exchange.
+ * All limits in this array will be hard limits.
+ */
+ struct TALER_EXCHANGE_AccountLimit *hard_limits;
+
+ /**
* Array of wire fees by wire method.
*/
struct TALER_EXCHANGE_WireFeesByMethod *fees;
@@ -551,20 +590,6 @@ struct TALER_EXCHANGE_Keys
struct TALER_Amount stefan_log;
/**
- * Maximum amount for an individual transaction.
- * Set to an invalid amount (see #TALER_amount_is_valid())
- * if there is no limit.
- */
- struct TALER_Amount transaction_limit;
-
- /**
- * Maximum amount that can be refunded per individual transaction.
- * Set to an invalid amount (see #TALER_amount_is_valid())
- * if there is no limit.
- */
- struct TALER_Amount refund_limit;
-
- /**
* Linear STEFAN parameter.
*/
double stefan_lin;
@@ -580,6 +605,11 @@ struct TALER_EXCHANGE_Keys
unsigned int fees_len;
/**
+ * Length of @e hard_limits array.
+ */
+ unsigned int hard_limits_length;
+
+ /**
* Length of the @e wallet_balance_limit_without_kyc
* array.
*/
@@ -4265,39 +4295,6 @@ struct TALER_EXCHANGE_KycCheckHandle;
/**
- * Applicable limits for an account. Exceeding these limits may trigger
- * additional KYC requirements or be categorically verboten.
- */
-struct TALER_EXCHANGE_AccountLimit
-{
-
- /**
- * Operation type for which the restriction applies.
- */
- enum TALER_KYCLOGIC_KycTriggerEvent operation_type;
-
- /**
- * Timeframe over which the @e threshold is computed.
- */
- struct GNUNET_TIME_Relative timeframe;
-
- /**
- * The maximum amount transacted within the given @e timeframe for the
- * specified @e operation_type.
- */
- struct TALER_Amount threshold;
-
- /**
- * True if this is a soft limit and passing KYC checks
- * or AML reviews may raise this limit. False if this
- * is a hard limit that the exchange will not permit
- * the client to exceed.
- */
- bool soft_limit;
-};
-
-
-/**
* KYC/AML status information about an account.
*/
struct TALER_EXCHANGE_AccountKycStatus
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index 806b39dc1..5e78ab44d 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -209,6 +209,17 @@ TALER_JSON_pack_age_commitment (
/**
+ * Generate packer instruction of a KYC Trigger Event.
+ *
+ * @param name name of the field to add to the object
+ * @param event event type to add
+ * @return json pack specification
+ */
+struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_kycte (const char *name,
+ enum TALER_KYCLOGIC_KycTriggerEvent event);
+
+/**
* Convert a TALER amount to a JSON object.
*
* @param amount the amount
diff --git a/src/include/taler_kyclogic_lib.h b/src/include/taler_kyclogic_lib.h
index 39256bb1e..17ca2fe04 100644
--- a/src/include/taler_kyclogic_lib.h
+++ b/src/include/taler_kyclogic_lib.h
@@ -54,7 +54,8 @@ enum TALER_KYCLOGIC_KycTriggerEvent
TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE = 3,
/**
- * Wallet balance exceeds threshold.
+ * Wallet balance exceeds threshold. The timeframe is
+ * irrelevant for this limit.
*/
TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE = 4,
@@ -67,7 +68,19 @@ enum TALER_KYCLOGIC_KycTriggerEvent
* Deposits have been aggregated, we are wiring a
* certain amount into a (merchant) bank account.
*/
- TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6
+ TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE = 6,
+
+ /**
+ * Limit per transaction. The timeframe is
+ * irrelevant for this limit.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION = 7,
+
+ /**
+ * Limit per refund. The timeframe is
+ * irrelevant for this limit.
+ */
+ TALER_KYCLOGIC_KYC_TRIGGER_REFUND = 8
};
@@ -225,16 +238,6 @@ TALER_KYCLOGIC_kyc_trigger_from_string (
/**
- * Convert KYC trigger value to human-readable string.
- *
- * @param trigger value to convert
- * @return human-readable representation of the @a trigger
- */
-const char *
-TALER_KYCLOGIC_kyc_trigger2s (enum TALER_KYCLOGIC_KycTriggerEvent trigger);
-
-
-/**
* Initialize KYC subsystem. Loads the KYC configuration.
*
* @param cfg configuration to parse
@@ -356,6 +359,17 @@ TALER_KYCLOGIC_kyc_test_required (
/**
+ * Return JSON array of AccountLimit objects with hard limits of this exchange
+ * suitable for the "hard_limits" field of the "/keys" response.
+ *
+ * @return the JSON array of AccountLimit objects,
+ * empty array if there are no hard limits
+ */
+json_t *
+TALER_KYCLOGIC_get_hard_limits (void);
+
+
+/**
* Get human-readable name of KYC rule.
*
* @param r rule to convert
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index db0a425db..2d1037ef6 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -1475,6 +1475,10 @@ parse_kycte (void *cls,
.val = TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE },
{ .name = "AGGREGATE",
.val = TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE },
+ { .name = "TRANSACTION",
+ .val = TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION },
+ { .name = "REFUND",
+ .val = TALER_KYCLOGIC_KYC_TRIGGER_REFUND },
{ .name = NULL,
.val = TALER_KYCLOGIC_KYC_TRIGGER_NONE },
};
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
index 85c9c5686..859976acb 100644
--- a/src/json/json_pack.c
+++ b/src/json/json_pack.c
@@ -97,6 +97,47 @@ TALER_JSON_pack_age_commitment (
struct GNUNET_JSON_PackSpec
+TALER_JSON_pack_kycte (const char *name,
+ enum TALER_KYCLOGIC_KycTriggerEvent event)
+{
+ const char *str = "INVALID";
+
+ switch (event)
+ {
+ case TALER_KYCLOGIC_KYC_TRIGGER_NONE:
+ str = "NONE";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW:
+ str = "WITHDRAW";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT:
+ str = "DEPOSIT";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE:
+ str = "MERGE";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE:
+ str = "BALANCE";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE:
+ str = "CLOSE";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE:
+ str = "AGGREGATE";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION:
+ str = "TRANSACTION";
+ break;
+ case TALER_KYCLOGIC_KYC_TRIGGER_REFUND:
+ str = "REFUND";
+ break;
+ }
+ return GNUNET_JSON_pack_string (name,
+ str);
+}
+
+
+struct GNUNET_JSON_PackSpec
TALER_JSON_pack_denom_pub (
const char *name,
const struct TALER_DenominationPublicKey *pk)
diff --git a/src/kyclogic/Makefile.am b/src/kyclogic/Makefile.am
index 7da1f758f..35e68e1a2 100644
--- a/src/kyclogic/Makefile.am
+++ b/src/kyclogic/Makefile.am
@@ -41,7 +41,7 @@ libtalerkyclogic_la_LIBADD = \
-lgnunetutil \
$(XLIB)
libtalerkyclogic_la_LDFLAGS = \
- -version-info 0:0:0 \
+ -version-info 1:0:0 \
-no-undefined
diff --git a/src/kyclogic/kyclogic_api.c b/src/kyclogic/kyclogic_api.c
index 9e37f16f9..7ea6b2b82 100644
--- a/src/kyclogic/kyclogic_api.c
+++ b/src/kyclogic/kyclogic_api.c
@@ -833,15 +833,16 @@ TALER_KYCLOGIC_rules_to_limits (const json_t *jrules)
}
limit = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string (
+ TALER_JSON_pack_kycte (
"operation_type",
- TALER_KYCLOGIC_kyc_trigger2s (operation_type)),
+ operation_type),
GNUNET_JSON_pack_time_rel (
"timeframe",
timeframe),
TALER_JSON_pack_amount (
"threshold",
&threshold),
+ /* optional since v21, defaults to 'false' */
GNUNET_JSON_pack_bool (
"soft_limit",
! forbidden));
@@ -1215,6 +1216,8 @@ TALER_KYCLOGIC_kyc_trigger_from_string (
const char *trigger_s,
enum TALER_KYCLOGIC_KycTriggerEvent *trigger)
{
+ /* NOTE: if you change this, also change
+ the code in src/json/json_helper.c! */
struct
{
const char *in;
@@ -1226,6 +1229,8 @@ TALER_KYCLOGIC_kyc_trigger_from_string (
{ "BALANCE", TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE },
{ "CLOSE", TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE },
{ "AGGREGATE", TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE },
+ { "TRANSACTION", TALER_KYCLOGIC_KYC_TRIGGER_TRANSACTION },
+ { "REFUND", TALER_KYCLOGIC_KYC_TRIGGER_REFUND },
{ NULL, 0 }
};
@@ -1243,33 +1248,6 @@ TALER_KYCLOGIC_kyc_trigger_from_string (
}
-const char *
-TALER_KYCLOGIC_kyc_trigger2s (
- enum TALER_KYCLOGIC_KycTriggerEvent trigger)
-{
- switch (trigger)
- {
- case TALER_KYCLOGIC_KYC_TRIGGER_NONE:
- GNUNET_break (0);
- return NULL;
- case TALER_KYCLOGIC_KYC_TRIGGER_WITHDRAW:
- return "WITHDRAW";
- case TALER_KYCLOGIC_KYC_TRIGGER_DEPOSIT:
- return "DEPOSIT";
- case TALER_KYCLOGIC_KYC_TRIGGER_P2P_RECEIVE:
- return "MERGE";
- case TALER_KYCLOGIC_KYC_TRIGGER_WALLET_BALANCE:
- return "BALANCE";
- case TALER_KYCLOGIC_KYC_TRIGGER_RESERVE_CLOSE:
- return "CLOSE";
- case TALER_KYCLOGIC_KYC_TRIGGER_AGGREGATE:
- return "AGGREGATE";
- }
- GNUNET_break (0);
- return NULL;
-}
-
-
json_t *
TALER_KYCLOGIC_get_wallet_thresholds (void)
{
@@ -3565,4 +3543,40 @@ TALER_KYCLOGIC_run_aml_program_cancel (
}
+json_t *
+TALER_KYCLOGIC_get_hard_limits ()
+{
+ const struct TALER_KYCLOGIC_KycRule *rules
+ = default_rules.kyc_rules;
+ unsigned int num_rules
+ = default_rules.num_kyc_rules;
+ json_t *hard_limits;
+
+ hard_limits = json_array ();
+ GNUNET_assert (NULL != hard_limits);
+ for (unsigned int i = 0; i<num_rules; i++)
+ {
+ const struct TALER_KYCLOGIC_KycRule *rule = &rules[i];
+ json_t *hard_limit;
+
+ if (! rule->verboten)
+ continue;
+ if (! rule->exposed)
+ continue;
+ hard_limit = GNUNET_JSON_PACK (
+ TALER_JSON_pack_kycte ("operation_type",
+ rule->trigger),
+ GNUNET_JSON_pack_time_rel ("timeframe",
+ rule->timeframe),
+ TALER_JSON_pack_amount ("threshold",
+ &rule->threshold)
+ );
+ GNUNET_assert (0 ==
+ json_array_append_new (hard_limits,
+ hard_limit));
+ }
+ return hard_limits;
+}
+
+
/* end of kyclogic_api.c */
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 8924ee604..df2c32109 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -18,7 +18,7 @@ lib_LTLIBRARIES = \
libtalerexchange.la
libtalerexchange_la_LDFLAGS = \
- -version-info 9:0:0 \
+ -version-info 10:0:0 \
-no-undefined
libtalerexchange_la_SOURCES = \
exchange_api_add_aml_decision.c \
diff --git a/src/lib/exchange_api_add_aml_decision.c b/src/lib/exchange_api_add_aml_decision.c
index 53cd04eb5..a9a41a0aa 100644
--- a/src/lib/exchange_api_add_aml_decision.c
+++ b/src/lib/exchange_api_add_aml_decision.c
@@ -167,9 +167,8 @@ TALER_EXCHANGE_add_aml_decision (
json_array_append_new (ameasures,
json_string (al->measures[j])));
rule = GNUNET_JSON_PACK (
- GNUNET_JSON_pack_string ("operation_type",
- TALER_KYCLOGIC_kyc_trigger2s (al->operation_type)
- ),
+ TALER_JSON_pack_kycte ("operation_type",
+ al->operation_type),
TALER_JSON_pack_amount ("threshold",
&al->threshold),
GNUNET_JSON_pack_time_rel ("timeframe",
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index f614ff3c2..5890fa75e 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -758,6 +758,61 @@ denoms_cmp (const struct TALER_EXCHANGE_DenomPublicKey *denom1,
/**
+ * Decode the JSON array in @a hard_limits from the /keys response
+ * and store the data in `hard_limits` array the @a key_data.
+ *
+ * @param[in] hard_limits JSON array to parse
+ * @param[out] key_data where to store the results we decoded
+ * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
+ * (malformed JSON)
+ */
+static enum GNUNET_GenericReturnValue
+parse_hard_limits (const json_t *hard_limits,
+ struct TALER_EXCHANGE_Keys *key_data)
+{
+ json_t *obj;
+ size_t off;
+
+ key_data->hard_limits_length
+ = (unsigned int) json_array_size (hard_limits);
+ if ( ((size_t) key_data->hard_limits_length)
+ != json_array_size (hard_limits))
+ {
+ GNUNET_break (0);
+ return GNUNET_SYSERR;
+ }
+ key_data->hard_limits
+ = GNUNET_new_array (key_data->hard_limits_length,
+ struct TALER_EXCHANGE_AccountLimit);
+
+ json_array_foreach (hard_limits, off, obj)
+ {
+ struct TALER_EXCHANGE_AccountLimit *al
+ = &key_data->hard_limits[off];
+ struct GNUNET_JSON_Specification spec[] = {
+ TALER_JSON_spec_kycte ("operation_type",
+ &al->operation_type),
+ TALER_JSON_spec_amount_any ("threshold",
+ &al->threshold),
+ GNUNET_JSON_spec_relative_time ("timeframe",
+ &al->timeframe),
+ GNUNET_JSON_spec_end ()
+ };
+
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (obj,
+ spec,
+ NULL, NULL))
+ {
+ GNUNET_break_op (0);
+ return GNUNET_SYSERR;
+ }
+ }
+ return GNUNET_OK;
+}
+
+
+/**
* Decode the JSON in @a resp_obj from the /keys response
* and store the data in the @a key_data.
*
@@ -920,6 +975,7 @@ decode_keys_json (const json_t *resp_obj,
EXITIF (1);
}
{
+ const json_t *hard_limits;
struct GNUNET_JSON_Specification sspec[] = {
TALER_JSON_spec_currency_specification (
"currency_specification",
@@ -933,18 +989,9 @@ decode_keys_json (const json_t *resp_obj,
"stefan_log",
currency,
&key_data->stefan_log),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_amount (
- "transaction_amount_limit",
- currency,
- &key_data->transaction_limit),
- NULL),
- GNUNET_JSON_spec_mark_optional (
- TALER_JSON_spec_amount (
- "refund_amount_limit",
- currency,
- &key_data->refund_limit),
- NULL),
+ GNUNET_JSON_spec_array_const (
+ "hard_limits",
+ &hard_limits),
GNUNET_JSON_spec_double (
"stefan_lin",
&key_data->stefan_lin),
@@ -963,6 +1010,14 @@ decode_keys_json (const json_t *resp_obj,
eline);
EXITIF (1);
}
+ if (GNUNET_OK !=
+ parse_hard_limits (hard_limits,
+ key_data))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Parsing hard limits of /keys failed\n");
+ EXITIF (1);
+ }
}
key_data->currency = GNUNET_strdup (currency);
@@ -1903,6 +1958,9 @@ TALER_EXCHANGE_keys_decref (struct TALER_EXCHANGE_Keys *keys)
0);
free_fees (keys->fees,
keys->fees_len);
+ GNUNET_array_grow (keys->hard_limits,
+ keys->hard_limits_length,
+ 0);
json_decref (keys->extensions);
GNUNET_free (keys->cspec.name);
json_decref (keys->cspec.map_alt_unit_names);
diff --git a/src/lib/exchange_api_kyc_check.c b/src/lib/exchange_api_kyc_check.c
index 75f238cca..39a3d9dac 100644
--- a/src/lib/exchange_api_kyc_check.c
+++ b/src/lib/exchange_api_kyc_check.c
@@ -99,8 +99,10 @@ parse_account_status (
{
struct TALER_EXCHANGE_AccountLimit *al = &ala[i];
struct GNUNET_JSON_Specification ispec[] = {
- GNUNET_JSON_spec_bool ("soft_limit",
- &al->soft_limit),
+ GNUNET_JSON_spec_mark_optional (
+ GNUNET_JSON_spec_bool ("soft_limit",
+ &al->soft_limit),
+ NULL),
GNUNET_JSON_spec_relative_time ("timeframe",
&al->timeframe),
TALER_JSON_spec_kycte ("operation_type",
@@ -110,6 +112,7 @@ parse_account_status (
GNUNET_JSON_spec_end ()
};
+ al->soft_limit = false;
if (GNUNET_OK !=
GNUNET_JSON_parse (limit,
ispec,