summaryrefslogtreecommitdiff
path: root/design-documents/036-currency-conversion-service.rst
blob: 319896bbcc6f0253c5e1b7cb5b34d84212512cca (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
98
99
100
101
102
103
104
105
106
107
108
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 Nexus structure.
* CCS must trigger Taler withdrawls every time a customer buys the
  regional currency ('buy-in' operation).
* CCS must offer cash-out operations.
* CCS should react as soon as possible to buy-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 into libeufin Sandbox.

Cash-out operation
------------------

The libeufin Sandbox component 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,
Sandbox performs a first wire transfer from regio-user to regio-issuer
by specifying the amount without any rates/fees applied.  Along
the same database transaction, Sandbox stores the *instructions*
of another payment *P* from fiat-issuer to fiat-target, but this time
**with** the cash-out rates/fees.  Notably, P includes the **current**
fiat-target and the rates/fees, since these are configurable.

Asynchronously, a 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 background task should also retry previous payments
like P that failed to be submitted to fiat bank.

CCS offers management endpoints for prepared fiat-transactions.
Through them, adminisrators can see, retry, or cancel every fiat-transaction
that was prepared to pay fiat-target.

Buy-in operation
----------------

A buy-in operation starts as soon as the customer sends a fiat
payment from fiat-customer to fiat-issuer.  Sandbox is responsible to
detect such an incoming payment in a timely fashion.  The detection
happens by long polling on the Nexus JSON API.  Nexus is ultimately
responsible to query the fiat bank via EBICS every X seconds.  X
should match the tightest interval allowed by the bank.

When Sandbox detects one incoming payment on fiat-issuer, it applies the
**current** buy-in rates/fees and wires the resuling amount from regio-issuer
to regio-exchange.  At this point, Nexus detects the incoming payment on
regio-exchange and makes the exchange aware via the Taler Wire Gateway API.
From now on, the system proceeds like it always did in Taler.

Milestones to a MVP
===================

*  Refactor configuration in Sandbox: `7527 <https://bugs.gnunet.org/view.php?id=7527>`_, `7515 <https://bugs.gnunet.org/view.php?id=7515>`_.
*  Make rates/fees and TAN channels configurable in Sandbox: `7694 <https://bugs.gnunet.org/view.php?id=7694>`_.
*  Long polling in Nexus to serve TWG: `6987 <https://bugs.gnunet.org/view.php?id=6987>`_, `6383 <https://bugs.gnunet.org/view.php?id=6383>`_.
*  Long polling in Nexus to serve fiat-transactions via native API: `7693 <https://bugs.gnunet.org/view.php?id=7693>`_.
*  Long polling in Sandbox to ask Nexus fiat-transactions via native API.
*  Serve transactions with date ranges in Sandbox Access API: `7685 <https://bugs.gnunet.org/view.php?id=7685>`_
*  Implement JSON-based "bank connection" in Nexus.  That's how Nexus
   gets regio-transactions to serve in the TWG.
*  Implement fiat-bank's EBICS flavor.
*  Ask transactions with date ranges in such flavor in Nexus: `7686 <https://bugs.gnunet.org/view.php?id=7686>`_.
*  Implement fiat-transactions management tools.

.. note::
  The list can be incomplete and not necessarily ordered.