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 `. More information about libEufin can be found in the :doc:`How-To page `. The following sections show how to install and launch Sandbox either `from sources `_, or `with Docker `_. .. _install-from-sources: Install and config from sources =============================== First :ref:`build LibEuFin `. 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 `_. .. code-block:: console $ export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=secret $ libeufin-sandbox serve --port 5016 If Sandbox is running, jump to `this part `_. .. _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 `, 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 `_, and try again to delete the account `like already done `_ Now the deletion command should have succeeded! Try to `ask the 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 `_. 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 `_ and the SMS command on the service offered by ``_. Check ``contrib/libeufin-tan-sms.sh`` and ``contrib/libeufin-tan-email.sh`` in the Libeufin repository.