taler-docs

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

036-currency-conversion-service.rst (4670B)


      1 DD 36: Currency conversion service
      2 ##################################
      3 
      4 :Design status: Accepted
      5 :Implementation status: Partial
      6 :DD shepherd: TBD
      7 :Historical contributors: Marcello Stanisci, Özgür Kesim, Antoine A, Christian Grothoff
      8 :First published: 2023-02-13
      9 :Last substantive change: 2023-12-15
     10 :Implementation evidence: taler-android (2023-12-05)
     11 :Normative references: ``core/api-corebank.rst``, ``core/api-bank-conversion-info.rst``
     12 
     13 Summary
     14 =======
     15 
     16 This document explains the design of the currency conversion
     17 service.  Such service enables customers to spend their fiat
     18 currency to buy Taler coins in a regional currency, and enables
     19 merchants to cash-out from the regional currency to fiat.
     20 
     21 Motivation
     22 ==========
     23 
     24 The conversion service (CCS) is fundamental for a regional
     25 currency and is missing in the Taler/Libeufin ecosystem.
     26 
     27 Definitions
     28 ===========
     29 
     30 *Fiat-issuer* is the fiat bank account that belongs to the regional currency
     31 issuer; typically, such bank account belongs to one association that runs the
     32 infrastructure.  This bank account is hosted at the "fiat bank".  *Regio-issuer*
     33 is the bank account that belongs to the local
     34 currency issuer but hosted at the bank that generates the regional currency.
     35 Such bank is also called "circuit bank".  *Regio-exchange* is the bank account
     36 that belongs to the Taler exchange and that is hosted at the circuit bank.
     37 *Fiat-target* is a bank account hosted in the same currency of fiat-issuer
     38 and that belongs to a customer who initiated a cash-out operation.  *Regio-user*
     39 is a bank account hosted at the circuit bank that is different from regio-issuer.
     40 *Fiat-customer* is a bank account hosted in the same currency of fiat-issuer,
     41 typically owned by customers that want to withdraw Taler coins in the regional
     42 currency.
     43 
     44 Requirements
     45 ============
     46 
     47 * CCS must not impact the libeufin-nexus structure.
     48 * CCS must trigger Taler withdrawls every time a customer buys the
     49   regional currency ('cash-in' operation).
     50 * CCS must offer cash-out operations.
     51 * CCS should react as soon as possible to cash-in and cash-out operations.
     52 * CCS must show its state to administrators and offer management tools.
     53 * CCS must link every fiat-side of a cash-out to its regional currency
     54   counterpart.  In particular, because every cash-out starts with a
     55   payment *P* from regio-user to regio-issuer and ends with another
     56   payment *Q* from fiat-issuer to fiat-target, CCS must link P and Q.
     57 
     58 Proposed Solution
     59 =================
     60 
     61 The following design assumes that CCS is coded in libeufin-bank and that
     62 libeufin-bank and libeufin-nexus share the same database with separate
     63 schemas. The solution relies on SQL triggers to atomically synchronise
     64 cash-in and cash-out operations between the two schemas.
     65 
     66 SQL triggers and conversion operations
     67 --------------------------------------
     68 
     69 Libeufin-bank controls the conversion support and sets up or removes
     70 conversion SQL triggers when necessary. In order for the SQL triggers to
     71 perform the conversion operations, the configurable rates/fees are stored
     72 in the database and the conversion operations are performed using stored
     73 SQL procedures. The SQL triggers and conversion procedures are stored in
     74 the libeufin-bank schema.
     75 
     76 Cash-out operation
     77 ------------------
     78 
     79 Libeufin-bank learns instantly about a cash-out operation, because it's
     80 *the* service offering such feature. Therefore, as soon as a cash-out
     81 operation gets TAN-confirmed, libeufin-bank performs a wire transfer from
     82 regio-user to regio-issuer by specifying the amount without any rates/fees
     83 applied. Along the same database transaction, a SQL trigger stores the
     84 *instructions* of another payment *Q* from fiat-issuer to fiat-target,
     85 but this time **with** the cash-out rates/fees.
     86 
     87 Asynchronously, a libeufin-nexus background task picks Q and sends it to
     88 the fiat bank. Finally, fiat bank conducts Q and fiat-target receives the
     89 wanted amount. The same libeufin-nexus background task should also retry
     90 previous payments like Q that failed to be submitted to fiat bank.
     91 
     92 Cash-in operation
     93 -----------------
     94 
     95 A cashin-in operation starts as soon as the customer sends a fiat
     96 payment from fiat-customer to fiat-issuer.
     97 
     98 The libeufin-nexus component is responsible to query the fiat bank
     99 via EBICS every X seconds. X should match the tightest interval allowed
    100 by the bank.
    101 
    102 When libeufin-nexus registers an incoming payment on fiat-issuer in the
    103 database, a SQL trigger applies the **current** cash-in rates/fees and
    104 performs a wire transfer from regio-issuer to regio-exchange. Libeufin-bank
    105 makes the exchange aware via the Taler Wire Gateway API and from now on,
    106 the system proceeds like it always did in Taler.