taler-docs

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

063-libeufin-conversion-rate-classes.rst (7590B)


      1 DD 63: LibEufin Conversion Rate Class
      2 #####################################
      3 
      4 :Design status: Accepted
      5 :Implementation status: Implemented
      6 :DD shepherd: TBD
      7 :Historical contributors: Antoine A, Sebastian, Florian Dold
      8 :First published: 2025-05-12
      9 :Last substantive change: 2025-07-01
     10 :Implementation evidence: libeufin (2025-07-16)
     11 :Normative references: ``core/api-corebank.rst``, ``core/api-bank-conversion-info.rst``
     12 
     13 .. note::
     14 
     15    API version numbers and endpoint descriptions below record the migration
     16    plan.  The current Core Bank and Conversion API specifications are
     17    normative.
     18 
     19 Summary
     20 =======
     21 
     22 We need an efficient solution to set specific conversion rates for some users. By efficient this means you do not have to set or update them manually for all accounts and a good way to see what are the current rates and which accounts use them.
     23 
     24 Proposed Solution
     25 =================
     26 
     27 The current global conversion rate schema is:
     28 
     29 .. ts:def:: ConversionRate
     30 
     31   interface ConversionRate {
     32     // Minimum fiat amount authorised for cashin before conversion
     33     cashin_min_amount: Amount;
     34 
     35     // Exchange rate to buy regional currency from fiat
     36     cashin_ratio: DecimalNumber;
     37 
     38     // Regional amount fee to subtract after applying the cashin ratio.
     39     cashin_fee: Amount;
     40 
     41     // Rounding mode used during cashin conversion
     42     cashin_rounding_mode: "zero" | "up" | "nearest";
     43 
     44     // Smallest possible fiat amount, converted amount is rounded to this amount
     45     cashin_tiny_amount: Amount;
     46 
     47     // Minimum regional amount authorised for cashout before conversion
     48     cashout_min_amount: Amount;
     49 
     50     // Exchange rate to sell regional currency for fiat
     51     cashout_ratio: DecimalNumber;
     52 
     53     // Fiat amount fee to subtract after applying the cashout ratio.
     54     cashout_fee: Amount;
     55 
     56     // Rounding mode used during cashout conversion
     57     cashout_rounding_mode: "zero" | "up" | "nearest";
     58 
     59     // Smallest possible fiat amount, converted amount is rounded to this amount
     60     cashout_tiny_amount: Amount;
     61 
     62   }
     63 
     64 This would become the ``default`` class with ``conversion_rate_class_id = 0``, that will be used by all new users that are created with ``conversion_rate_class_id = null`` or updated with a PATCH request with ``conversion_rate_class_id = null``. The administrator would be able to create new classes with values that override some of the default properties:
     65 
     66 .. ts:def:: ConversionRateClassRequest
     67 
     68   interface ConversionRateClassRequest {
     69     // The name of this class
     70     name: string;
     71 
     72     // A description of the class
     73     description?: string;
     74 
     75     // Minimum fiat amount authorised for cashin before conversion
     76     cashin_min_amount?: Amount;
     77 
     78     // Exchange rate to buy regional currency from fiat
     79     cashin_ratio?: DecimalNumber;
     80 
     81     // Regional amount fee to subtract after applying the cashin ratio.
     82     cashin_fee?: Amount;
     83 
     84     // Rounding mode used during cashin conversion
     85     cashin_rounding_mode?: "zero" | "up" | "nearest";
     86 
     87     // Minimum regional amount authorised for cashout before conversion
     88     cashout_min_amount?: Amount;
     89 
     90     // Exchange rate to sell regional currency for fiat
     91     cashout_ratio?: DecimalNumber;
     92 
     93     // Fiat amount fee to subtract after applying the cashout ratio.
     94     cashout_fee?: Amount;
     95 
     96     // Rounding mode used during cashout conversion
     97     cashout_rounding_mode?: "zero" | "up" | "nearest";
     98   }
     99 
    100 .. ts:def:: ConversionRateClass
    101 
    102   interface ConversionRateClass {
    103     // The name of this class
    104     name: string;
    105 
    106     // A description of the class
    107     description?: string;
    108 
    109     // Class unique ID
    110     conversion_rate_class_id: Integer;
    111 
    112     // Number of users affected to this class
    113     num_users: Integer;
    114 
    115     // Applied conversion rate
    116     conversion_rate: ConversionRate;
    117 
    118     // Minimum fiat amount authorised for cashin before conversion
    119     cashin_min_amount?: Amount;
    120 
    121     // Exchange rate to buy regional currency from fiat
    122     cashin_ratio?: DecimalNumber;
    123 
    124     // Regional amount fee to subtract after applying the cashin ratio.
    125     cashin_fee?: Amount;
    126 
    127     // Rounding mode used during cashin conversion
    128     cashin_rounding_mode?: "zero" | "up" | "nearest";
    129 
    130     // Minimum regional amount authorised for cashout before conversion
    131     cashout_min_amount?: Amount;
    132 
    133     // Exchange rate to sell regional currency for fiat
    134     cashout_ratio?: DecimalNumber;
    135 
    136     // Fiat amount fee to subtract after applying the cashout ratio.
    137     cashout_fee?: Amount;
    138 
    139     // Rounding mode used during cashout conversion
    140     cashout_rounding_mode?: "zero" | "up" | "nearest";
    141   }
    142 
    143 .. ts:def:: ConversionRateClasses
    144 
    145   interface ConversionRateClasses {
    146     default: ConversionRate;
    147     classes: ConversionRateClass[];
    148   }
    149 
    150 
    151 After creating a new converion class, that needs to be associated with the user.
    152 
    153 When we run the conversion logic we take values from the user class and fallback to the default values when they are ``null``.
    154 
    155 If an admin want to prevent a group of user or exchanges from doing conversion between currencies then those users should be associated with a conversion class with ``cashin_ratio = 0`` to disable any cashin operation or ``cashout_ratio = 0`` to disable any cashout operation.
    156 
    157 
    158 Taler Conversion Info API
    159 -------------------------
    160 
    161 The version changes to v2.
    162 
    163 The migration moved the conversion-info API from ``/conversion-info/*`` to
    164 ``/accounts/$USERNAME/conversion-info/*`` to take user-specific conversion
    165 rates into account.
    166 
    167 A ``/rate`` to get, the potentially private, user specific conversion rate.
    168 
    169 Taler Core Bank API
    170 -------------------
    171 
    172 The design targeted Core Bank API v9.  The current normative Core Bank API has
    173 since advanced beyond that version.
    174 
    175 Deprecated API that should not longer be used:
    176 
    177 
    178 Removed the field ``min_cashout``, not longer used. Replaced by a convertion rate class reference.
    179 
    180 Removed sub-api ``/conversion-info/*``
    181 
    182 
    183 We added new endpoints for conversion rate class management, only accesible by the admin user:
    184 
    185 POST ``/conversion-rate-classes``
    186 
    187 GET ``/conversion-rate-classes``
    188 
    189 GET ``/conversion-rate-classes/$CLASS-ID``
    190 
    191 PATCH ``/conversion-rate-classes/$CLASS-ID``
    192 
    193 DELETE ``/conversion-rate-classes/$CLASS-ID``
    194 
    195 Added an admin-only ``conversion_rate_class_id`` field of type ``Integer``. It is optional field to POST ``/accounts`` requests (creating an account) and PATCH ``/accounts/$USERNAME`` requests (updating an account).
    196 
    197 
    198 
    199 Added query filter to GET ``/accounts`` (listing accounts)
    200 
    201 Added ``conversion_rate_class`` field of type ``AccountConversionRateClass`` of GET ``/accounts/$USERNAME`` request with all the information about the convertion rate. ``conversion_rate_class_id`` points to the class assigned to the user but the values of the fields could be from the default class if the assigned class is not completed.
    202 
    203 
    204 
    205 Added sub-api ``/conversion-rate-class/$CLASS-ID/conversion-info/*``. This is used by admin to run simulations to know how the conversion rate behaves regartherless of the user on the group.
    206 
    207 Added sub-api ``/accounts/$USERNAME/conversion-info/*``. This is used by normal users get the right convertion rate for it's own operations. For user with ``is_taler_exchange = true`` this sub-api will be public.
    208 
    209 
    210 
    211 There are also new error code reported by the API, like ``TALER_EC_BANK_CONVERSION_RATE_CLASS_UNKNOWN`` when the client is trying to create or update an account.
    212 
    213 Specification follow-up
    214 ^^^^^^^^^^^^^^^^^^^^^^^
    215 
    216 The conversion-rate-class endpoints and error codes are now part of the
    217 normative Core Bank API.  Clients should use that specification rather than
    218 the historical endpoint inventory above.