summaryrefslogtreecommitdiff
path: root/texinfo/taler-developer-manual.texi
diff options
context:
space:
mode:
Diffstat (limited to 'texinfo/taler-developer-manual.texi')
-rw-r--r--texinfo/taler-developer-manual.texi2731
1 files changed, 2731 insertions, 0 deletions
diff --git a/texinfo/taler-developer-manual.texi b/texinfo/taler-developer-manual.texi
new file mode 100644
index 00000000..5c7dbc73
--- /dev/null
+++ b/texinfo/taler-developer-manual.texi
@@ -0,0 +1,2731 @@
+\input texinfo @c -*-texinfo-*-
+@c %**start of header
+@setfilename taler-developer-manual.info
+@documentencoding UTF-8
+@ifinfo
+@*Generated by Sphinx 3.4.3.@*
+@end ifinfo
+@settitle Taler Developer Manual
+@defindex ge
+@paragraphindent 0
+@exampleindent 4
+@finalout
+@dircategory CATEGORY
+@direntry
+* MENU ENTRY: (taler-developer-manual.info). DESCRIPTION
+@end direntry
+
+@definfoenclose strong,`,'
+@definfoenclose emph,`,'
+@c %**end of header
+
+@copying
+@quotation
+GNU Taler 0.8.0pre0, Apr 26, 2021
+
+GNU Taler team
+
+Copyright @copyright{} 2014-2021 Taler Systems SA (GPLv3+ or GFDL 1.3+)
+@end quotation
+
+@end copying
+
+@titlepage
+@title Taler Developer Manual
+@insertcopying
+@end titlepage
+@contents
+
+@c %** start of user preamble
+
+@c %** end of user preamble
+
+@ifnottex
+@node Top
+@top Taler Developer Manual
+@insertcopying
+@end ifnottex
+
+@c %**start of body
+@anchor{taler-developer-manual doc}@anchor{0}
+@c This file is part of GNU TALER.
+@c
+@c Copyright (C) 2014-2021 Taler Systems SA
+@c
+@c TALER is free software; you can redistribute it and/or modify it under the
+@c terms of the GNU General Public License as published by the Free Software
+@c Foundation; either version 2.1, or (at your option) any later version.
+@c
+@c TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+@c WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+@c A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+@c
+@c You should have received a copy of the GNU General Public License along with
+@c TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+@c
+@c @author Christian Grothoff
+
+@menu
+* GNU Taler Release Checklist::
+* GNU Taler Demo Upgrade Checklist::
+* Fundamentals::
+* Language-Specific Guidelines::
+* Taler Deployment on gv.taler.net: Taler Deployment on gv taler net.
+* Demo Upgrade Procedure::
+* Environments and Builders on taler.net: Environments and Builders on taler net.
+* Releases::
+* Continuous integration::
+* Internationalization::
+* Android Apps::
+* Code Coverage::
+* Coding Conventions::
+* Testing library::
+* User-Facing Terminology::
+* Developer Glossary::
+* Developer Tools::
+* Index::
+
+@end menu
+
+@node GNU Taler Release Checklist,GNU Taler Demo Upgrade Checklist,Top,Top
+@anchor{checklist-release doc}@anchor{1}@anchor{checklist-release developer-s-manual}@anchor{2}@anchor{checklist-release gnu-taler-release-checklist}@anchor{3}
+@chapter GNU Taler Release Checklist
+
+
+Release checklists for GNU Taler:
+
+Wallet:
+
+
+@itemize -
+
+@item
+[ ] build wallet
+
+@item
+[ ] verify wallet works against 'test.taler.net'
+
+@item
+[ ] tag repo.
+
+@item
+[ ] upgrade 'demo.taler.net' to 'test.taler.net'
+
+@item
+[ ] upload new wallet release to app store
+
+@item
+[ ] Update bug tracker (mark release, resolved -> closed)
+
+@item
+[ ] Send announcement to @email{taler@@gnu.org}
+
+@item
+[ ] Send announcement to @email{info-gnu@@gnu.org} (major releases only)
+
+@item
+[ ] Send announcement to @email{coordinator@@translationproject.org}
+@end itemize
+
+For exchange:
+
+
+@itemize -
+
+@item
+[ ] check no compiler warnings at "-Wall"
+
+@item
+[ ] ensure Coverity static analysis passes
+
+@item
+[ ] make check.
+
+@item
+[ ] upgrade 'demo.taler.net' to 'test.taler.net'
+
+@item
+[ ] make dist, make check on result of 'make dist'.
+
+@item
+[ ] Change version number in configure.ac.
+
+@item
+[ ] make dist for release.
+
+@item
+[ ] tag repo.
+
+@item
+[ ] Upload triplet to ftp-upload.gnu.org/incoming/ftp or /incoming/alpha
+
+@item
+[ ] Update bug tracker (mark release, resolved -> closed)
+
+@item
+[ ] Send announcement to @email{taler@@gnu.org}
+
+@item
+[ ] Send announcement to @email{info-gnu@@gnu.org} (major releases only)
+
+@item
+[ ] Send announcement to @email{coordinator@@translationproject.org}
+@end itemize
+
+For merchant (C backend):
+
+
+@itemize -
+
+@item
+[ ] check no compiler warnings at "-Wall"
+
+@item
+[ ] ensure Coverity static analysis passes
+
+@item
+[ ] make check.
+
+@item
+[ ] upgrade 'demo.taler.net' to 'test.taler.net'
+
+@item
+[ ] make dist, make check on result of 'make dist'.
+
+@item
+[ ] Change version number in configure.ac.
+
+@item
+[ ] make dist for release.
+
+@item
+[ ] tag repo.
+
+@item
+[ ] Upload triplet to ftp-upload.gnu.org/incoming/ftp or /incoming/alpha
+
+@item
+[ ] Update bug tracker (mark release, resolved -> closed)
+
+@item
+[ ] Send announcement to @email{taler@@gnu.org}
+
+@item
+[ ] Send announcement to @email{info-gnu@@gnu.org} (major releases only)
+
+@item
+[ ] Send announcement to @email{coordinator@@translationproject.org}
+@end itemize
+
+For bank:
+
+
+@itemize -
+
+@item
+TBD
+@end itemize
+
+For Python merchant frontend:
+
+
+@itemize -
+
+@item
+TBD
+@end itemize
+
+For PHP merchant frontend:
+
+
+@itemize -
+
+@item
+TBD
+@end itemize
+
+For auditor:
+
+
+@itemize -
+
+@item
+TBD
+@end itemize
+
+For libebics:
+
+
+@itemize -
+
+@item
+TBD
+@end itemize
+
+@node GNU Taler Demo Upgrade Checklist,Fundamentals,GNU Taler Release Checklist,Top
+@anchor{checklist-demo-upgrade doc}@anchor{4}@anchor{checklist-demo-upgrade gnu-taler-demo-upgrade-checklist}@anchor{5}
+@chapter GNU Taler Demo Upgrade Checklist
+
+
+Post-upgrade checks:
+
+
+@itemize -
+
+@item
+ Run @code{taler-deployment-arm -I} to verify that all services are running.
+
+@item
+ Run the headless wallet to check that services are actually working:
+
+@example
+$ taler-wallet-cli integrationtest \
+ -e https://exchange.demo.taler.net/ \
+ -m https://backend.demo.taler.net/ \
+ -b https://bank.demo.taler.net \
+ -w "KUDOS:10" \
+ -s "KUDOS:5"
+@end example
+@end itemize
+
+Basics:
+
+
+@itemize -
+
+@item
+ Visit @indicateurl{https://demo.taler.net/} to see if the landing page is displayed correctly
+
+@item
+ Visit the wallet installation page, install the wallet, and see if the presence
+indicator is updated correctly.
+
+@item
+ Visit @indicateurl{https://bank.demo.taler.net/}, register a new user and withdraw coins into the
+browser wallet.
+@end itemize
+
+Blog demo:
+
+
+@itemize -
+
+@item
+ Visit @indicateurl{https://shop.demo.taler.net/} and purchase an article.
+
+@item
+ Verify that the balance in the wallet was updated correctly.
+
+@item
+ Go back to @indicateurl{https://shop.demo.taler.net/} and click on the same article
+link. Verify that the article is shown and @strong{no} repeated payment is
+requested.
+
+@item
+ Open the fulfillment page from the previous step in an anonymous browsing session
+(without the wallet installed) and verify that it requests a payment again.
+
+@item
+ Delete cookies on @indicateurl{https://shop.demo.taler.net/} and click on the same article again.
+Verify that the wallet detects that the article has already purchased and successfully
+redirects to the article without spending more money.
+@end itemize
+
+Donation demo:
+
+
+@itemize -
+
+@item
+ Make a donation on @indicateurl{https://donations.demo.taler.net}
+
+@item
+ Make another donation with the same parameters and verify
+that the payment is requested again, instead of showing the previous
+fulfillment page.
+@end itemize
+
+Survey/Tipping:
+
+
+@itemize -
+
+@item
+ Visit @indicateurl{https://survey.demo.taler.net/} and receive a tip.
+
+@item
+ Verify that the survey stats page (@indicateurl{https://survey.demo.taler.net/survey-stats}) is working,
+and that the survey reserve has sufficient funds.
+@end itemize
+
+@cartouche
+@quotation Note
+This manual contains information for developers working on GNU Taler
+and related components. It is not intended for a general audience.
+@end quotation
+@end cartouche
+
+@node Fundamentals,Language-Specific Guidelines,GNU Taler Demo Upgrade Checklist,Top
+@anchor{taler-developer-manual fundamentals}@anchor{6}
+@chapter Fundamentals
+
+
+@menu
+* Bug Tracking::
+* Code Repositories::
+* Committing code::
+* Observing changes::
+* Communication::
+
+@end menu
+
+@node Bug Tracking,Code Repositories,,Fundamentals
+@anchor{taler-developer-manual bug-tracking}@anchor{7}
+@section Bug Tracking
+
+
+Bug tracking is done with Mantis (@indicateurl{https://www.mantisbt.org/}). The bug tracker
+is available at @indicateurl{https://bugs.taler.net}. A registration on the Web site is
+needed in order to use the bug tracker, only read access is granted without a
+login.
+
+@node Code Repositories,Committing code,Bug Tracking,Fundamentals
+@anchor{taler-developer-manual code-repositories}@anchor{8}
+@section Code Repositories
+
+
+Taler code is versioned with Git. For those users without write access, all the
+codebases are found at the following URL:
+
+@example
+git://git.taler.net/<repository>
+@end example
+
+A complete list of all the existing repositories is currently found at
+@indicateurl{https://git.taler.net/}.
+
+@node Committing code,Observing changes,Code Repositories,Fundamentals
+@anchor{taler-developer-manual committing-code}@anchor{9}
+@section Committing code
+
+
+Before you can obtain Git write access, you must sign the copyright
+agreement. As we collaborate closely with GNUnet, we use their
+copyright agreement -- with the understanding that your contributions
+to GNU Taler are included in the assignment. You can find the
+agreement on the GNUnet site@footnote{https://gnunet.org/en/copyright.html}.
+Please sign and mail it to Christian Grothoff as he currently collects
+all the documents for GNUnet e.V.
+
+To obtain Git access, you need to send us your SSH public key. Most core
+team members have administrative Git access, so simply contact whoever
+is your primary point of contact so far. You can
+find instructions on how to generate an SSH key
+in the Git book@footnote{https://git-scm.com/book/en/v2/Git-on-the-Server-Generating-Your-SSH-Public-Key}.
+If you have been granted write access, you first of all must change the URL of
+the respective repository to:
+
+@example
+ssh://git@@git.taler.net/<repository>
+@end example
+
+For an existing checkout, this can be done by editing the @code{.git/config} file.
+
+The server is configured to reject all commits that have not been signed with
+GnuPG. If you do not yet have a GnuPG key, you must create one, as explained
+in the GNU Privacy Handbook@footnote{https://www.gnupg.org/gph/en/manual/c14.html}.
+You do not need to share the respective public key with us to make commits.
+However, we recommend that you upload it to key servers, put it on your
+business card and personally meet with other GNU hackers to have it signed
+such that others can verify your commits later.
+
+To sign all commits, you should run
+
+@example
+$ git config --global commit.gpgsign true
+@end example
+
+You can also sign individual commits only by adding the @code{-S} option to the
+@code{git commit} command. If you accidentally already made commits but forgot
+to sign them, you can retroactively add signatures using:
+
+@example
+$ git rebase -S
+@end example
+
+Whether you commit to a personal branch (recommended: @code{dev/$USER/...}),
+a feature branch or to @code{master} should
+depend on your level of comfort and the nature of the change. As a general
+rule, the code in @code{master} must always build and tests should always pass, at
+least on your own system. However, we all make mistakes and you should expect
+to receive friendly reminders if your change did not live up to this simple
+standard. We plan to move to a system where the CI guarantees this invariant
+in the future.
+
+In order to keep a linear and clean commits history, we advise to avoid
+merge commits and instead always rebase your changes before pushing to
+the @code{master} branch. If you commit and later find out that new commits were
+pushed, the following command will pull the new commits and rebase yours
+on top of them.
+
+@example
+# -S instructs Git to (re)sign your commits
+$ git pull --rebase -S
+@end example
+
+@node Observing changes,Communication,Committing code,Fundamentals
+@anchor{taler-developer-manual observing-changes}@anchor{a}
+@section Observing changes
+
+
+Every commit to the @code{master} branch of any of our public repositories
+(and almost all are public) is automatically sent to the
+@email{gnunet-svn@@gnu.org} mailinglist. That list is for Git commits only,
+and must not be used for discussions. It also carries commits from
+our main dependencies, namely GNUnet and GNU libmicrohttpd. While
+it can be high volume, the lists is a good way to follow overall
+development.
+
+@node Communication,,Observing changes,Fundamentals
+@anchor{taler-developer-manual communication}@anchor{b}
+@section Communication
+
+
+We use the #taler channel on the Freenode IRC network and the @email{taler@@gnu.org}
+public mailinglist for discussions. Not all developers are active on IRC, but
+all developers should probably subscribe to the low-volume Taler mailinglist.
+There are separate low-volume mailinglists for gnunet-developers (@@gnu.org)
+and for libmicrohttpd (@@gnu.org).
+
+@node Language-Specific Guidelines,Taler Deployment on gv taler net,Fundamentals,Top
+@anchor{taler-developer-manual language-specific-guidelines}@anchor{c}
+@chapter Language-Specific Guidelines
+
+
+
+@itemize *
+
+@item
+Python Guidelines
+@end itemize
+
+@node Taler Deployment on gv taler net,Demo Upgrade Procedure,Language-Specific Guidelines,Top
+@anchor{taler-developer-manual taler-deployment-on-gv-taler-net}@anchor{d}
+@chapter Taler Deployment on gv.taler.net
+
+
+This section describes the GNU Taler deployment on @code{gv.taler.net}.
+@code{gv} is our server at BFH. It hosts the Git repositories, Web sites,
+CI and other services. Developers can receive an SSH account and
+e-mail alias for the system. As with Git, ask your primary team
+contact for shell access if you think you need it.
+
+Our old server, @code{tripwire}, is currently offline and will likely
+go back online to host @code{production} systems for operating real
+Taler payments at BFH in the future.
+
+@menu
+* DNS::
+* User Acccounts::
+
+@end menu
+
+@node DNS,User Acccounts,,Taler Deployment on gv taler net
+@anchor{taler-developer-manual dns}@anchor{e}
+@section DNS
+
+
+DNS records for taler.net are controlled by the GNU Taler
+maintainers, specifically Christian and Florian. If you
+need a sub-domain to be added, please contact one of them.
+
+@node User Acccounts,,DNS,Taler Deployment on gv taler net
+@anchor{taler-developer-manual user-acccounts}@anchor{f}
+@section User Acccounts
+
+
+On @code{gv.taler.net}, there are four system users that are set up to
+serve Taler on the Internet:
+
+
+@itemize -
+
+@item
+@code{taler-test}: serves @code{*.test.taler.net} and gets automatically
+built by Buildbot.
+
+@item
+@code{taler-internal}: serves @code{*.int.taler.net}, and does @emph{NOT} get
+automatically built.
+@end itemize
+
+The following two users are @emph{never} automatically built, and they both
+serve @code{*.demo.taler.net}. At any given time, only one is active and
+serves the HTTP requests from the outside; the other one can so be
+compiled without any downtime. If the compilation succeeds, the inactive
+user can be switched to become active (see next section), and vice versa.
+
+
+@itemize -
+
+@item
+@code{demo-blue}
+
+@item
+@code{demo-green}
+@end itemize
+
+@node Demo Upgrade Procedure,Environments and Builders on taler net,Taler Deployment on gv taler net,Top
+@anchor{taler-developer-manual demo-upgrade-procedure}@anchor{10}
+@chapter Demo Upgrade Procedure
+
+
+Upgrading the @code{demo} environment should be done with care, and ideally be
+coordinated on the mailing list before. It is our goal for @code{demo} to always
+run a "working version" that is compatible with various published wallets.
+
+Before deploying on @code{demo}, the same version of all components @strong{must}
+be deployed @emph{and} tested on @code{int}.
+
+Please use the @ref{4,,demo upgrade checklist} to make
+sure everything is working.
+
+@menu
+* Tagging components::
+* Environment Layout::
+* Using envcfg.py: Using envcfg py.
+* Bootstrapping an Environment::
+* Upgrading an Existing Environment::
+* Switching Demo Colors::
+
+@end menu
+
+@node Tagging components,Environment Layout,,Demo Upgrade Procedure
+@anchor{taler-developer-manual tagging-components}@anchor{11}
+@section Tagging components
+
+
+All Taler components must be tagged with git before they are deployed on the
+@code{demo} environment, using a tag of the following form:
+
+@example
+demo-YYYY-MM-DD-SS
+YYYY = year
+MM = month
+DD = day
+SS = serial
+@end example
+
+@node Environment Layout,Using envcfg py,Tagging components,Demo Upgrade Procedure
+@anchor{taler-developer-manual environment-layout}@anchor{12}
+@section Environment Layout
+
+
+Environments have the following layout:
+
+@example
+$HOME/
+ deployment (deployment.git checkout)
+ envcfg.py (configuration of the Taler environment)
+ activate (bash file, sourced to set environment variables)
+ logs/ (log files)
+ local/ (locally installed software)
+ sources/ (sources repos of locally build components)
+ sockets/ (unix domain sockets of running components)
+ taler-data (on-disk state, public and private keys)
+ .config/taler.conf (main Taler configuration file)
+@end example
+
+On @code{demo-blue} and @code{demo-green}, @code{taler-data} is a symlink pointing to @code{$HOME/demo/shared-data}
+instead of a directory.
+
+@node Using envcfg py,Bootstrapping an Environment,Environment Layout,Demo Upgrade Procedure
+@anchor{taler-developer-manual using-envcfg-py}@anchor{13}
+@section Using envcfg.py
+
+
+The @code{$HOME/envcfg.py} file contains (1) the name of the environment and (2) the version
+of all components we build (in the form of a git rev).
+
+The @code{envcfg.py} for demo looks like this:
+
+@example
+env = "demo"
+tag = "demo-2019-10-05-01:
+tag_gnunet = tag
+tag_libmicrohttpd = tag
+tag_exchange = tag
+tag_merchant = tag
+tag_bank = tag
+tag_twister = tag
+tag_landing = tag
+tag_donations = tag
+tag_blog = tag
+tag_survey = tag
+tag_backoffice = tag
+tag_sync = tag
+@end example
+
+Currently only the variables @code{env} and @code{tag_$@{component@}} are used.
+
+When deploying to @code{demo}, the @code{envcfg.py} should be committed to @code{deployment.git/envcfg/envcfg-demo-YYYY-MM-DD-SS.py}.
+
+@node Bootstrapping an Environment,Upgrading an Existing Environment,Using envcfg py,Demo Upgrade Procedure
+@anchor{taler-developer-manual bootstrapping-an-environment}@anchor{14}
+@section Bootstrapping an Environment
+
+
+@example
+$ git clone https://git.taler.net/deployment.git ~/deployment
+$ cp ~/deployment/envcfg/$ENVCFGFILE ~/envcfg.py
+$ ./deployment/bin/taler-deployment bootstrap
+$ source ~/activate
+$ taler-deployment build
+$ taler-deployment-prepare
+$ taler-deployment-start
+$ taler-deployment-arm -I # check everything works
+# The following command sets up the 'blog' and 'donations' instances.
+$ taler-config-instances
+@end example
+
+@node Upgrading an Existing Environment,Switching Demo Colors,Bootstrapping an Environment,Demo Upgrade Procedure
+@anchor{taler-developer-manual upgrading-an-existing-environment}@anchor{15}
+@section Upgrading an Existing Environment
+
+
+@example
+$ rm -rf ~/sources ~/local
+$ git -C ~/deployment pull
+$ cp ~/deployment/envcfg/$ENVCFGFILE ~/envcfg.py
+$ taler-deployment bootstrap
+$ taler-deployment build
+$ taler-deployment-prepare
+$ taler-deployment-restart
+$ taler-deployment-arm -I # check everything works
+@end example
+
+@node Switching Demo Colors,,Upgrading an Existing Environment,Demo Upgrade Procedure
+@anchor{taler-developer-manual switching-demo-colors}@anchor{16}
+@section Switching Demo Colors
+
+
+As the @code{demo} user, to switch to color @code{$@{COLOR@}},
+run the following script from @code{deployment/bin}:
+
+@example
+$ taler-deployment switch-demo
+@end example
+
+@node Environments and Builders on taler net,Releases,Demo Upgrade Procedure,Top
+@anchor{taler-developer-manual environments-and-builders-on-taler-net}@anchor{17}
+@chapter Environments and Builders on taler.net
+
+
+@menu
+* Buildbot implementation::
+* Documentation Builder::
+* Website Builder::
+* Code coverage::
+* Service Checker::
+* Tipping reserve top-up::
+* Producing auditor reports::
+* Database schema versioning::
+
+@end menu
+
+@node Buildbot implementation,Documentation Builder,,Environments and Builders on taler net
+@anchor{taler-developer-manual buildbot-implementation}@anchor{18}
+@section Buildbot implementation
+
+
+GNU Taler uses a buildbot implementation (front end at @indicateurl{https://buildbot.taler.net}) to manage continuous integration. Buildbot documentation is at @indicateurl{https://docs.buildbot.net/}.
+
+Here are some highlights:
+
+
+@itemize -
+
+@item
+The WORKER is the config that that lives on a shell account on a localhost (taler.net), where this host has buildbot-worker installed. The WORKER executes the commands that perform all end-functions of buildbot.
+
+@item
+The WORKER running buildbot-worker receives these commands by authenticating and communicating with the buildbot server using parameters that were specified when the worker was created in that shell account with the @code{buildbot-worker} command.
+
+@item
+The buildbot server's master.cfg file contains FACTORY declarations which specify the commands that the WORKER will run on localhost.
+
+@item
+The FACTORY is tied to the WORKER in master.cfg by a BUILDER.
+
+@item
+The master.cfg also allows for SCHEDULER that defines how and when the BUILDER is executed.
+
+@item
+Our master.cfg file is checked into git, and then periodically updated on a particular account on taler.net (ask Christian for access if needed). Do not edit this file directly/locally on taler.net, but check changes into Git.
+@end itemize
+
+Best Practices:
+
+
+@itemize -
+
+@item
+When creating a new WORKER in the @code{master.cfg} file, leave a comment specifying the server and user account that this WORKER is called from. (At this time, taler.net is the only server used by this implementation, but it's still good practice.)
+
+@item
+Create a worker from a shell account with this command: @code{buildbot-worker create-worker <workername> localhost <username> <password>}
+@end itemize
+
+Then make sure there is a WORKER defined in master.cfg like: @code{worker.Worker("<username>", "<password>")}
+
+@node Documentation Builder,Website Builder,Buildbot implementation,Environments and Builders on taler net
+@anchor{taler-developer-manual documentation-builder}@anchor{19}
+@section Documentation Builder
+
+
+All the Taler documentation is built by the user @code{docbuilder} that
+runs a Buildbot worker. The following commands set the @code{docbuilder} up,
+starting with a empty home directory.
+
+@example
+# Log-in as the 'docbuilder' user.
+
+$ cd $HOME
+$ git clone git://git.taler.net/deployment
+$ ./deployment/bootstrap-docbuilder
+
+# If the previous step worked, the setup is
+# complete and the Buildbot worker can be started.
+
+$ buildbot-worker start worker/
+@end example
+
+@node Website Builder,Code coverage,Documentation Builder,Environments and Builders on taler net
+@anchor{taler-developer-manual website-builder}@anchor{1a}
+@section Website Builder
+
+
+Taler Websites, @code{www.taler.net} and @code{stage.taler.net}, are built by the
+user @code{taler-websites} by the means of a Buildbot worker. The following
+commands set the @code{taler-websites} up, starting with a empty home directory.
+
+@example
+# Log-in as the 'taler-websites' user.
+
+$ cd $HOME
+$ git clone git://git.taler.net/deployment
+$ ./deployment/bootstrap-sitesbuilder
+
+# If the previous step worked, the setup is
+# complete and the Buildbot worker can be started.
+
+$ buildbot-worker start worker/
+@end example
+
+@node Code coverage,Service Checker,Website Builder,Environments and Builders on taler net
+@anchor{taler-developer-manual code-coverage}@anchor{1b}
+@section Code coverage
+
+
+Code coverage tests are run by the @code{lcovworker} user, and are also driven
+by Buildbot.
+
+@example
+# Log-in as the 'lcovworker' user.
+
+$ cd $HOME
+$ git clone git://git.taler.net/deployment
+$ ./deployment/bootstrap-taler lcov
+
+# If the previous step worked, the setup is
+# complete and the Buildbot worker can be started.
+
+$ buildbot-worker start worker/
+@end example
+
+The results are then published at @code{https://lcov.taler.net/}.
+
+@node Service Checker,Tipping reserve top-up,Code coverage,Environments and Builders on taler net
+@anchor{taler-developer-manual service-checker}@anchor{1c}
+@section Service Checker
+
+
+The user @code{demo-checker} runs periodic checks to see if all the
+@code{*.demo.taler.net} services are up and running. It is driven by
+Buildbot, and can be bootstrapped as follows.
+
+@example
+# Log-in as the 'demo-checker' user
+
+$ cd $HOME
+$ git clone git://git.taler.net/deployment
+$ ./deployment/bootstrap-demochecker
+
+# If the previous step worked, the setup is
+# complete and the Buildbot worker can be started.
+
+$ buildbot-worker start worker/
+@end example
+
+@node Tipping reserve top-up,Producing auditor reports,Service Checker,Environments and Builders on taler net
+@anchor{taler-developer-manual tipping-reserve-top-up}@anchor{1d}
+@section Tipping reserve top-up
+
+
+Both 'test' and 'demo' setups get their tip reserve topped up
+by a Buildbot worker. The following steps get the reserve topper
+prepared.
+
+@example
+# Log-in as <env>-topper, with <env> being either 'test' or 'demo'
+
+$ git clone git://git.taler.net/deployment
+$ ./deployment/prepare-reservetopper <env>
+
+# If the previous steps worked, then it should suffice to start
+# the worker, with:
+
+$ buildbot-worker start worker/
+@end example
+
+@node Producing auditor reports,Database schema versioning,Tipping reserve top-up,Environments and Builders on taler net
+@anchor{taler-developer-manual producing-auditor-reports}@anchor{1e}
+@section Producing auditor reports
+
+
+Both 'test' and 'demo' setups get their auditor reports compiled
+by a Buildbot worker. The following steps get the reports compiler
+prepared.
+
+@example
+# Log-in as <env>-auditor, with <env> being either 'test' or 'demo'
+
+$ git clone git://git.taler.net/deployment
+$ ./deployment/prepare-auditorreporter <env>
+
+# If the previous steps worked, then it should suffice to start
+# the worker, with:
+
+$ buildbot-worker start worker/
+@end example
+
+@node Database schema versioning,,Producing auditor reports,Environments and Builders on taler net
+@anchor{taler-developer-manual database-schema-versioning}@anchor{1f}
+@section Database schema versioning
+
+
+The Postgres databases of the exchange and the auditor are versioned.
+See the 0000.sql file in the respective directory for documentation.
+
+Every set of changes to the database schema must be stored in a new
+versioned SQL script. The scripts must have contiguous numbers. After
+any release (or version being deployed to a production or staging
+environment), existing scripts MUST be immutable.
+
+Developers and operators MUST NOT make changes to database schema
+outside of this versioning.
+
+@node Releases,Continuous integration,Environments and Builders on taler net,Top
+@anchor{taler-developer-manual releases}@anchor{20}
+@chapter Releases
+
+
+@menu
+* Release Process and Checklists::
+* Tagging::
+* Database for tests::
+* Exchange@comma{} merchant: Exchange merchant.
+* Wallet WebExtension::
+* Upload to GNU mirrors::
+* Creating Debian packages::
+
+@end menu
+
+@node Release Process and Checklists,Tagging,,Releases
+@anchor{taler-developer-manual release-process-and-checklists}@anchor{21}
+@section Release Process and Checklists
+
+
+Please use the @ref{1,,release checklist}
+
+This document describes the process for releasing a new version of the
+various Taler components to the official GNU mirrors.
+
+The following components are published on the GNU mirrors
+
+
+@itemize -
+
+@item
+taler-exchange (exchange.git)
+
+@item
+taler-merchant (merchant.git)
+
+@item
+talerdonations (donations.git)
+
+@item
+talerblog (blog.git)
+
+@item
+taler-bank (bank.git)
+
+@item
+taler-wallet-webex (wallet-webex.git)
+@end itemize
+
+@node Tagging,Database for tests,Release Process and Checklists,Releases
+@anchor{taler-developer-manual tagging}@anchor{22}
+@section Tagging
+
+
+Tag releases with an @strong{annotated} commit, like
+
+@example
+$ git tag -a v0.1.0 -m "Official release v0.1.0"
+$ git push origin v0.1.0
+@end example
+
+@node Database for tests,Exchange merchant,Tagging,Releases
+@anchor{taler-developer-manual database-for-tests}@anchor{23}
+@section Database for tests
+
+
+For tests in the exchange and merchant to run, make sure that a database
+@emph{talercheck} is accessible by @emph{$USER}. Otherwise tests involving the
+database logic are skipped.
+
+@node Exchange merchant,Wallet WebExtension,Database for tests,Releases
+@anchor{taler-developer-manual exchange-merchant}@anchor{24}
+@section Exchange, merchant
+
+
+Set the version in @code{configure.ac}. The commit being tagged should be
+the change of the version.
+
+Tag the current GANA version that works with the exchange and merchant and
+checkout that tag of gana.git (instead of master). Otherwise, if there are
+incompatible changes in GANA (like removed symbols), old builds could break.
+
+Update the Texinfo documentation using the files from docs.git:
+
+@example
+# Get the latest documentation repository
+$ cd $GIT/docs
+$ git pull
+$ make texinfo
+# The *.texi files are now in _build/texinfo
+#
+# This checks out the prebuilt branch in the prebuilt directory
+$ git worktree add prebuilt prebuilt
+$ cd prebuilt
+# Copy the pre-built documentation into the prebuilt directory
+$ cp -r ../_build/texinfo .
+# Push and commit to branch
+$ git commit -a -S -m "updating texinfo"
+$ git status
+# Verify that all files that should be tracked are tracked,
+# new files will have to be added to the Makefile.am in
+# exchange.git as well!
+$ git push
+# Remember $REVISION of commit
+#
+# Go to exchange
+$ cd $GIT/exchange/doc/prebuilt
+# Update submodule to point to latest commit
+$ git checkout $REVISION
+@end example
+
+Finally, the Automake @code{Makefile.am} files may have to be adjusted to
+include new @code{*.texi} files or images.
+
+For bootstrap, you will need to install
+GNU Recutils@footnote{https://www.gnu.org/software/recutils/}.
+
+For the exchange test cases to pass, @code{make install} must be run first.
+Without it, test cases will fail because plugins can't be located.
+
+@example
+$ ./bootstrap
+$ ./configure # add required options for your system
+$ make dist
+$ tar -xf taler-$COMPONENT-$VERSION.tar.gz
+$ cd taler-$COMPONENT-$VERSION
+$ make install check
+@end example
+
+@node Wallet WebExtension,Upload to GNU mirrors,Exchange merchant,Releases
+@anchor{taler-developer-manual wallet-webextension}@anchor{25}
+@section Wallet WebExtension
+
+
+The version of the wallet is in @emph{manifest.json}. The @code{version_name}
+should be adjusted, and @emph{version} should be increased independently on
+every upload to the WebStore.
+
+@example
+$ ./configure
+$ make dist
+@end example
+
+@node Upload to GNU mirrors,Creating Debian packages,Wallet WebExtension,Releases
+@anchor{taler-developer-manual upload-to-gnu-mirrors}@anchor{26}
+@section Upload to GNU mirrors
+
+
+See @indicateurl{https://www.gnu.org/prep/maintain/maintain.html#Automated-FTP-Uploads}
+
+Directive file:
+
+@example
+version: 1.2
+directory: taler
+filename: taler-exchange-0.1.0.tar.gz
+@end example
+
+Upload the files in @strong{binary mode} to the ftp servers.
+
+@node Creating Debian packages,,Upload to GNU mirrors,Releases
+@anchor{taler-developer-manual creating-debian-packages}@anchor{27}
+@section Creating Debian packages
+
+
+Our general setup is based on
+@indicateurl{https://wiki.debian.org/DebianRepository/SetupWithReprepro}
+
+First, update at least the version of the Debian package in
+debian/changelog, and then run:
+
+@example
+$ dpkg-buildpackage -rfakeroot -b -uc -us
+@end example
+
+in the respective source directory (GNUnet, exchange, merchant) to create the
+@code{.deb} files. Note that they will be created in the parent directory. This
+can be done on gv.taler.net, or on another (secure) machine.
+
+Next, the @code{*.deb} files should be copied to gv.taler.net, say to
+@code{/root/incoming}. Then, run
+
+@example
+# cd /var/www/repos/apt/debian/
+# reprepro includedeb sid /root/incoming/*.deb
+@end example
+
+to import all Debian files from @code{/root/incoming/} into the @code{sid}
+distribution. If Debian packages were build against other distributions,
+reprepro may need to be first configured for those and the import command
+updated accordingly.
+
+Finally, make sure to clean up @code{/root/incoming/} (by deleting the
+now imported @code{*.deb} files).
+
+@node Continuous integration,Internationalization,Releases,Top
+@anchor{taler-developer-manual continuous-integration}@anchor{28}
+@chapter Continuous integration
+
+
+CI is done with Buildbot (@indicateurl{https://buildbot.net/}), and builds are
+triggered by the means of Git hooks. The results are published at
+@indicateurl{https://buildbot.taler.net/} .
+
+In order to avoid downtimes, CI uses a "blue/green" deployment
+technique. In detail, there are two users building code on the system,
+the "green" and the "blue" user; and at any given time, one is running
+Taler services and the other one is either building the code or waiting
+for that.
+
+There is also the possibility to trigger builds manually, but this is
+only reserved to "admin" users.
+
+@node Internationalization,Android Apps,Continuous integration,Top
+@anchor{taler-developer-manual internationalization}@anchor{29}
+@chapter Internationalization
+
+
+Internationalization (a.k.a "Translation") is handled with Weblate (@indicateurl{https://weblate.org}) via our instance at @indicateurl{https://weblate.taler.net/} .
+
+At this time, this system is still very new for Taler.net and this documentation may be incorrect and is certainly incomplete.
+
+@menu
+* Who can Register::
+* About Privilege Levels::
+* Upgrading Privileges::
+* How to Create a Project::
+* How to Create a Component::
+* How to Create a Translation::
+* Translation Standards and Practices::
+* GPG Signing of Translations::
+
+@end menu
+
+@node Who can Register,About Privilege Levels,,Internationalization
+@anchor{taler-developer-manual who-can-register}@anchor{2a}
+@section Who can Register
+
+
+At this time, anyone can register an account at @indicateurl{https://weblate.taler.net/} to create translations. Registered users default to the @strong{Users} and @strong{Viewers} privilege level.
+
+@node About Privilege Levels,Upgrading Privileges,Who can Register,Internationalization
+@anchor{taler-developer-manual about-privilege-levels}@anchor{2b}
+@section About Privilege Levels
+
+
+This is the breakdown of privilege levels in Weblate:
+
+
+@itemize *
+
+@item
+@strong{Users}/@strong{Viewers} = Can log in, view Translations (@emph{applies to new users})
+
+@item
+@strong{Reviewers} = Can contribute Translations to existing @emph{Components}
+
+@item
+@strong{Managers} = Can create new @emph{Components} of existing @emph{Projects}
+
+@item
+@strong{Superusers} = Can create new @emph{Projects}
+@end itemize
+
+@node Upgrading Privileges,How to Create a Project,About Privilege Levels,Internationalization
+@anchor{taler-developer-manual upgrading-privileges}@anchor{2c}
+@section Upgrading Privileges
+
+
+To upgrade from @strong{Users}/@strong{Viewers}, a superuser must manually augment your privileges. At this time, superusers are Christian, Florian, and Buck.
+
+@node How to Create a Project,How to Create a Component,Upgrading Privileges,Internationalization
+@anchor{taler-developer-manual how-to-create-a-project}@anchor{2d}
+@section How to Create a Project
+
+
+The @emph{GNU Taler} project is probably the correct project for most Components and Translations falling under this guide. Please contact a superuser if you need another Project created.
+
+@node How to Create a Component,How to Create a Translation,How to Create a Project,Internationalization
+@anchor{taler-developer-manual how-to-create-a-component}@anchor{2e}
+@section How to Create a Component
+
+
+Reference: @indicateurl{https://docs.weblate.org/en/weblate-4.0.3/admin/projects.html#component-configuration}
+
+In Weblate, a @emph{Component} is a subset of a @emph{Project} and each Component contains N translations. A Component is generally associated with a Git repo.
+
+To create a Component, log into @indicateurl{https://weblate.taler.net/} with your @emph{Manager} or higher credentials and choose @strong{+ Add} from the upper-right corner.
+
+What follows is a sort of Wizard. You can find detailed docs at @indicateurl{https://docs.weblate.org/}. Here are some important notes about connecting your Component to the Taler Git repository:
+
+Under @emph{https://weblate.taler.net/create/component/vcs/}:
+
+
+@itemize *
+
+@item
+@strong{Source code repository} - Generally @code{git+ssh://git@@git.taler.net/<reponame>`}. Check with @code{git remote -v}.
+
+@item
+@strong{Repository branch} - Choose the correct branch to draw from and commit to.
+
+@item
+@strong{Repository push URL} - This is generally @code{git+ssh://git@@git.taler.net/<reponame>`} Check with @code{git remote -v}.
+
+@item
+@strong{Repository browser} - This is the www URL of the Git repo's file browser. Example @code{https://git.taler.net/<repositoryname>.git/tree/@{@{filename@}@}?h=@{@{branch@}@}#n@{@{line@}@}} where @code{<repositoryname>} gets replaced but @code{@{@{filename@}@}} and other items in braces are actual variables in the string.
+
+@item
+@strong{Merge style} - @emph{Rebase}, in line with GNU Taler development procedures
+
+@item
+@strong{Translation license} - @emph{GNU General Public License v3.0 or Later}
+
+@item
+@strong{Adding new translation} - Decide how to handle adding new translations
+@end itemize
+
+@node How to Create a Translation,Translation Standards and Practices,How to Create a Component,Internationalization
+@anchor{taler-developer-manual how-to-create-a-translation}@anchor{2f}
+@section How to Create a Translation
+
+
+1 - Log into @indicateurl{https://weblate.taler.net}
+
+2 - Navigate to @emph{Projects} > @emph{Browse all projects}
+
+3 - Choose the @emph{Project} you wish to contribute to.
+
+4 - Choose the @emph{Component} you wish to contribute to.
+
+5 - Find the language you want to translate into. Click "Translate" on that line.
+
+6 - Find a phrase and translate it.
+
+You may also wish to refer to @indicateurl{https://docs.weblate.org/} .
+
+@node Translation Standards and Practices,GPG Signing of Translations,How to Create a Translation,Internationalization
+@anchor{taler-developer-manual translation-standards-and-practices}@anchor{30}
+@section Translation Standards and Practices
+
+
+By default, our Weblate instance is set to accept translations in English, French, German, Italian, Russian, Spanish, and Portuguese. If you want to contribute a translation in a different language, navigate to the @emph{Component} you want to translate for, and click "Start new translation" to begin. If you require a privilege upgrade, please contact a superuser with your request.
+
+When asked, set the license to GPLv3 or later.
+
+Set commit/push to manual only.
+
+@node GPG Signing of Translations,,Translation Standards and Practices,Internationalization
+@anchor{taler-developer-manual gpg-signing-of-translations}@anchor{31}
+@section GPG Signing of Translations
+
+
+weblate.taler.net signs GPG commits with the GPG key CD33CE35801462FA5EB0B695F2664BF474BFE502, and the corresponding public key can be found at @indicateurl{https://weblate.taler.net/keys/}.
+
+This means that contributions made through weblate will not be signed with the individual contributor's key when they are checked into the Git repository, but with the weblate key.
+
+@node Android Apps,Code Coverage,Internationalization,Top
+@anchor{taler-developer-manual android-apps}@anchor{32}
+@chapter Android Apps
+
+
+@menu
+* Android App Nightly Builds::
+* Building apps from source::
+* Update translations::
+* Release process::
+
+@end menu
+
+@node Android App Nightly Builds,Building apps from source,,Android Apps
+@anchor{taler-developer-manual android-app-nightly-builds}@anchor{33}
+@section Android App Nightly Builds
+
+
+There are currently three Android apps in
+the official Git repository@footnote{https://git.taler.net/taler-android.git}:
+
+
+@itemize *
+
+@item
+Wallet
+[CI@footnote{https://git.taler.net/taler-android.git/tree/wallet/.gitlab-ci.yml}]
+
+@item
+Merchant PoS Terminal
+[CI@footnote{https://git.taler.net/taler-android.git/tree/merchant-terminal/.gitlab-ci.yml}]
+
+@item
+Cashier
+[CI@footnote{https://git.taler.net/taler-android.git/tree/cashier/.gitlab-ci.yml}]
+@end itemize
+
+Their git repositories are mirrored at Gitlab@footnote{https://gitlab.com/gnu-taler/taler-android}
+to utilize their CI
+and F-Droid@footnote{https://f-droid.org}'s Gitlab integration
+to publish automatic nightly builds@footnote{https://f-droid.org/docs/Publishing_Nightly_Builds/}
+for each change on the @code{master} branch.
+
+All three apps publish their builds to the same F-Droid nightly repository
+(which is stored as a git repository):
+@indicateurl{https://gitlab.com/gnu-taler/fdroid-repo-nightly}
+
+You can download the APK files directly from that repository
+or add it to the F-Droid app for automatic updates
+by clicking the following link (on the phone that has F-Droid installed).
+
+@quotation
+
+GNU Taler Nightly F-Droid Repository@footnote{fdroidrepos://gnu-taler.gitlab.io/fdroid-repo-nightly/fdroid/repo?fingerprint=55F8A24F97FAB7B0960016AF393B7E57E7A0B13C2D2D36BAC50E1205923A7843}
+@end quotation
+
+@cartouche
+@quotation Note
+Nightly apps can be installed alongside official releases
+and thus are meant @strong{only for testing purposes}.
+Use at your own risk!
+@end quotation
+@end cartouche
+
+@node Building apps from source,Update translations,Android App Nightly Builds,Android Apps
+@anchor{taler-developer-manual build-apps-from-source}@anchor{34}@anchor{taler-developer-manual building-apps-from-source}@anchor{35}
+@section Building apps from source
+
+
+Note that this guide is different from other guides for building Android apps,
+because it does not require you to run non-free software.
+It uses the Merchant PoS Terminal as an example, but works as well for the other apps
+if you replace @code{merchant-terminal} with @code{wallet} or @code{cashier}.
+
+First, ensure that you have the required dependencies installed:
+
+
+@itemize *
+
+@item
+Java Development Kit 8 or higher (default-jdk-headless)
+
+@item
+git
+
+@item
+unzip
+@end itemize
+
+Then you can get the app's source code using git:
+
+@example
+# Start by cloning the Android git repository
+$ git clone https://git.taler.net/taler-android.git
+
+# Change into the directory of the cloned repository
+$ cd taler-android
+
+# Find out which Android SDK version you will need
+$ grep -i compileSdkVersion merchant-terminal/build.gradle
+@end example
+
+The last command will return something like @code{compileSdkVersion 29}.
+So visit the Android Rebuilds@footnote{http://android-rebuilds.beuc.net/} project
+and look for that version of the Android SDK there.
+If the SDK version is not yet available as a free rebuild,
+you can try to lower the @code{compileSdkVersion} in the app's @code{merchant-terminal/build.gradle} file.
+Note that this might break things
+or require you to also lower other versions such as @code{targetSdkVersion}.
+
+In our example, the version is @code{29} which is available,
+so download the "SDK Platform" package of "Android 10.0.0 (API 29)"
+and unpack it:
+
+@example
+# Change into the directory that contains your downloaded SDK
+$ cd $HOME
+
+# Unpack/extract the Android SDK
+$ unzip android-sdk_eng.10.0.0_r14_linux-x86.zip
+
+# Tell the build system where to find the SDK
+$ export ANDROID_SDK_ROOT="$HOME/android-sdk_eng.10.0.0_r14_linux-x86"
+
+# Change into the directory of the cloned repository
+$ cd taler-android
+
+# Build the merchant-terminal app
+$ ./gradlew :merchant-terminal:assembleRelease
+@end example
+
+If you get an error message complaining about build-tools
+
+@quotation
+
+
+@table @asis
+
+@item > Failed to install the following Android SDK packages as some licences have not been accepted.
+
+build-tools;29.0.3 Android SDK Build-Tools 29.0.3
+@end table
+@end quotation
+
+you can try changing the @code{buildToolsVersion} in the app's @code{merchant-terminal/build.gradle} file
+to the latest "Android SDK build tools" version supported by the Android Rebuilds project.
+
+After the build finished successfully,
+you will find your APK in @code{merchant-terminal/build/outputs/apk/release/}.
+
+@node Update translations,Release process,Building apps from source,Android Apps
+@anchor{taler-developer-manual update-translations}@anchor{36}
+@section Update translations
+
+
+Translations are managed with Taler's weblate instance:
+@indicateurl{https://weblate.taler.net/projects/gnu-taler/}
+
+To update translations, enter the taler-android git repository
+and ensure that the weblate remote exists:
+
+@example
+$ git config -l | grep weblate
+@end example
+
+If it does not yet exist (empty output), you can add it like this:
+
+@example
+$ git remote add weblate https://weblate.taler.net/git/gnu-taler/wallet-android/
+@end example
+
+Then you can merge in translations commit from the weblate remote:
+
+@example
+# ensure you have latest version
+$ git fetch weblate
+
+# merge in translation commits
+$ git merge weblate/master
+@end example
+
+Afterwards, build the entire project from source and test the UI
+to ensure that no erroneous translations (missing placeholders) are breaking things.
+
+@node Release process,,Update translations,Android Apps
+@anchor{taler-developer-manual release-process}@anchor{37}
+@section Release process
+
+
+After extensive testing, the code making up a new release should get a signed git tag.
+The current tag format is:
+
+
+@itemize *
+
+@item
+cashier-$VERSION
+
+@item
+pos-$VERSION
+
+@item
+wallet-$VERSION (where $VERSION has a v prefix)
+@end itemize
+
+@example
+$ git tag -s $APP-$VERSION
+@end example
+
+@menu
+* F-Droid::
+* Google Play::
+
+@end menu
+
+@node F-Droid,Google Play,,Release process
+@anchor{taler-developer-manual id1}@anchor{38}
+@subsection F-Droid
+
+
+Nightly builds get published automatically (see above) after pushing code to the official repo.
+Actual releases get picked up by F-Droid's official repository via git tags.
+So ensure that all releases get tagged properly.
+
+Some information for F-Droid official repository debugging:
+
+
+@itemize *
+
+@item
+Wallet: [metadata@footnote{https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/net.taler.wallet.fdroid.yml}] [build log@footnote{https://f-droid.org/wiki/page/net.taler.wallet.fdroid/lastbuild}]
+
+@item
+Cashier: [metadata@footnote{https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/net.taler.cashier.yml}] [build log@footnote{https://f-droid.org/wiki/page/net.taler.cashier/lastbuild}]
+
+@item
+PoS: [metadata@footnote{https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/net.taler.merchantpos.yml}] [build log@footnote{https://f-droid.org/wiki/page/net.taler.merchantpos/lastbuild}]
+@end itemize
+
+@node Google Play,,F-Droid,Release process
+@anchor{taler-developer-manual google-play}@anchor{39}
+@subsection Google Play
+
+
+Google Play uploads are managed via Fastlane@footnote{https://docs.fastlane.tools/getting-started/android/setup/}.
+Before proceeding, ensure that this is properly set up
+and that you have access to the Google Play API.
+
+To release an app, enter into its respective folder and run fastlane:
+
+@example
+$ bundle exec fastlane
+@end example
+
+Then select the deploy option.
+Note this requires access to the Google Play upload signing key
+set via the various environment variables in $app/fastlane/Fastfile.
+
+All uploads are going to the beta track by default.
+These can be promoted to production later or immediately after upload if you feel daring.
+
+@node Code Coverage,Coding Conventions,Android Apps,Top
+@anchor{taler-developer-manual id2}@anchor{3a}@anchor{taler-developer-manual id3}@anchor{3b}
+@chapter Code Coverage
+
+
+Code coverage is done with the Gcov / Lcov
+(@indicateurl{http://ltp.sourceforge.net/coverage/lcov.php}) combo, and it is run
+nightly (once a day) by a Buildbot worker. The coverage results are
+then published at @indicateurl{https://lcov.taler.net/} .
+
+@node Coding Conventions,Testing library,Code Coverage,Top
+@anchor{taler-developer-manual coding-conventions}@anchor{3c}
+@chapter Coding Conventions
+
+
+GNU Taler is developed primarily in C, Kotlin, Python and TypeScript.
+
+@menu
+* Components written in C::
+* Shell Scripts::
+* Kotlin::
+* Python::
+
+@end menu
+
+@node Components written in C,Shell Scripts,,Coding Conventions
+@anchor{taler-developer-manual components-written-in-c}@anchor{3d}
+@section Components written in C
+
+
+These are the general coding style rules for Taler.
+
+
+@itemize *
+
+@item
+Baseline rules are to follow GNU guidelines, modified or extended
+by the GNUnet style: @indicateurl{https://docs.gnunet.org/handbook/gnunet.html#Coding-style}
+@end itemize
+
+@menu
+* Naming conventions::
+
+@end menu
+
+@node Naming conventions,,,Components written in C
+@anchor{taler-developer-manual naming-conventions}@anchor{3e}
+@subsection Naming conventions
+
+
+
+@itemize *
+
+@item
+include files (very similar to GNUnet):
+
+
+@itemize *
+
+@item
+if installed, must start with "@code{taler_}" (exception: platform.h),
+and MUST live in src/include/
+
+@item
+if NOT installed, must NOT start with "@code{taler_}" and
+MUST NOT live in src/include/ and
+SHOULD NOT be included from outside of their own directory
+
+@item
+end in "_lib" for "simple" libraries
+
+@item
+end in "_plugin" for plugins
+
+@item
+end in "_service" for libraries accessing a service, i.e. the exchange
+@end itemize
+
+@item
+binaries:
+
+
+@itemize *
+
+@item
+taler-exchange-xxx: exchange programs
+
+@item
+taler-merchant-xxx: merchant programs (demos)
+
+@item
+taler-wallet-xxx: wallet programs
+
+@item
+plugins should be libtaler_plugin_xxx_yyy.so: plugin yyy for API xxx
+
+@item
+libtalerxxx: library for API xxx
+@end itemize
+
+@item
+logging
+
+
+@itemize *
+
+@item
+tools use their full name in GNUNET_log_setup
+(i.e. 'taler-exchange-offline') and log using plain 'GNUNET_log'.
+
+@item
+pure libraries (without associated service) use 'GNUNET_log_from'
+with the component set to their library name (without lib or '.so'),
+which should also be their directory name (i.e. 'util')
+
+@item
+plugin libraries (without associated service) use 'GNUNET_log_from'
+with the component set to their type and plugin name (without lib or '.so'),
+which should also be their directory name (i.e. 'exchangedb-postgres')
+
+@item
+libraries with associated service) use 'GNUNET_log_from'
+with the name of the service, which should also be their
+directory name (i.e. 'exchange')
+
+@item
+for tools with @code{-l LOGFILE}, its absence means write logs to stderr
+@end itemize
+
+@item
+configuration
+
+
+@itemize *
+
+@item
+same rules as for GNUnet
+@end itemize
+
+@item
+exported symbols
+
+
+@itemize *
+
+@item
+must start with TALER_[SUBSYSTEMNAME]_ where SUBSYSTEMNAME
+MUST match the subdirectory of src/ in which the symbol is defined
+
+@item
+from libtalerutil start just with @code{TALER_}, without subsystemname
+
+@item
+if scope is ONE binary and symbols are not in a shared library,
+use binary-specific prefix (such as TMH = taler-exchange-httpd) for
+globals, possibly followed by the subsystem (TMH_DB_xxx).
+@end itemize
+
+@item
+structs:
+
+
+@itemize *
+
+@item
+structs that are 'packed' and do not contain pointers and are
+thus suitable for hashing or similar operations are distinguished
+by adding a "P" at the end of the name. (NEW) Note that this
+convention does not hold for the GNUnet-structs (yet).
+
+@item
+structs that are used with a purpose for signatures, additionally
+get an "S" at the end of the name.
+@end itemize
+
+@item
+private (library-internal) symbols (including structs and macros)
+
+
+@itemize *
+
+@item
+must not start with @code{TALER_} or any other prefix
+@end itemize
+
+@item
+testcases
+
+
+@itemize *
+
+@item
+must be called "test_module-under-test_case-description.c"
+@end itemize
+
+@item
+performance tests
+
+
+@itemize *
+
+@item
+must be called "perf_module-under-test_case-description.c"
+@end itemize
+@end itemize
+
+@node Shell Scripts,Kotlin,Components written in C,Coding Conventions
+@anchor{taler-developer-manual shell-scripts}@anchor{3f}
+@section Shell Scripts
+
+
+Shell scripts should be avoided if at all possible. The only permissible uses of shell scripts
+in GNU Taler are:
+
+
+@itemize *
+
+@item
+Trivial invocation of other commands.
+
+@item
+Scripts for compatibility (e.g. @code{./configure}) that must run on
+as many systems as possible.
+@end itemize
+
+When shell scripts are used, they @code{MUST} begin with the following @code{set} command:
+
+@example
+# Make the shell fail on undefined variables and
+# commands with non-zero exit status.
+$ set -eu
+@end example
+
+@node Kotlin,Python,Shell Scripts,Coding Conventions
+@anchor{taler-developer-manual kotlin}@anchor{40}
+@section Kotlin
+
+
+We so far have no specific guidelines, please follow best practices
+for the language.
+
+@node Python,,Kotlin,Coding Conventions
+@anchor{taler-developer-manual python}@anchor{41}
+@section Python
+
+
+@menu
+* Supported Python Versions::
+* Style::
+* Python for Scripting::
+
+@end menu
+
+@node Supported Python Versions,Style,,Python
+@anchor{taler-developer-manual supported-python-versions}@anchor{42}
+@subsection Supported Python Versions
+
+
+Python code should be written and build against version 3.7 of Python.
+
+@node Style,Python for Scripting,Supported Python Versions,Python
+@anchor{taler-developer-manual style}@anchor{43}
+@subsection Style
+
+
+We use yapf@footnote{https://github.com/google/yapf} to reformat the
+code to conform to our style instructions.
+A reusable yapf style file can be found in @code{build-common},
+which is intended to be used as a git submodule.
+
+@node Python for Scripting,,Style,Python
+@anchor{taler-developer-manual python-for-scripting}@anchor{44}
+@subsection Python for Scripting
+
+
+When using Python for writing small utilities, the following libraries
+are useful:
+
+
+@itemize *
+
+@item
+@code{click} for argument parsing (should be preferred over argparse)
+
+@item
+@code{pathlib} for path manipulation (part of the standard library)
+
+@item
+@code{subprocess} for "shelling out" to other programs. Prefer @code{subprocess.run}
+over the older APIs.
+@end itemize
+
+@node Testing library,User-Facing Terminology,Coding Conventions,Top
+@anchor{taler-developer-manual testing-library}@anchor{45}
+@chapter Testing library
+
+
+This chapter is a VERY ABSTRACT description of how testing is
+implemented in Taler, and in NO WAY wants to substitute the reading of
+the actual source code by the user.
+
+In Taler, a test case is a array of @code{struct TALER_TESTING_Command},
+informally referred to as @code{CMD}, that is iteratively executed by the
+testing interpreter. This latter is transparently initiated by the
+testing library.
+
+However, the developer does not have to defined CMDs manually, but
+rather call the proper constructor provided by the library. For example,
+if a CMD is supposed to test feature @code{x}, then the library would
+provide the @code{TALER_TESTING_cmd_x ()} constructor for it. Obviously,
+each constructor has its own particular arguments that make sense to
+test @code{x}, and all constructor are thoroughly commented within the
+source code.
+
+Internally, each CMD has two methods: @code{run ()} and @code{cleanup ()}. The
+former contains the main logic to test feature @code{x}, whereas the latter
+cleans the memory up after execution.
+
+In a test life, each CMD needs some internal state, made by values it
+keeps in memory. Often, the test has to @emph{share} those values with other
+CMDs: for example, CMD1 may create some key material and CMD2 needs this
+key material to encrypt data.
+
+The offering of internal values from CMD1 to CMD2 is made by @emph{traits}. A
+trait is a @code{struct TALER_TESTING_Trait}, and each CMD contains a array
+of traits, that it offers via the public trait interface to other
+commands. The definition and filling of such array happens transparently
+to the test developer.
+
+For example, the following example shows how CMD2 takes an amount object
+offered by CMD1 via the trait interface.
+
+Note: the main interpreter and the most part of CMDs and traits are
+hosted inside the exchange codebase, but nothing prevents the developer
+from implementing new CMDs and traits within other codebases.
+
+@example
+/* Without loss of generality, let's consider the
+ * following logic to exist inside the run() method of CMD1 */
+...
+
+struct TALER_Amount *a;
+/**
+ * the second argument (0) points to the first amount object offered,
+ * in case multiple are available.
+ */
+if (GNUNET_OK != TALER_TESTING_get_trait_amount_obj (cmd2, 0, &a))
+ return GNUNET_SYSERR;
+...
+
+use(a); /* 'a' points straight into the internal state of CMD2 */
+@end example
+
+In the Taler realm, there is also the possibility to alter the behaviour
+of supposedly well-behaved components. This is needed when, for example,
+we want the exchange to return some corrupted signature in order to
+check if the merchant backend detects it.
+
+This alteration is accomplished by another service called @emph{twister}. The
+twister acts as a proxy between service A and B, and can be programmed
+to tamper with the data exchanged by A and B.
+
+Please refer to the Twister codebase (under the @code{test} directory) in
+order to see how to configure it.
+
+@node User-Facing Terminology,Developer Glossary,Testing library,Top
+@anchor{taler-developer-manual user-facing-terminology}@anchor{46}
+@chapter User-Facing Terminology
+
+
+This section contains terminology that should be used and that should not be
+used in the user interface and help materials.
+
+@menu
+* Terms to Avoid::
+* Terms to Use::
+
+@end menu
+
+@node Terms to Avoid,Terms to Use,,User-Facing Terminology
+@anchor{taler-developer-manual terms-to-avoid}@anchor{47}
+@section Terms to Avoid
+
+
+
+@table @asis
+
+@item Refreshing
+
+Refreshing is the internal technical terminology for the protocol to
+give change for partially spent coins
+
+@strong{Use instead}: "Obtaining change"
+
+@item Coin
+
+Coins are an internal construct, the user should never be aware that their balance
+is represented by coins if different denominations.
+
+@strong{Use instead}: "(Digital) Cash" or "(Wallet) Balance"
+
+@item Consumer
+
+Has bad connotation of consumption.
+
+@strong{Use instead}: Customer or user.
+
+@item Proposal
+
+The term used to describe the process of the merchant facilitating the download
+of the signed contract terms for an order.
+
+@strong{Avoid}. Generally events that relate to proposal downloads
+should not be shown to normal users, only developers. Instead, use
+"communication with mechant failed" if a proposed order can't be downloaded.
+
+@item Anonymous E-Cash
+
+Should be generally avoided, since Taler is only anonymous for
+the customer. Also some people are scared of anonymity (which as
+a term is also way too absolute, as anonymity is hardly ever perfect).
+
+@strong{Use instead}: "Privacy-preserving", "Privacy-friendly"
+
+@item Payment Replay
+
+The process of proving to the merchant that the customer is entitled
+to view a digital product again, as they already paid for it.
+
+@strong{Use instead}: In the event history, "re-activated digital content purchase"
+could be used. (FIXME: this is still not nice.)
+
+@item Session ID
+
+See Payment Replay.
+
+@item Order
+
+Too ambiguous in the wallet.
+
+@strong{Use instead}: Purchase
+
+@item Fulfillment URL
+
+URL that the serves the digital content that the user purchased
+with their payment. Can also be something like a donation receipt.
+@end table
+
+@node Terms to Use,,Terms to Avoid,User-Facing Terminology
+@anchor{taler-developer-manual terms-to-use}@anchor{48}
+@section Terms to Use
+
+
+
+@table @asis
+
+@item Auditor
+
+Regulatory entity that certifies exchanges and oversees their operation.
+
+@item Exchange Operator
+
+The entity/service that gives out digital cash in exchange for some
+other means of payment.
+
+In some contexts, using "Issuer" could also be appropriate.
+When showing a balance breakdown,
+we can say "100 Eur (issued by exchange.euro.taler.net)".
+Sometimes we may also use the more generic term "Payment Service Provider"
+when the concept of an "Exchange" is still unclear to the reader.
+
+@item Refund
+
+A refund is given by a merchant to the customer (rather the customer's wallet)
+and "undoes" a previous payment operation.
+
+@item Payment
+
+The act of sending digital cash to a merchant to pay for an order.
+
+@item Purchase
+
+Used to refer to the "result" of a payment, as in "view purchase".
+Use sparsingly, as the word doesn't fit for all payments, such as donations.
+
+@item Contract Terms
+
+Partially machine-readable representation of the merchant's obligation after the
+customer makes a payment.
+
+@item Merchant
+
+Party that receives a payment.
+
+@item Wallet
+
+Also "Taler Wallet". Software component that manages the user's digital cash
+and payments.
+@end table
+
+@node Developer Glossary,Developer Tools,User-Facing Terminology,Top
+@anchor{taler-developer-manual developer-glossary}@anchor{49}
+@chapter Developer Glossary
+
+
+This glossary is meant for developers. It contains some terms that we usually do not
+use when talking to end users or even system administrators.
+
+
+@table @asis
+@anchor{taler-developer-manual term-absolute-time}@anchor{4a}
+@geindex absolute time
+
+@item absolute time
+
+method of keeping time in @ref{4b,,GNUnet} where the time is represented
+as the number of microseconds since 1.1.1970 (UNIX epoch). Called
+absolute time in contrast to @ref{4c,,relative time}.
+@anchor{taler-developer-manual term-aggregate}@anchor{4d}
+@geindex aggregate
+
+@item aggregate
+
+the @ref{4e,,exchange} combines multiple payments received by the
+same @ref{4f,,merchant} into one larger @ref{50,,wire transfer} to
+the respective merchant's @ref{51,,bank} account
+@anchor{taler-developer-manual term-auditor}@anchor{52}
+@geindex auditor
+
+@item auditor
+
+trusted third party that verifies that the @ref{4e,,exchange} is operating correctly
+@anchor{taler-developer-manual term-bank}@anchor{51}
+@geindex bank
+
+@item bank
+
+traditional financial service provider who offers wire @ref{53,,transfers} between accounts
+@anchor{taler-developer-manual term-buyer}@anchor{54}
+@geindex buyer
+
+@item buyer
+
+individual in control of a Taler @ref{55,,wallet}, usually using it to
+@ref{56,,spend} the @ref{57,,coins} on @ref{58,,contracts} (see also @ref{59,,customer}).
+@anchor{taler-developer-manual term-close}@anchor{5a}
+@geindex close
+
+@item close@anchor{taler-developer-manual term-closes}@anchor{5b}
+@geindex closes
+
+@itemx closes@anchor{taler-developer-manual term-closed}@anchor{5c}
+@geindex closed
+
+@itemx closed@anchor{taler-developer-manual term-closing}@anchor{5d}
+@geindex closing
+
+@itemx closing
+
+operation an @ref{4e,,exchange} performs on a @ref{5e,,reserve} that has not been
+@ref{5f,,drained} by @ref{60,,withdraw} operations. When closing a reserve, the
+exchange wires the remaining funds back to the customer, minus a @ref{61,,fee}
+for closing
+@anchor{taler-developer-manual term-coin}@anchor{62}
+@geindex coin
+
+@item coin@anchor{taler-developer-manual term-coins}@anchor{57}
+@geindex coins
+
+@itemx coins
+
+coins are individual token representing a certain amount of value, also known as the @ref{63,,denomination} of the coin
+@anchor{taler-developer-manual term-commitment}@anchor{64}
+@geindex commitment
+
+@item commitment@anchor{taler-developer-manual term-refresh-commitment}@anchor{65}
+@geindex refresh commitment
+
+@itemx refresh commitment
+
+data that the wallet commits to during the @ref{66,,melt} stage of the
+@ref{67,,refresh} protocol where it
+has to prove to the @ref{4e,,exchange} that it is deriving the @ref{68,,fresh}
+coins as specified by the Taler protocol. The commitment is verified
+probabilistically (see: @ref{69,,kappa}) during the @ref{6a,,reveal} stage.
+@anchor{taler-developer-manual term-contract}@anchor{6b}
+@geindex contract
+
+@item contract@anchor{taler-developer-manual term-contracts}@anchor{58}
+@geindex contracts
+
+@itemx contracts
+
+formal agreement between @ref{4f,,merchant} and @ref{59,,customer} specifying the
+@ref{6c,,contract terms} and signed by the merchant and the @ref{57,,coins} of the
+customer
+@anchor{taler-developer-manual term-contract-terms}@anchor{6c}
+@geindex contract terms
+
+@item contract terms
+
+the individual clauses specifying what the buyer is purchasing from the
+@ref{4f,,merchant}
+@anchor{taler-developer-manual term-customer}@anchor{59}
+@geindex customer
+
+@item customer
+
+individual that directs the buyer (perhaps the same individual) to make a purchase
+@anchor{taler-developer-manual term-denomination}@anchor{63}
+@geindex denomination
+
+@item denomination
+
+unit of currency, specifies both the currency and the face value of a @ref{62,,coin},
+as well as associated fees and validity periods
+@anchor{taler-developer-manual term-denomination-key}@anchor{6d}
+@geindex denomination key
+
+@item denomination key
+
+(RSA) key used by the exchange to certify that a given @ref{62,,coin} is valid and of a
+particular @ref{63,,denomination}
+@anchor{taler-developer-manual term-deposit}@anchor{6e}
+@geindex deposit
+
+@item deposit@anchor{taler-developer-manual term-deposits}@anchor{6f}
+@geindex deposits
+
+@itemx deposits@anchor{taler-developer-manual term-depositing}@anchor{70}
+@geindex depositing
+
+@itemx depositing
+
+operation by which a merchant passes coins to an exchange, expecting the
+exchange to credit his bank account in the future using an
+@ref{4d,,aggregate} @ref{50,,wire transfer}
+@anchor{taler-developer-manual term-dirty}@anchor{71}
+@geindex dirty
+
+@item dirty@anchor{taler-developer-manual term-dirty-coin}@anchor{72}
+@geindex dirty coin
+
+@itemx dirty coin
+
+a coin is dirty if its public key may be known to an entity other than
+the customer, thereby creating the danger of some entity being able to
+link multiple transactions of coin's owner if the coin is not refreshed
+@anchor{taler-developer-manual term-drain}@anchor{73}
+@geindex drain
+
+@item drain@anchor{taler-developer-manual term-drained}@anchor{5f}
+@geindex drained
+
+@itemx drained
+
+a @ref{5e,,reserve} is being drained when a @ref{55,,wallet} is using the
+reserve's private key to @ref{60,,withdraw} coins from it. This reduces
+the balance of the reserve. Once the balance reaches zero, we say that
+the reserve has been (fully) drained. Reserves that are not drained
+(which is the normal process) are @ref{5c,,closed} by the exchange.
+@anchor{taler-developer-manual term-exchange}@anchor{4e}
+@geindex exchange
+
+@item exchange
+
+Taler's payment service operator. Issues electronic coins during
+withdrawal and redeems them when they are deposited by merchants
+@anchor{taler-developer-manual term-expired}@anchor{74}
+@geindex expired
+
+@item expired@anchor{taler-developer-manual term-expiration}@anchor{75}
+@geindex expiration
+
+@itemx expiration
+
+Various operations come with time limits. In particular, denomination keys
+come with strict time limits for the various operations involving the
+coin issued under the denomination. The most important limit is the
+deposit expiration, which specifies until when wallets are allowed to
+use the coin in deposit or refreshing operations. There is also a "legal"
+expiration, which specifies how long the exchange keeps records beyond the
+deposit expiration time. This latter expiration matters for legal disputes
+in courts and also creates an upper limit for refreshing operations on
+special zombie coin
+@anchor{taler-developer-manual term-fakebank}@anchor{76}
+@geindex fakebank
+
+@item fakebank
+
+implementation of the @ref{51,,bank} API in memory to be used only for test
+cases.
+@anchor{taler-developer-manual term-fee}@anchor{61}
+@geindex fee
+
+@item fee
+
+an @ref{4e,,exchange} charges various fees for its service. The different
+fees are specified in the protocol. There are fees per coin for
+@ref{77,,withdrawing}, @ref{70,,depositing}, @ref{78,,melting}, and
+@ref{79,,refunding}. Furthermore, there are fees per wire transfer
+for @ref{5d,,closing} a @ref{5e,,reserve}: and for
+@ref{4d,,aggregate} @ref{7a,,wire transfers} to the @ref{4f,,merchant}.
+@anchor{taler-developer-manual term-fresh}@anchor{68}
+@geindex fresh
+
+@item fresh@anchor{taler-developer-manual term-fresh-coin}@anchor{7b}
+@geindex fresh coin
+
+@itemx fresh coin
+
+a coin is fresh if its public key is only known to the customer
+@anchor{taler-developer-manual term-GNUnet}@anchor{4b}
+@geindex GNUnet
+
+@item GNUnet
+
+Codebase of various libraries for a better Internet, some of which
+GNU Taler depends upon.
+@anchor{taler-developer-manual term-json}@anchor{7c}
+@geindex json
+
+@item json@anchor{taler-developer-manual term-JSON}@anchor{7d}
+@geindex JSON
+
+@itemx JSON@anchor{taler-developer-manual term-JavaScript-Object-Notation}@anchor{7e}
+@geindex JavaScript Object Notation
+
+@itemx JavaScript Object Notation
+
+serialization format derived from the JavaScript language which is
+commonly used in the Taler protocol as the payload of HTTP requests
+and responses.
+@anchor{taler-developer-manual term-kappa}@anchor{69}
+@geindex kappa
+
+@item kappa
+
+security parameter used in the @ref{67,,refresh} protocol. Defined to be 3.
+The probability of successfully evading the income transparency with the
+refresh protocol is 1:kappa.
+@anchor{taler-developer-manual term-LibEuFin}@anchor{7f}
+@geindex LibEuFin
+
+@item LibEuFin
+
+FIXME: explain
+@anchor{taler-developer-manual term-link}@anchor{80}
+@geindex link
+
+@item link@anchor{taler-developer-manual term-linking}@anchor{81}
+@geindex linking
+
+@itemx linking
+
+specific step in the @ref{67,,refresh} protocol that an exchange must offer
+to prevent abuse of the @ref{67,,refresh} mechanism. The link step is
+not needed in normal operation, it just must be offered.
+@anchor{taler-developer-manual term-master-key}@anchor{82}
+@geindex master key
+
+@item master key
+
+offline key used by the exchange to certify denomination keys and
+message signing keys
+@anchor{taler-developer-manual term-melt}@anchor{66}
+@geindex melt
+
+@item melt@anchor{taler-developer-manual term-melted}@anchor{83}
+@geindex melted
+
+@itemx melted@anchor{taler-developer-manual term-melting}@anchor{78}
+@geindex melting
+
+@itemx melting
+
+step of the @ref{67,,refresh} protocol where a @ref{72,,dirty coin}
+is invalidated to be reborn @ref{68,,fresh} in a subsequent
+@ref{6a,,reveal} step.
+@anchor{taler-developer-manual term-merchant}@anchor{4f}
+@geindex merchant
+
+@item merchant
+
+party receiving payments (usually in return for goods or services)
+@anchor{taler-developer-manual term-message-signing-key}@anchor{84}
+@geindex message signing key
+
+@item message signing key
+
+key used by the exchange to sign online messages, other than coins
+@anchor{taler-developer-manual term-order}@anchor{85}
+@geindex order
+
+@item order
+
+FIXME: to be written!
+@anchor{taler-developer-manual term-owner}@anchor{86}
+@geindex owner
+
+@item owner
+
+a coin is owned by the entity that knows the private key of the coin
+@anchor{taler-developer-manual term-planchet}@anchor{87}
+@geindex planchet
+
+@item planchet
+
+precursor data for a @ref{62,,coin}. A planchet includes the coin's internal
+secrets (coin private key, blinding factor), but lacks the RSA signature
+of the @ref{4e,,exchange}. When @ref{77,,withdrawing}, a @ref{55,,wallet}
+creates and persists a planchet before asking the exchange to sign it to
+get the coin.
+@anchor{taler-developer-manual term-privacy-policy}@anchor{88}
+@geindex privacy policy
+
+@item privacy policy
+
+Statement of an operator how they will protect the privacy of users.
+@anchor{taler-developer-manual term-proof}@anchor{89}
+@geindex proof
+
+@item proof
+
+Message that cryptographically demonstrates that a particular claim is correct.
+@anchor{taler-developer-manual term-proposal}@anchor{8a}
+@geindex proposal
+
+@item proposal
+
+a list of @ref{6c,,contract terms} that has been completed and signed by the
+merchant backend.
+@anchor{taler-developer-manual term-purchase}@anchor{8b}
+@geindex purchase
+
+@item purchase
+
+Refers to the overall process of negotiating a @ref{6b,,contract} and then
+making a payment with @ref{57,,coins} to a @ref{4f,,merchant}.
+@anchor{taler-developer-manual term-recoup}@anchor{8c}
+@geindex recoup
+
+@item recoup
+
+Operation by which an exchange returns the value of coins affected
+by a @ref{8d,,revocation} to their @ref{86,,owner}, either by allowing the owner to
+withdraw new coins or wiring funds back to the bank account of the @ref{86,,owner}.
+@anchor{taler-developer-manual term-refresh}@anchor{67}
+@geindex refresh
+
+@item refresh@anchor{taler-developer-manual term-refreshing}@anchor{8e}
+@geindex refreshing
+
+@itemx refreshing
+
+operation by which a @ref{72,,dirty coin} is converted into one or more
+@ref{68,,fresh} coins. Involves @ref{78,,melting} the @ref{72,,dirty coin} and
+then @ref{8f,,revealing} so-called @ref{90,,transfer keys}.
+@anchor{taler-developer-manual term-refund}@anchor{91}
+@geindex refund
+
+@item refund@anchor{taler-developer-manual term-refunding}@anchor{79}
+@geindex refunding
+
+@itemx refunding
+
+operation by which a merchant steps back from the right to funds that he
+obtained from a @ref{6e,,deposit} operation, giving the right to the funds back
+to the customer
+@anchor{taler-developer-manual term-refund-transaction-id}@anchor{92}
+@geindex refund transaction id
+
+@item refund transaction id
+
+unique number by which a merchant identifies a @ref{91,,refund}. Needed
+as refunds can be partial and thus there could be multiple refunds for
+the same @ref{8b,,purchase}.
+@anchor{taler-developer-manual term-relative-time}@anchor{4c}
+@geindex relative time
+
+@item relative time
+
+method of keeping time in @ref{4b,,GNUnet} where the time is represented
+as a relative number of microseconds. Thus, a relative time specifies
+an offset or a duration, but not a date. Called relative time in
+contrast to @ref{4a,,absolute time}.
+@anchor{taler-developer-manual term-reserve}@anchor{5e}
+@geindex reserve
+
+@item reserve
+
+accounting mechanism used by the exchange to track customer funds
+from incoming @ref{7a,,wire transfers}. A reserve is created whenever
+a customer wires money to the exchange using a well-formed public key
+in the subject. The exchange then allows the customer's @ref{55,,wallet}
+to @ref{60,,withdraw} up to the amount received in @ref{68,,fresh}
+@ref{57,,coins} from the reserve, thereby draining the reserve. If a
+reserve is not drained, the exchange eventually @ref{5b,,closes} it.
+
+Other definition: Funds set aside for future use; either the balance of a customer at the
+exchange ready for withdrawal, or the funds kept in the exchange;s bank
+account to cover obligations from coins in circulation.
+@anchor{taler-developer-manual term-reveal}@anchor{6a}
+@geindex reveal
+
+@item reveal@anchor{taler-developer-manual term-revealing}@anchor{8f}
+@geindex revealing
+
+@itemx revealing
+
+step in the @ref{67,,refresh} protocol where some of the transfer private
+keys are revealed to prove honest behavior on the part of the wallet.
+In the reveal step, the exchange returns the signed @ref{68,,fresh} coins.
+@anchor{taler-developer-manual term-revoke}@anchor{93}
+@geindex revoke
+
+@item revoke@anchor{taler-developer-manual term-revocation}@anchor{8d}
+@geindex revocation
+
+@itemx revocation
+
+exceptional operation by which an exchange withdraws a denomination from
+circulation, either because the signing key was compromised or because
+the exchange is going out of operation; unspent coins of a revoked
+denomination are subjected to recoup.
+@anchor{taler-developer-manual term-sharing}@anchor{94}
+@geindex sharing
+
+@item sharing
+
+users can share ownership of a @ref{62,,coin} by sharing access to the coin&#39;s
+private key, thereby allowing all co-owners to spend the coin at any
+time.
+@anchor{taler-developer-manual term-spend}@anchor{56}
+@geindex spend
+
+@item spend@anchor{taler-developer-manual term-spending}@anchor{95}
+@geindex spending
+
+@itemx spending
+
+operation by which a customer gives a merchant the right to deposit
+coins in return for merchandise
+@anchor{taler-developer-manual term-terms}@anchor{96}
+@geindex terms
+
+@item terms
+
+the general terms of service of an operator, possibly including
+the @ref{88,,privacy policy}. Not to be confused with the
+@ref{6c,,contract terms} which are about the specific purchase.
+@anchor{taler-developer-manual term-transaction}@anchor{97}
+@geindex transaction
+
+@item transaction
+
+method by which ownership is exclusively transferred from one entity
+@anchor{taler-developer-manual term-transfer}@anchor{53}
+@geindex transfer
+
+@item transfer@anchor{taler-developer-manual term-transfers}@anchor{98}
+@geindex transfers
+
+@itemx transfers@anchor{taler-developer-manual term-wire-transfer}@anchor{50}
+@geindex wire transfer
+
+@itemx wire transfer@anchor{taler-developer-manual term-wire-transfers}@anchor{7a}
+@geindex wire transfers
+
+@itemx wire transfers
+
+method of sending funds between @ref{51,,bank} accounts
+@anchor{taler-developer-manual term-transfer-key}@anchor{99}
+@geindex transfer key
+
+@item transfer key@anchor{taler-developer-manual term-transfer-keys}@anchor{90}
+@geindex transfer keys
+
+@itemx transfer keys
+
+special cryptographic key used in the @ref{67,,refresh} protocol, some of which
+are revealed during the @ref{6a,,reveal} step. Note that transfer keys have,
+despite the name, no relationship to @ref{7a,,wire transfers}. They merely
+help to transfer the value from a @ref{72,,dirty coin} to a @ref{7b,,fresh coin}
+@anchor{taler-developer-manual term-user}@anchor{9a}
+@geindex user
+
+@item user
+
+any individual using the Taler payment system
+(see @ref{59,,customer}, @ref{54,,buyer}, @ref{4f,,merchant}).
+@anchor{taler-developer-manual term-version}@anchor{9b}
+@geindex version
+
+@item version
+
+Taler uses various forms of versioning. There is a database
+schema version (stored itself in the database, see *-0000.sql) describing
+the state of the table structure in the database of an @ref{4e,,exchange},
+@ref{52,,auditor} or @ref{4f,,merchant}. There is a protocol
+version (CURRENT:REVISION:AGE, see GNU libtool) which specifies
+the network protocol spoken by an @ref{4e,,exchange} or @ref{4f,,merchant}
+including backwards-compatibility. And finally there is the software
+release version (MAJOR.MINOR.PATCH, see @indicateurl{https://semver.org/}) of
+the respective code base.
+@anchor{taler-developer-manual term-wallet}@anchor{55}
+@geindex wallet
+
+@item wallet
+
+software running on a customer's computer; withdraws, stores and
+spends coins
+@anchor{taler-developer-manual term-WebExtension}@anchor{9c}
+@geindex WebExtension
+
+@item WebExtension
+
+Cross-browser API used to implement the GNU Taler wallet browser extension.
+@anchor{taler-developer-manual term-wire-gateway}@anchor{9d}
+@geindex wire gateway
+
+@item wire gateway
+
+FIXME: explain
+@anchor{taler-developer-manual term-wire-transfer-identifier}@anchor{9e}
+@geindex wire transfer identifier
+
+@item wire transfer identifier@anchor{taler-developer-manual term-wtid}@anchor{9f}
+@geindex wtid
+
+@itemx wtid
+
+Subject of a wire transfer from the exchange to a merchant;
+set by the aggregator to a random nonce which uniquely
+identifies the transfer.
+@anchor{taler-developer-manual term-withdraw}@anchor{60}
+@geindex withdraw
+
+@item withdraw@anchor{taler-developer-manual term-withdrawing}@anchor{77}
+@geindex withdrawing
+
+@itemx withdrawing@anchor{taler-developer-manual term-withdrawal}@anchor{a0}
+@geindex withdrawal
+
+@itemx withdrawal
+
+operation by which a @ref{55,,wallet} can convert funds from a @ref{5e,,reserve} to
+fresh coins
+@anchor{taler-developer-manual term-zombie}@anchor{a1}
+@geindex zombie
+
+@item zombie@anchor{taler-developer-manual term-zombie-coin}@anchor{a2}
+@geindex zombie coin
+
+@itemx zombie coin
+
+coin where the respective @ref{6d,,denomination key} is past its
+@ref{6e,,deposit} @ref{75,,expiration} time, but which is still (again) valid
+for an operation because it was @ref{83,,melted} while it was still
+valid, and then later again credited during a @ref{8c,,recoup} process
+@end table
+
+@node Developer Tools,Index,Developer Glossary,Top
+@anchor{taler-developer-manual developer-tools}@anchor{a3}
+@chapter Developer Tools
+
+
+This section describes various internal programs to make life easier for the
+developer.
+
+@menu
+* taler-config-generate::
+
+@end menu
+
+@node taler-config-generate,,,Developer Tools
+@anchor{taler-developer-manual taler-config-generate}@anchor{a4}
+@section taler-config-generate
+
+
+@strong{taler-config-generate} - tool to simplify Taler configuration generation
+
+@strong{taler-config-generate}
+[@strong{-C} @emph{CURRENCY} | @strong{––currency=}‌@emph{CURRENCY}]
+[@strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}]
+[@strong{-e} | @strong{––exchange}]
+[@strong{-f} @emph{AMOUNT} | @emph{––wirefee=}‌@emph{AMOUNT}]
+[@strong{-h} | @strong{––help}]
+[@strong{-J} @emph{JSON} | @strong{––wire-json-exchange=}‌@emph{JSON}]
+[@strong{-j} @emph{JSON} | @strong{––wire-json-merchant=}‌@emph{JSON}]
+[@strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}]
+[@strong{-m} | @strong{––merchant}]
+[@strong{-t} | @strong{––trusted}]
+[@strong{-v} | @strong{––version}]
+[@strong{-w} @emph{WIREFORMAT} | @strong{––wire} @emph{WIREFORMAT}]
+[@strong{––bank-uri}]
+[@strong{––exchange-bank-account}]
+[@strong{––merchant-bank-account}]
+
+@strong{taler-config-generate} can be used to generate configuration files
+for the Taler exchange or Taler merchants.
+
+
+@table @asis
+
+@item @strong{-C} @emph{CURRENCY} | @strong{––currency=}‌@emph{CURRENCY}
+
+Which currency should we use in the configuration.
+
+@item @strong{-c} @emph{FILENAME} | @strong{––config=}‌@emph{FILENAME}
+
+Location where to write the generated configuration. Existing file
+will be updated, not overwritten.
+
+@item @strong{-e} | @strong{––exchange}
+
+Generate configuration for a Taler exchange.
+
+@item @strong{-f} @emph{AMOUNT} | @emph{-wirefee=}‌@emph{AMOUNT}
+
+Setup wire transfer fees for the next 5 years for the exchange (for
+all wire methods).
+
+@item @strong{-h} | @strong{––help}
+
+Shows this man page.
+
+@item @strong{-J} @emph{JSON} | @strong{––wire-json-exchange=}‌@emph{JSON}
+
+Wire configuration to use for the exchange.
+
+@item @strong{-j} @emph{JSON} | @strong{––wire-json-merchant=}‌@emph{JSON}
+
+Wire configuration to use for the merchant.
+
+@item @strong{-L} @emph{LOGLEVEL} | @strong{––loglevel=}‌@emph{LOGLEVEL}
+
+Use LOGLEVEL for logging. Valid values are DEBUG, INFO, WARNING and
+ERROR.
+
+@item @strong{-m} | @strong{––merchant}
+
+Generate configuration for a Taler merchant.
+
+@item @strong{-t} | @strong{––trusted}
+
+Setup current exchange as trusted with current merchant. Generally
+only useful when configuring for testcases.
+
+@item @strong{-v} | @strong{––version}
+
+Print version information.
+
+@item @strong{-w} @emph{WIREFORMAT} | @strong{––wire} @emph{WIREFORMAT}
+
+Specifies which wire format to use (i.e. “test” or “sepa”)
+
+@item @strong{––bank-uri}
+
+Alternative to specify wire configuration to use for the exchange and
+merchant for the “test” wire method. Only useful if WIREFORMAT was
+set to “test”. Specifies the URI of the bank.
+
+@item @strong{––exchange-bank-account}
+
+Alternative to specify wire configuration to use for the exchange for
+the “test” wire method. Only useful if WIREFORMAT was set to “test”.
+Specifies the bank account number of the exchange.
+
+@item @strong{––merchant-bank-account}
+
+Alternative to specify wire configuration to use for the merchant for
+the “test” wire method. Only useful if WIREFORMAT was set to “test”.
+Specifies the bank account number of the merchant.
+@end table
+
+@node Index,,Developer Tools,Top
+@unnumbered Index
+
+
+@printindex ge
+
+
+@c %**end of body
+@bye