This LibEuFin tutorial shows how to manage a bank account in the local currency, and how to convert assets from the local to the fiat currency. Such conversion is called cash-out.
This tutorial is based on the Circuit API, and more general information about libEufin can be found in the How-To page.
The first step is building LibEuFin.
If the installation succeeded, configure Sandbox (= the service acting as the bank) with the following command.
$ 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.
$ export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=secret
$ libeufin-sandbox serve
Sandbox should now be listening on the port 5000. Check it with:
$ 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.
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 the following command. The two environment variables LIBEUFIN_SANDBOX_USERNAME and LIBEUFIN_SANDBOX_PASSWORD instruct the CLI to authenticate as the merchant.
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:
{
"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.
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.
{
"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).
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:
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.
"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, as the administrator, with the following command
export LIBEUFIN_SANDBOX_USERNAME=admin
export LIBEUFIN_SANDBOX_PASSWORD=secret
libeufin-cli \
sandbox demobank \
circuit-delete-account --username circuit-shop
The expected output is:
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.
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:
{
"error" : {
"type" : "util-error",
"description" : "Customer 'circuit-shop' not found"
}
}
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:
libeufin-sandbox serve --sms-tan sms_provider_command
Alternatively, for the e-mail TAN:
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 telesign.com. Check contrib/libeufin-tan-sms.sh
and contrib/libeufin-tan-email.sh
in the Libeufin repository.