summaryrefslogtreecommitdiff
path: root/libeufin/local-currencies-tutorial.rst
blob: f2b55befe3e171f6cf508a15369f1e66893c8b60 (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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
Create a local currency (experimental)
######################################

The following commands are based on the :ref:`Circuit API <circuit-api>`,
that allows to register merchants to participate
in a local currency circuit.  The main difference with ordinary
registrations is that this API offers to associate a `cash-out`
address to the account, so that merchants can convert the local
currency back to their fiat bank account.

The following commands show a minimal use case where the
administrator adds a merchant to the circuit, then this latter
would cash-out their assets, and finally the administrator
deletes the merchant account.

More general information about libEufin can be found in the
:doc:`How-To page </libeufin/nexus-tutorial>`.

After having built libEufin (see :ref:`dedicate section <building-from-source>`),
configure *Sandbox* (= the service acting as the bank) with the following command.

.. code-block:: console

   $ export LIBEUFIN_SANDBOX_DB_CONNECTION=jdbc:sqlite:/tmp/libeufin.sqlite3
   $ libeufin-sandbox config --currency NB --without-registrations default

.. note::

   The ``--without-registrations`` option allows *only the administrator*
   to add new accounts.  Without this option, other APIs may offer
   unrestricted registrations.

All the commands mentioned in the following steps support a ``--help``
option that lists all the available options under the related command.

If the configuration step succeeded, Sandbox should be ready to serve the
bank for a currency named `NB`.

In following step, we launch Sandbox by setting the administrator
password as ``secret``.

.. note::

   The following command launches Sandbox so that it writes
   TANs on the filesystem to ease the cash-out operations without
   relying on an `actual e-mail or SMS provider <email-sms-setup_>`_.
.. code-block:: console

   $ export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=secret
   $ libeufin-sandbox serve

Sandbox should now be listening on the port 5000.  Check it with:

.. code-block:: console

   $ curl http://localhost:5000

If Sandbox is correctly running, it should respond with a greeting message.
At this point, the administrator can add a new merchant to the bank with the
following command.

.. code-block:: console

   export LIBEUFIN_SANDBOX_USERNAME=admin
   export LIBEUFIN_SANDBOX_PASSWORD=secret
   export LIBEUFIN_SANDBOX_URL=http://localhost:5000/
   export LIBEUFIN_NEW_CIRCUIT_ACCOUNT_PASSWORD=shop-secret

   libeufin-cli \
     sandbox \
     demobank \
     circuit-register \
       --name "Circuit Shop" \
       --username circuit-shop \
       --cashout-address payto://iban/CH463312 \
       --internal-iban INT940993

If the previous step succeeded, the merchant should have
access to their bank account with the *circuit-shop* username
and *shop-secret* password.

Check it by asking the merchant balance with this command:

.. _check-balance:

.. code-block:: console

   export LIBEUFIN_SANDBOX_USERNAME=circuit-shop
   export LIBEUFIN_SANDBOX_PASSWORD=shop-secret

   libeufin-cli sandbox demobank info --bank-account circuit-shop

The expected response looks like the following one:


.. code-block:: console

   {
     "balance" : {
       "amount" : "NB:0",
       "credit_debit_indicator" : "credit"
     },
     "paytoUri" : "payto://iban/SANDBOXX/INT940993?receiver-name=Circuit+Shop",
     "iban" : "INT940993"
   }

In the following example, the merchant creates a cash-out operation,
trying to convert 1 NB back to the fiat currency.  The ``--amount-debit``
option takes the amount that the merchant wants to be debited
in their local currency bank account, whereas the ``--amount-credit``
option is the calculation of the conversion rates as expected
by the merchant.  The two values will be checked by the bank along
this request, to make sure that both parties agree.

.. note::
  
   The current version has a fixed **0.95** conversion rate for cashing
   out.  Future version will make this value configurable.

.. code-block:: console

  libeufin-cli \
    sandbox \
    demobank \
    circuit-cashout \
      --amount-debit=NB:1 \
      --amount-credit=FIAT:0.95 \
      --tan-channel=file

If the previous command succeeded, it returned a JSON looking
like the following, although most likely having a **different**
UUID.

.. code-block:: console

   {
     "uuid" : "de12389b-e477-4a0c-829e-f779c1cfb3a0"
   }

The *uuid* represents the cash-out operation being just created
and waiting to be confirmed with a TAN.

.. note::

   The current version provides **only** the local currency
   side of such operation.  In other words, the merchant can
   now only see a deduction on their local currency bank account
   but no incoming payment in their fiat bank account.  Future
   versions will implement this.

Confirm now the cash-out operation by sending to the
bank the TAN found in the file ``/tmp/libeufin-cashout-tan.txt``.
Assuming that the TAN for it is ``WXYZ``, the next command will confirm
it to the bank (please, use **your** UUID).

.. code-block:: console

   libeufin-cli \
     sandbox demobank circuit-cashout-confirm \
       --uuid de12389b-e477-4a0c-829e-f779c1cfb3a0 \
       --tan WXYZ

Check now that the cash-out operation appears as a outgoing
transaction for the merchant:

.. code-block:: console

  libeufin-cli \
    sandbox demobank list-transactions \
      --bank-account circuit-shop

The expected output should contain one line like the
following.  That witnesses that the cash-out was correctly
confirmed and scheduled to be transferred to the fiat
account.

.. code-block:: console

   "subject" : "Cash-out of NB:1 to FIAT:0.95"

The next commands show how to delete one account from
the local currency circuit.  For the deletion to succeed,
the account must have a balance of zero NB.  Because
of the cash-out operation, the merchant has now -1 NB
to their account, therefore the deletion will fail.  Check
it with the following command:


.. _delete-account:

.. code-block:: console
   
   export LIBEUFIN_SANDBOX_USERNAME=admin
   export LIBEUFIN_SANDBOX_PASSWORD=secret
  
   libeufin-cli \
     sandbox demobank \
     circuit-delete-account --username circuit-shop

The expected output is:

.. code-block:: console

   Unexpected response status: 412
   Response: {
     "error" : {
       "type" : "sandbox-error",
       "description" : "Account circuit-shop doesn't have zero balance.  Won't delete it"
     }
   }


The bank may now award 1 NB to the merchant to bring their
balance to zero and finally delete the account.  The following
command awards 1 NB to the merchant.

.. code-block:: console

   libeufin-cli \
     sandbox demobank new-transaction \
       --bank-account admin \
       --payto-with-subject "payto://iban/SANDBOXX/INT940993?message=bring-to-zero" \
       --amount NB:1

Check if the balance returned to zero with `this command <check-balance_>`_,
and try again to delete the account `like already done <delete-account_>`_

Now the deletion command should succeed!  Try asking
again the balance, and expect one error like the following:


.. code-block:: console

   {
     "error" : {
       "type" : "util-error",
       "description" : "Customer 'circuit-shop' not found"
     }
   }


Finally, the following command shows a list that includes all
the operations that use the Circuit API: those named ``circuit-*``.

.. code-block:: console

   libeufin-cli sandbox demobank


.. _email-sms-setup:

E-mail or SMS TAN setup
-----------------------

SMS and E-mail TANs get sent via commands that
are invoked by the Sandbox.  Sandbox learns about those commands
via optional parameters to the ``serve`` command.

.. note::

  Future versions will allow setting the external commands
  via the configuration; follow `#7527 <https://bugs.gnunet.org/view.php?id=7527>`_.

Hence, starting Sandbox as shown in the following commands is
the **only** requirement to use the aforementioned TAN channels.

For the SMS TAN:

.. code-block:: console

   libeufin-sandbox serve --sms-tan sms_provider_command

Alternatively, for the e-mail TAN:

.. code-block:: console

   libeufin-sandbox serve --email-tan email_provider_command

Both commands will be passed the TAN to STDIN and the target
phone number / e-mail address as their first command line argument.

.. note::

   The way the invoked commands interact with their providers
   is out of the Sandbox scope.

Finally, Libeufin ships two TAN commands as example.  The e-mail
command relies on `GNU mail <mailutils.org>`_ and the SMS command
on the service offered by `<telesign.com>`_.  Check ``contrib/libeufin-tan-sms.sh``
and ``contrib/libeufin-tan-email.sh`` in the Libeufin repository.