summaryrefslogtreecommitdiff
path: root/design-documents/036-currency-conversion-service.rst
blob: 92d8849987bf3824c4f613541910469c3d3947de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
DD 36: Currency conversion service
##################################

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.

Motivation
==========

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

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.

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.

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.

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.

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.

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.