summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2023-10-08 20:58:06 +0200
committerChristian Grothoff <grothoff@gnunet.org>2023-10-08 20:58:06 +0200
commitb57b15a5eefea6f35724e95a351367b5f3e1bd0f (patch)
tree2626a6f1566981fa7e8c6c56e9bc7bc72bf4583d
parentda30a706a864661d85f40d4a5b03f6a9e9e0aa7b (diff)
downloadexchange-b57b15a5eefea6f35724e95a351367b5f3e1bd0f.tar.gz
exchange-b57b15a5eefea6f35724e95a351367b5f3e1bd0f.tar.bz2
exchange-b57b15a5eefea6f35724e95a351367b5f3e1bd0f.zip
more work on DD51
-rw-r--r--src/exchange/taler-exchange-httpd.c56
-rw-r--r--src/exchange/taler-exchange-httpd.h5
-rw-r--r--src/exchange/taler-exchange-httpd_config.c3
-rw-r--r--src/exchange/taler-exchange-httpd_keys.c5
-rw-r--r--src/include/taler_exchange_service.h11
-rw-r--r--src/include/taler_json_lib.h62
-rw-r--r--src/include/taler_util.h4
-rw-r--r--src/json/json_helper.c129
-rw-r--r--src/json/json_pack.c24
-rw-r--r--src/lib/exchange_api_handle.c11
-rw-r--r--src/util/amount.c1
-rw-r--r--src/util/config.c2
-rw-r--r--src/util/currencies.conf54
13 files changed, 177 insertions, 190 deletions
diff --git a/src/exchange/taler-exchange-httpd.c b/src/exchange/taler-exchange-httpd.c
index a9d10cc3f..bcf5b67da 100644
--- a/src/exchange/taler-exchange-httpd.c
+++ b/src/exchange/taler-exchange-httpd.c
@@ -253,6 +253,22 @@ static unsigned long long active_connections;
static unsigned long long req_max;
/**
+ * Length of the cspecs array.
+ */
+static unsigned int num_cspecs;
+
+/**
+ * Rendering specs for currencies.
+ */
+static struct TALER_CurrencySpecification *cspecs;
+
+/**
+ * Rendering spec for our currency.
+ */
+const struct TALER_CurrencySpecification *TEH_cspec;
+
+
+/**
* Context for all CURL operations (useful to the event loop)
*/
struct GNUNET_CURL_Context *TEH_curl_ctx;
@@ -2039,24 +2055,31 @@ exchange_serve_process_config (void)
"CURRENCY");
return GNUNET_SYSERR;
}
+
+ if (GNUNET_OK !=
+ TALER_CONFIG_parse_currencies (TEH_cfg,
+ &num_cspecs,
+ &cspecs))
+ return GNUNET_SYSERR;
+ for (unsigned int i = 0; i<num_cspecs; i++)
{
- unsigned long long cfd;
+ struct TALER_CurrencySpecification *cspec;
- if (GNUNET_OK !=
- GNUNET_CONFIGURATION_get_value_number (TEH_cfg,
- "exchange",
- "CURRENCY_FRACTION_DIGITS",
- &cfd))
- cfd = 0;
- if (cfd > 8)
+ cspec = &cspecs[i];
+ if (0 == strcmp (TEH_currency,
+ cspec->currency))
{
- GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
- "taler",
- "CURRENCY_FRACTION_DIGITS",
- "Value must be below 8");
- return GNUNET_SYSERR;
+ TEH_cspec = cspec;
+ break;
}
- TEH_currency_fraction_digits = (unsigned int) cfd;
+ }
+ if (NULL == TEH_cspec)
+ {
+ GNUNET_log_config_invalid (GNUNET_ERROR_TYPE_ERROR,
+ "taler",
+ "CURRENCY",
+ "Lacking enabled currency specification for the given currency");
+ return GNUNET_SYSERR;
}
if (GNUNET_OK !=
TALER_config_get_amount (TEH_cfg,
@@ -2466,6 +2489,11 @@ do_shutdown (void *cls)
exchange_curl_rc = NULL;
}
TALER_TEMPLATING_done ();
+ TEH_cspec = NULL;
+ TALER_CONFIG_free_currencies (num_cspecs,
+ cspecs);
+ num_cspecs = 0;
+ cspecs = NULL;
}
diff --git a/src/exchange/taler-exchange-httpd.h b/src/exchange/taler-exchange-httpd.h
index 9e18f9e69..1ab77291d 100644
--- a/src/exchange/taler-exchange-httpd.h
+++ b/src/exchange/taler-exchange-httpd.h
@@ -113,10 +113,9 @@ extern struct TALER_Amount TEH_stefan_log;
extern struct TALER_Amount TEH_stefan_lin;
/**
- * Default number of fractional digits to render
- * amounts with.
+ * Default ways how to render #TEH_currency amounts.
*/
-extern unsigned int TEH_currency_fraction_digits;
+extern const struct TALER_CurrencySpecification *TEH_cspec;
/**
* Our currency.
diff --git a/src/exchange/taler-exchange-httpd_config.c b/src/exchange/taler-exchange-httpd_config.c
index da5bf9691..fde1823fc 100644
--- a/src/exchange/taler-exchange-httpd_config.c
+++ b/src/exchange/taler-exchange-httpd_config.c
@@ -39,6 +39,9 @@ TEH_handler_config (struct TEH_RequestContext *rc,
resp = TALER_MHD_MAKE_JSON_PACK (
GNUNET_JSON_pack_array_steal ("supported_kyc_requirements",
TALER_KYCLOGIC_get_satisfiable ()),
+ GNUNET_JSON_pack_object_steal (
+ "currency_specification",
+ TALER_CONFIG_currency_specs_to_json (TEH_cspec)),
GNUNET_JSON_pack_string ("currency",
TEH_currency),
GNUNET_JSON_pack_string ("name",
diff --git a/src/exchange/taler-exchange-httpd_keys.c b/src/exchange/taler-exchange-httpd_keys.c
index 12d50a811..6bdc404d0 100644
--- a/src/exchange/taler-exchange-httpd_keys.c
+++ b/src/exchange/taler-exchange-httpd_keys.c
@@ -2490,8 +2490,9 @@ create_krd (struct TEH_KeyStateHandle *ksh,
TEH_base_url),
GNUNET_JSON_pack_string ("currency",
TEH_currency),
- GNUNET_JSON_pack_uint64 ("currency_fraction_digits",
- TEH_currency_fraction_digits),
+ GNUNET_JSON_pack_object_steal (
+ "currency_specification",
+ TALER_CONFIG_currency_specs_to_json (TEH_cspec)),
TALER_JSON_pack_amount ("stefan_abs",
&TEH_stefan_abs),
TALER_JSON_pack_amount ("stefan_log",
diff --git a/src/include/taler_exchange_service.h b/src/include/taler_exchange_service.h
index b14d68d6d..bf584036a 100644
--- a/src/include/taler_exchange_service.h
+++ b/src/include/taler_exchange_service.h
@@ -488,6 +488,11 @@ struct TALER_EXCHANGE_Keys
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).
@@ -532,12 +537,6 @@ struct TALER_EXCHANGE_Keys
struct TALER_Amount stefan_lin;
/**
- * Default number of fractional digits to render
- * amounts with.
- */
- uint32_t currency_fraction_digits;
-
- /**
* Length of @e accounts array.
*/
unsigned int accounts_len;
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h
index a6febbbfd..a8da05e4c 100644
--- a/src/include/taler_json_lib.h
+++ b/src/include/taler_json_lib.h
@@ -92,18 +92,6 @@ TALER_JSON_pack_time_abs_human (const char *name,
GNUNET_JSON_pack_string ("hint", TALER_ErrorCode_get_hint (ec)), \
GNUNET_JSON_pack_uint64 ("code", ec)
-/**
- * Generate packer instruction for a JSON field of type
- * absolute time creating a human-readable timestamp.
- *
- * @param name name of the field to add to the object
- * @param at absolute time to pack
- * @return json pack specification
- */
-struct GNUNET_JSON_PackSpec
-TALER_JSON_pack_time_abs_nbo_human (const char *name,
- struct GNUNET_TIME_AbsoluteNBO at);
-
/**
* Generate packer instruction for a JSON field of type
@@ -191,19 +179,6 @@ TALER_JSON_pack_amount (const char *name,
/**
* Generate packer instruction for a JSON field of type
- * amount.
- *
- * @param name name of the field to add to the object
- * @param amount valid amount to pack
- * @return json pack specification
- */
-struct GNUNET_JSON_PackSpec
-TALER_JSON_pack_amount_nbo (const char *name,
- const struct TALER_AmountNBO *amount);
-
-
-/**
- * Generate packer instruction for a JSON field of type
* encrypted contract.
*
* @param name name of the field to add to the object
@@ -239,16 +214,6 @@ TALER_JSON_from_amount (const struct TALER_Amount *amount);
/**
- * Convert a TALER amount to a JSON object.
- *
- * @param amount the amount
- * @return a json object describing the amount
- */
-json_t *
-TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO *amount);
-
-
-/**
* Provide specification to parse given JSON object to an amount.
* The @a currency must be a valid pointer while the
* parsing is done, a copy is not made.
@@ -265,20 +230,17 @@ TALER_JSON_spec_amount (const char *name,
/**
- * Provide specification to parse given JSON object to an amount
- * in network byte order.
- * The @a currency must be a valid pointer while the
- * parsing is done, a copy is not made.
+ * Provide specification to parse given JSON object to
+ * a currency specification.
*
* @param name name of the amount field in the JSON
- * @param currency the currency the amount must be in
- * @param[out] r_amount where the amount has to be written
+ * @param[out] r_cspec where the currency spec has to be written
* @return spec for parsing an amount
*/
struct GNUNET_JSON_Specification
-TALER_JSON_spec_amount_nbo (const char *name,
- const char *currency,
- struct TALER_AmountNBO *r_amount);
+TALER_JSON_spec_currency_specification (
+ const char *name,
+ struct TALER_CurrencySpecification *r_cspec);
/**
@@ -317,18 +279,6 @@ struct GNUNET_JSON_Specification
TALER_JSON_spec_age_commitment (const char *name,
struct TALER_AgeCommitment *age_commitment);
-/**
- * Provide specification to parse given JSON object to an amount
- * in any currency in network byte order.
- *
- * @param name name of the amount field in the JSON
- * @param[out] r_amount where the amount has to be written
- * @return spec for parsing an amount
- */
-struct GNUNET_JSON_Specification
-TALER_JSON_spec_amount_any_nbo (const char *name,
- struct TALER_AmountNBO *r_amount);
-
/**
* Generate specification to parse all fees for
diff --git a/src/include/taler_util.h b/src/include/taler_util.h
index 4c3a1c9f2..4dcf6f8f8 100644
--- a/src/include/taler_util.h
+++ b/src/include/taler_util.h
@@ -300,8 +300,8 @@ TALER_CONFIG_free_currencies (
* @return JSON object encoding @a cspec for `/config`.
*/
json_t *
-TALER_CONFIG_currency_specs_to_json (const struct
- TALER_CurrencySpecification *cspec);
+TALER_CONFIG_currency_specs_to_json (
+ const struct TALER_CurrencySpecification *cspec);
/**
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
index ab1ce7876..99d8e5b50 100644
--- a/src/json/json_helper.c
+++ b/src/json/json_helper.c
@@ -64,17 +64,6 @@ TALER_JSON_from_amount (const struct TALER_Amount *amount)
}
-json_t *
-TALER_JSON_from_amount_nbo (const struct TALER_AmountNBO *amount)
-{
- struct TALER_Amount a;
-
- TALER_amount_ntoh (&a,
- amount);
- return TALER_JSON_from_amount (&a);
-}
-
-
/**
* Parse given JSON object to Amount
*
@@ -160,7 +149,7 @@ TALER_JSON_spec_amount_any (const char *name,
/**
- * Parse given JSON object to Amount in NBO.
+ * Parse given JSON object to currency spec.
*
* @param cls closure, NULL
* @param root the json object representing data
@@ -168,73 +157,111 @@ TALER_JSON_spec_amount_any (const char *name,
* @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
*/
static enum GNUNET_GenericReturnValue
-parse_amount_nbo (void *cls,
- json_t *root,
- struct GNUNET_JSON_Specification *spec)
+parse_cspec (void *cls,
+ json_t *root,
+ struct GNUNET_JSON_Specification *spec)
{
- const char *currency = cls;
- struct TALER_AmountNBO *r_amount = spec->ptr;
- const char *sv;
+ struct TALER_CurrencySpecification *r_cspec = spec->ptr;
+ const char *name;
+ const char *currency;
+ const char *decimal_separator;
+ uint32_t fid;
+ uint32_t fnd;
+ uint32_t ftzd;
+ const json_t *map;
+ struct GNUNET_JSON_Specification gspec[] = {
+ GNUNET_JSON_spec_string ("currency",
+ &currency),
+ GNUNET_JSON_spec_string ("name",
+ &name),
+ GNUNET_JSON_spec_string ("decimal_separator",
+ &decimal_separator),
+ GNUNET_JSON_spec_uint32 ("num_fractional_input_digits",
+ &fid),
+ GNUNET_JSON_spec_uint32 ("num_fractional_normal_digits",
+ &fnd),
+ GNUNET_JSON_spec_uint32 ("num_fractional_trailing_zero_digits",
+ &ftzd),
+ GNUNET_JSON_spec_bool ("is_currency_name_leading",
+ &r_cspec->is_currency_name_leading),
+ GNUNET_JSON_spec_object_const ("alt_unit_names",
+ &map),
+ GNUNET_JSON_spec_end ()
+ };
+ const char *emsg;
+ unsigned int eline;
(void) cls;
- if (! json_is_string (root))
+ if (GNUNET_OK !=
+ GNUNET_JSON_parse (root,
+ gspec,
+ &emsg,
+ &eline))
{
- GNUNET_break (0);
+ GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
+ "Failed to parse %s at %u: %s\n",
+ spec[eline].field,
+ eline,
+ emsg);
+ GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- sv = json_string_value (root);
- if (GNUNET_OK !=
- TALER_string_to_amount_nbo (sv,
- r_amount))
+ if (strlen (currency) >= TALER_CURRENCY_LEN)
{
- GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
- "`%s' is not a valid amount\n",
- sv);
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
- if ( (NULL != currency) &&
- (0 !=
- strcasecmp (currency,
- r_amount->currency)) )
+ if ( (fid > TALER_AMOUNT_FRAC_LEN) ||
+ (fnd > TALER_AMOUNT_FRAC_LEN) ||
+ (ftzd > TALER_AMOUNT_FRAC_LEN) )
{
GNUNET_break_op (0);
return GNUNET_SYSERR;
}
+ memset (r_cspec->currency,
+ 0,
+ sizeof (r_cspec->currency));
+ /* FIXME: check currency consists only of legal characters! */
+ strcpy (r_cspec->currency,
+ currency);
+ /* FIXME: check map is valid! */
+ r_cspec->name = GNUNET_strdup (name);
+ r_cspec->decimal_separator = GNUNET_strdup (decimal_separator);
+ r_cspec->map_alt_unit_names = json_incref ((json_t *) map);
return GNUNET_OK;
}
-struct GNUNET_JSON_Specification
-TALER_JSON_spec_amount_nbo (const char *name,
- const char *currency,
- struct TALER_AmountNBO *r_amount)
+/**
+ * Cleanup data left from parsing encrypted contract.
+ *
+ * @param cls closure, NULL
+ * @param[out] spec where to free the data
+ */
+static void
+clean_cspec (void *cls,
+ struct GNUNET_JSON_Specification *spec)
{
- struct GNUNET_JSON_Specification ret = {
- .parser = &parse_amount_nbo,
- .cleaner = NULL,
- .cls = (void *) currency,
- .field = name,
- .ptr = r_amount,
- .ptr_size = 0,
- .size_ptr = NULL
- };
+ struct TALER_CurrencySpecification *cspec = spec->ptr;
- GNUNET_assert (NULL != currency);
- return ret;
+ (void) cls;
+ GNUNET_free (cspec->name);
+ GNUNET_free (cspec->decimal_separator);
+ json_decref (cspec->map_alt_unit_names);
}
struct GNUNET_JSON_Specification
-TALER_JSON_spec_amount_any_nbo (const char *name,
- struct TALER_AmountNBO *r_amount)
+TALER_JSON_spec_currency_specification (
+ const char *name,
+ struct TALER_CurrencySpecification *r_cspec)
{
struct GNUNET_JSON_Specification ret = {
- .parser = &parse_amount_nbo,
- .cleaner = NULL,
+ .parser = &parse_cspec,
+ .cleaner = &clean_cspec,
.cls = NULL,
.field = name,
- .ptr = r_amount,
+ .ptr = r_cspec,
.ptr_size = 0,
.size_ptr = NULL
};
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
index 834e8104b..c6844c17b 100644
--- a/src/json/json_pack.c
+++ b/src/json/json_pack.c
@@ -39,15 +39,6 @@ TALER_JSON_pack_time_abs_human (const char *name,
struct GNUNET_JSON_PackSpec
-TALER_JSON_pack_time_abs_nbo_human (const char *name,
- struct GNUNET_TIME_AbsoluteNBO at)
-{
- return TALER_JSON_pack_time_abs_human (name,
- GNUNET_TIME_absolute_ntoh (at));
-}
-
-
-struct GNUNET_JSON_PackSpec
TALER_JSON_pack_econtract (
const char *name,
const struct TALER_EncryptedContract *econtract)
@@ -314,19 +305,4 @@ TALER_JSON_pack_amount (const char *name,
}
-struct GNUNET_JSON_PackSpec
-TALER_JSON_pack_amount_nbo (const char *name,
- const struct TALER_AmountNBO *amount)
-{
- struct GNUNET_JSON_PackSpec ps = {
- .field_name = name,
- .object = (NULL != amount)
- ? TALER_JSON_from_amount_nbo (amount)
- : NULL
- };
-
- return ps;
-}
-
-
/* End of json/json_pack.c */
diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c
index 6009b7c10..811120a85 100644
--- a/src/lib/exchange_api_handle.c
+++ b/src/lib/exchange_api_handle.c
@@ -864,9 +864,9 @@ decode_keys_json (const json_t *resp_obj,
GNUNET_JSON_spec_string (
"currency",
&currency),
- GNUNET_JSON_spec_uint32 (
- "currency_fraction_digits",
- &key_data->currency_fraction_digits),
+ TALER_JSON_spec_currency_specification (
+ "currency_specification",
+ &key_data->cspec),
GNUNET_JSON_spec_string (
"asset_type",
&asset_type),
@@ -2381,8 +2381,9 @@ TALER_EXCHANGE_keys_to_json (const struct TALER_EXCHANGE_Keys *kd)
kd->version),
GNUNET_JSON_pack_string ("currency",
kd->currency),
- GNUNET_JSON_pack_uint64 ("currency_fraction_digits",
- kd->currency_fraction_digits),
+ GNUNET_JSON_pack_object_steal ("currency_specification",
+ TALER_CONFIG_currency_specs_to_json (
+ &kd->cspec)),
TALER_JSON_pack_amount ("stefan_abs",
&kd->stefan_abs),
TALER_JSON_pack_amount ("stefan_log",
diff --git a/src/util/amount.c b/src/util/amount.c
index 9cd0739c9..97a1cf46a 100644
--- a/src/util/amount.c
+++ b/src/util/amount.c
@@ -225,6 +225,7 @@ TALER_amount_set_zero (const char *cur,
sizeof (struct TALER_Amount));
for (unsigned int i = 0; i<slen; i++)
amount->currency[i] = toupper (cur[i]);
+ /* FIXME: check currency consists only of legal characters! */
return GNUNET_OK;
}
diff --git a/src/util/config.c b/src/util/config.c
index 9e1156240..cd30221ac 100644
--- a/src/util/config.c
+++ b/src/util/config.c
@@ -260,6 +260,7 @@ parse_currencies_cb (void *cls,
GNUNET_free (str);
return;
}
+ /* FIXME: validate str has only legal characters in it! */
strcpy (cspec->currency,
str);
GNUNET_free (str);
@@ -388,6 +389,7 @@ parse_currencies_cb (void *cls,
return;
}
}
+ /* FIXME: validate map only maps from decimal numbers to strings! */
}
diff --git a/src/util/currencies.conf b/src/util/currencies.conf
index 4e923943c..3341a9a72 100644
--- a/src/util/currencies.conf
+++ b/src/util/currencies.conf
@@ -3,9 +3,9 @@ ENABLED = YES
name = "Euro"
code = "EUR"
decimal_separator = ","
-num_fractional_input_digits = 2
-num_fractional_normal_digits = 2
-num_fractional_trailing_zero_digits = 2
+fractional_input_digits = 2
+fractional_normal_digits = 2
+fractional_trailing_zero_digits = 2
is_currency_name_leading = NO
alt_unit_names = {"0":"€"}
@@ -14,9 +14,9 @@ ENABLED = YES
name = "Swiss Francs"
code = "CHF"
decimal_separator = "."
-num_fractional_input_digits = 2
-num_fractional_normal_digits = 2
-num_fractional_trailing_zero_digits = 2
+fractional_input_digits = 2
+fractional_normal_digits = 2
+fractional_trailing_zero_digits = 2
is_currency_name_leading = YES
alt_unit_names = {"0":"Fr.","-2":"Rp."}
@@ -25,9 +25,9 @@ ENABLED = NO
name = "Hungarian Forint"
code = "HUF"
decimal_separator = ","
-num_fractional_input_digits = 0
-num_fractional_normal_digits = 0
-num_fractional_trailing_zero_digits = 0
+fractional_input_digits = 0
+fractional_normal_digits = 0
+fractional_trailing_zero_digits = 0
is_currency_name_leading = NO
alt_unit_names = {"0":"Ft"}
@@ -36,9 +36,9 @@ ENABLED = NO
name = "US Dollar"
code = "USD"
decimal_separator = "."
-num_fractional_input_digits = 2
-num_fractional_normal_digits = 2
-num_fractional_trailing_zero_digits = 2
+fractional_input_digits = 2
+fractional_normal_digits = 2
+fractional_trailing_zero_digits = 2
is_currency_name_leading = YES
alt_unit_names = {"0":"$"}
@@ -47,9 +47,9 @@ ENABLED = YES
name = "Kudos (Taler Demonstrator)"
code = "KUDOS"
decimal_separator = ","
-num_fractional_input_digits = 2
-num_fractional_normal_digits = 2
-num_fractional_trailing_zero_digits = 2
+fractional_input_digits = 2
+fractional_normal_digits = 2
+fractional_trailing_zero_digits = 2
is_currency_name_leading = NO
alt_unit_names = {"0":"ク"}
@@ -58,9 +58,9 @@ ENABLED = YES
name = "Test-kudos (Taler Demonstrator)"
code = "TESTKUDOS"
decimal_separator = "."
-num_fractional_input_digits = 2
-num_fractional_normal_digits = 2
-num_fractional_trailing_zero_digits = 2
+fractional_input_digits = 2
+fractional_normal_digits = 2
+fractional_trailing_zero_digits = 2
is_currency_name_leading = NO
alt_unit_names = {"0":"テ","3":"kテ","-3":"mテ"}
@@ -69,9 +69,9 @@ ENABLED = NO
name = "Japanese Yen"
code = "JPY"
decimal_separator = "."
-num_fractional_input_digits = 2
-num_fractional_normal_digits = 0
-num_fractional_trailing_zero_digits = 2
+fractional_input_digits = 2
+fractional_normal_digits = 0
+fractional_trailing_zero_digits = 2
is_currency_name_leading = YES
alt_unit_names = {"0":"¥"}
@@ -80,9 +80,9 @@ ENABLED = NO
name = "Bitcoin (Mainnet)"
code = "BITCOINBTC"
decimal_separator = "."
-num_fractional_input_digits = 8
-num_fractional_normal_digits = 3
-num_fractional_trailing_zero_digits = 0
+fractional_input_digits = 8
+fractional_normal_digits = 3
+fractional_trailing_zero_digits = 0
is_currency_name_leading = NO
alt_unit_names = {"0":"BTC","-3":"mBTC"}
@@ -91,9 +91,9 @@ ENABLED = NO
name = "WAI-ETHER (Ethereum)"
code = "EthereumWAI"
decimal_separator = "."
-num_fractional_input_digits = 0
-num_fractional_normal_digits = 0
-num_fractional_trailing_zero_digits = 0
+fractional_input_digits = 0
+fractional_normal_digits = 0
+fractional_trailing_zero_digits = 0
is_currency_name_leading = NO
alt_unit_names = {"0":"WAI","3":"KWAI","6":"MWAI","9":"GWAI","12":"Szabo","15":"Finney","18":"Ether","21":"KEther","24":"MEther"}