12.36. DD 36: Currency conversion service

12.36.1. Summary

This document explains the design of the currency conversion service. Such service enables customers to spend their fiat currency to buy Taler coins in a regional currency, and enables merchants to cash-out from the regional currency to fiat.

12.36.2. Motivation

The conversion service (CCS) is fundamental for a regional currency and is missing in the Taler/Libeufin ecosystem.

12.36.3. Definitions

Fiat-issuer is the fiat bank account that belongs to the regional currency issuer; typically, such bank account belongs to one association that runs the infrastructure. This bank account is hosted at the “fiat bank”. Regio-issuer is the bank account that belongs to the local currency issuer but hosted at the bank that generates the regional currency. Such bank is also called “circuit bank”. Regio-exchange is the bank account that belongs to the Taler exchange and that is hosted at the circuit bank. Fiat-target is a bank account hosted in the same currency of fiat-issuer and that belongs to a customer who initiated a cash-out operation. Regio-user is a bank account hosted at the circuit bank that is different from regio-issuer. Fiat-customer is a bank account hosted in the same currency of fiat-issuer, typically owned by customers that want to withdraw Taler coins in the regional currency.

12.36.4. Requirements

  • CCS must not impact the libeufin-nexus structure.

  • CCS must trigger Taler withdrawls every time a customer buys the regional currency (‘cash-in’ operation).

  • CCS must offer cash-out operations.

  • CCS should react as soon as possible to cash-in and cash-out operations.

  • CCS must show its state to administrators and offer management tools.

  • CCS must link every fiat-side of a cash-out to its regional currency counterpart. In particular, because every cash-out starts with a payment P from regio-user to regio-issuer and ends with another payment Q from fiat-issuer to fiat-target, CCS must link P and Q.

12.36.5. Proposed Solution

The following design assumes that CCS is coded in libeufin-bank and that libeufin-bank and libeufin-nexus share the same database with separate schemas. The solution relies on SQL triggers to atomically synchronise cash-in and cash-out operations between the two schemas.

12.36.5.1. SQL triggers and conversion operations

Libeufin-bank controls the conversion support and sets up or removes conversion SQL triggers when necessary. In order for the SQL triggers to perform the conversion operations, the configurable rates/fees are stored in the database and the conversion operations are performed using stored SQL procedures. The SQL triggers and conversion procedures are stored in the libeufin-bank schema.

12.36.5.2. Cash-out operation

Libeufin-bank learns instantly about a cash-out operation, because it’s the service offering such feature. Therefore, as soon as a cash-out operation gets TAN-confirmed, libeufin-bank performs a wire transfer from regio-user to regio-issuer by specifying the amount without any rates/fees applied. Along the same database transaction, a SQL trigger store the instructions of another payment P from fiat-issuer to fiat-target, but this time with the cash-out rates/fees.

Asynchronously, a libeufin-nexus background task picks P and sends it to the fiat bank. Finally, fiat bank conducts P and fiat-target receives the wanted amount. The same libeufin-nexus background task should also retry previous payments like P that failed to be submitted to fiat bank.

12.36.5.3. Cash-in operation

A cashin-in operation starts as soon as the customer sends a fiat payment from fiat-customer to fiat-issuer.

The libeufin-nexus component is responsible to query the fiat bank via EBICS every X seconds. X should match the tightest interval allowed by the bank.

When libeufin-nexus registers an incoming payment on fiat-issuer in the database, a SQL trigger applies the current cash-in rates/fees and performs a wire transfer from regio-issuer to regio-exchange. Libeufin-bank makes the exchange aware via the Taler Wire Gateway API and from now on, the system proceeds like it always did in Taler.