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.