taler-docs

Documentation for GNU Taler components, APIs and protocols
Log | Files | Refs | README | LICENSE

commit 17994444afb9a8ef5e2aa04b727ebf3651b0c08f
parent 730e586de44576bd106c337e87b03fd192b5fb7a
Author: Christian Grothoff <grothoff@gnunet.org>
Date:   Thu,  5 Oct 2023 16:37:07 +0200

review DD51

Diffstat:
Mdesign-documents/050-libeufin-nexus.rst | 4++--
Mdesign-documents/051-fractional-digits.rst | 98+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
2 files changed, 85 insertions(+), 17 deletions(-)

diff --git a/design-documents/050-libeufin-nexus.rst b/design-documents/050-libeufin-nexus.rst @@ -1,5 +1,5 @@ -DD 050: Libeufin-Nexus -###################### +DD 50: Libeufin-Nexus +##################### Summary ======= diff --git a/design-documents/051-fractional-digits.rst b/design-documents/051-fractional-digits.rst @@ -5,18 +5,23 @@ Summary ======= This design document specifies how an amount's fractional digits should be rendered. +Note that UIs that cannot render amounts as specified (e.g. because the display does +not support super script digits) may ignore the rendering advice provided by the +protocol under this DD. + Motivation ========== -Since different currencies have different ways to show/render fractionals, the end-user apps should follow these guidelines. +Since different currencies have different ways to show/render fractionals, the +end-user apps should follow these guidelines. Requirements ============ There is already a specification for ScopedCurrencyInfo - this needs to change -We need three characteristics for fractional digits for each currency: +We need three core characteristics for fractional digits for each currency: a) the number of fractional digits [0..8] the user may enter in a TextInputField @@ -28,13 +33,29 @@ c) the number of fractional digits [0..8] to be rendered as trailing zeroes (inc E.g. if this is 2 (and normal == 2), then render $5 as “$ 5.00”. If this is 3 (and normal == 2), then render $5 as “$ 5.00⁰” with two normal trailing zeroes and one superscript trailing zero. -Usually, all these three numbers have the same value, which means that in case of e.g. “2” (used for €,$,£) the user can enter -cent/penny values (but not a fraction of those), these cents/pennies are always shown (even if they are 0) as two normal digits -after the decimal separator, and fractions of a cent/penny are rendered as SuperScriptDigits, but only if they are not trailing zeroes. +Usually, all these three numbers have the same value, which means that in case +of e.g. “2” (used for €,$,£) the user can enter cent/penny values (but not a +fraction of those), these cents/pennies are always shown (even if they are 0) +as two normal digits after the decimal separator, and fractions of a +cent/penny are rendered as SuperScriptDigits, but only if they are not +trailing zeroes. + +Additionally, some cryptocurrencies have such huge units, that they are +commonly rendered in milli-units, such as mBTC (milliBTC, 1/1000 of a BTC), +Gwei (Giga-WEI), MWei (Million-WEI), Kwei (Kilo-WEI), or +Mether/Kether/Gether/Tether and more "logical" units such as Szabo and +Finney. See `https://coinguides.org/ethereum-unit-converter-gwei-ether/` if +you want a good laugh. Regardless of the self-inflicted insanity here, this +could also make sense for inflated currencies in some cases. So we probably +should also have the ability to ship such a conversion map. + + -iOS has a built-in currency formatter, which knows how to deal with thousands-separators and where to apply them -(e.g. India uses a mixture of hundreds and thousands instead of putting the separator after each 3 digits like western currencies). -However, this formatter will round after two (or three) fractional digits and thus cannot be used for the whole amount. +iOS has a built-in currency formatter, which knows how to deal with +thousands-separators and where to apply them (e.g. India uses a mixture of +hundreds and thousands instead of putting the separator after each 3 digits +like western currencies). However, this formatter will round after two (or +three) fractional digits and thus cannot be used for the whole amount. (please add information about Android and WebEx here) @@ -42,18 +63,54 @@ However, this formatter will round after two (or three) fractional digits and th Proposed Solution ================= +Protocol considerations +----------------------- + +The exchange, bank and merchant backends would need to be configured (via +their configuration files) to return the following ScopedCurrencyInfo in their +``/config`` and/or ``/keys`` endpoints. The bank returns this so that the +bank SPA can render amounts correctly, the exchange informs the wallets about +the desired way to render the currency, and the merchant backend informs the +merchant SPA --- independently of any particular exchange being used --- how +the merchant SPA should render amounts. Hence, the information will need to be +provisioned by all three services. + .. code-block:: swift public struct ScopedCurrencyInfo: Codable, Sendable { - let decimalSeparator: String // e.g. “.” for $ and ¥; “,” for € - let numFractionalInputDigits: Int // how much digits the user may enter after the decimalSeparator - let numFractionalNormalDigits: Int // €,$,£: 2; some arabic currencies: 3, ¥: 0 - let numFractionalTrailingZeroDigits: Int // usually same as numFractionalNormalDigits, but e.g. might be 2 for ¥ - let isCurrencyNameLeading: Bool // true for “$ 3.50”; false for “3,50 €” + // e.g. “.” for $ and ¥; “,” for € + let decimal_separator: String + // how much digits the user may enter after the decimalSeparator + let num_fractional_input_digits: Integer + // €,$,£: 2; some arabic currencies: 3, ¥: 0 + let num_fractional_normal_digits: Int + // usually same as numFractionalNormalDigits, but e.g. might be 2 for ¥ + let num_fractional_trailing_zero_digits: Int + // true for “$ 3.50”; false for “3,50 €” + let is_currency_name_leading: Bool + // map of powers of 10 to alternative currency names, must + // always have an entry under "0" that defines the base name, + // e.g. "0 => EUR". For BTC, would be "0 => BTC, -3 => mBTC". + let alt_unit_names: Map<Int, String> } -For iOS, we plan to format the integer part of the amount with the built-in currency formatter, then add the fractional part -according to this document. +For very large (2400000) or very tiny amounts (0.000056) the software would +then first represent the number compactly without any fraction (so for our +examples above, 24 * 10^6 and 56 * 10^-6) and then search for the nearest fit +in the alt_unit_names table. The result might then be 24000 KGELD or 0.056 +mGELD, assuming the map had entries for 3 and -3 respectively. Depending on +the table, the result could also be 24 MGELD (6 => MGELD), or 5.6 nGELD +(assuming -6 => nGeld). Fractional rendering rules would still be applied +to the alternative unit name, alas the "num_fractional_input_digits" would +always apply to the unit currency and may need to be adjusted if amounts +are input using an alternative unit name. + + +Implementation considerations +----------------------------- + +For iOS, we plan to format the integer part of the amount with the built-in +currency formatter, then add the fractional part according to this document. (please add information about Android and WebEx here) @@ -66,9 +123,20 @@ Definition of Done DoD is not satisfied yet, a user-facing feature **must** be behind a feature flag or dev-mode flag.) + * Configuration (INI) format finalized and documented in taler.conf man page + * Endpoints of libeufin-bank, fakebank, exchange and merchant return the information + * SPAs use the information to render amounts + * Wallet-core passes rendering information to wallet UIs + * WebExtension, Android and iOS Apps render amounts accordingly + + Alternatives ============ +None, we cannot confuse users by rendering amounts in ways that break cultural +standards, and we cannot round and have numbers in balances not add up. + + Drawbacks =========