summaryrefslogtreecommitdiff
path: root/libeufin/local-currencies-tutorial.rst
blob: 8182b6688c4619acb42cf2b23bcf60f5d13affc3 (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
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
Create a local currency (experimental)
######################################

This tutorial shows how to setup LibEuFin to act as the
bank of a local currency.  The main features include the
registration and removal of user accounts *(only) by the
admin*, and the possibility to convert the local currency
into fiat (a.k.a. cashing out).

The banking capabilities are offered by a LibEuFin service
called *Sandbox*.  In particular, the tutorial relies on the
:ref:`Circuit API <circuit-api>`.  More information about libEufin
can be found in the :doc:`How-To page </libeufin/nexus-tutorial>`.

The following sections show how to install and launch Sandbox
either `from sources <install-from-sources_>`_, or `with Docker <docker-setup_>`_.


.. _install-from-sources:

Install and config from sources
===============================

First :ref:`build LibEuFin <building-from-source>`.

If the installation succeeded, configure *Sandbox* 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.

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 --port 5016

If Sandbox is running, jump to `this part <after-installation_>`_.

.. _docker-setup:


Install and config with Docker
==============================

First, clone the deployment repository:

.. code-block:: console

   $ git clone git://git.taler.net/deployment

Then navigate to the Docker image location:

.. code-block:: console

   $ cd deployment/nlnet/task1

Now build the image with the following command.

.. code-block:: console

  $ docker build -t nlnet .

If the build step went well, the following command
should suffice to start Sandbox and NGINX, by mapping
the host's 8080 port to the container's 80.

.. code-block:: console

  $ export LIBEUFIN_EXPOSED_PORT=8080
  $ docker run \
    -e LIBEUFIN_EXPOSED_PORT=$LIBEUFIN_EXPOSED_PORT \
    -p $LIBEUFIN_EXPOSED_PORT:80 \
    -it nlnet

The previous command uses a default admin password of 'admin'.
Do **CHANGE** the admin password in a production scenario.  The
following command shows how to start the services with custom
values.

.. note::

   Start the services this way to provide the environment
   suitable for this tutorial.

.. code-block:: console

   $ export MY_ADMIN_PASSWORD=secret
   $ export LIBEUFIN_EXPOSED_PORT=8080
   $ docker run \
     -e LIBEUFIN_SANDBOX_ADMIN_PASSWORD=$MY_ADMIN_PASSWORD \
     -e CURRENCY=NB \
     -e LIBEUFIN_EXPOSED_PORT=$LIBEUFIN_EXPOSED_PORT \
     -v libeufin_data:/libeufin-data \
     -v /tmp:/tmp \
     -p $LIBEUFIN_EXPOSED_PORT:80 \
     -p 5016:5016 \
     -it nlnet

In the example above, Docker:

0.  Sets the admin password to *secret*
1.  Sets the currency to *NB*
2.  Stores the database in a *volume*.  This helps to
    share the database between containers.
3.  Mounts container's ``/tmp`` to the host's, to let
    the reader obtain the file TAN in the same way the
    source-based installation does.
4.  Maps the host's 8080 to the container's 80 port.
5.  Maps the host's 5016 to the container's 5016 port.
    That lets the CLI reach Sandbox inside the container,
    and therefore run the tutorial.

By success, Web browsers get the UI by visiting **http://localhost:8080**

The following command shows how to delete the database,
by deleting its volume.

.. code-block:: console

   $ docker volume rm libeufin_data

Note: the removal might fail because the exited containers
are seen as still using the container.  Please refer to the Docker
documentation for further information.

.. _after-installation:

If Sandbox is running
=====================

Sandbox should now be reachable on the port 5016.  Check it with:

.. code-block:: console

   $ curl http://localhost:5016

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.

.. note::

   Consult :doc:`this document </libeufin/circuit-cli-commands>`,
   to learn all the CLI commands that address the (Circuit) API
   used in this tutorial.

.. code-block:: console

   export LIBEUFIN_SANDBOX_USERNAME=admin
   export LIBEUFIN_SANDBOX_PASSWORD=secret
   export LIBEUFIN_SANDBOX_URL=http://localhost:5016/
   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 the following command.
The two environment variables LIBEUFIN_SANDBOX_USERNAME and
LIBEUFIN_SANDBOX_PASSWORD instruct the CLI to authenticate as the
merchant.


.. _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=CHF: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 CHF: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, as the administrator, 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.  With the following
command, the administrator 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 have succeeded!
Try to `ask the balance <check-balance_>`_ again, and expect one
error like the following:


.. code-block:: console

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


.. note::

   Every Circuit API endpoint is addressed by a CLI subcommand
   whose name starts with ``circuit-``.  The following command
   shows them.
   
   .. code-block:: console
     
      libeufin-cli sandbox demobank | grep circuit

.. _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.