summaryrefslogtreecommitdiff
path: root/design-documents
diff options
context:
space:
mode:
authorChristian Blättler <blatc2@bfh.ch>2024-03-05 21:37:22 +0100
committerChristian Blättler <blatc2@bfh.ch>2024-03-05 21:37:22 +0100
commitc04429f8b534890ee7a0823c7e56a45655cd6bd3 (patch)
treea7ecae8e6bf4aa0b77cfca0c66d1020d3b2eeb17 /design-documents
parent5f82d484feaa6b41371226cb3239a68a14caa8a3 (diff)
parent6f4f2ca7ef5cea652417ba56bc0eb61ec9c792f5 (diff)
downloaddocs-c04429f8b534890ee7a0823c7e56a45655cd6bd3.tar.gz
docs-c04429f8b534890ee7a0823c7e56a45655cd6bd3.tar.bz2
docs-c04429f8b534890ee7a0823c7e56a45655cd6bd3.zip
Merge branch 'master' into feature/tokens
Diffstat (limited to 'design-documents')
-rw-r--r--design-documents/014-merchant-backoffice-ui.rst8
-rw-r--r--design-documents/020-backoffice-rewards-management.rst2
-rw-r--r--design-documents/023-taler-kyc.rst2
-rw-r--r--design-documents/024-age-restriction.rst4
-rw-r--r--design-documents/028-deposit-policies.rst23
-rw-r--r--design-documents/031-invoicing.rst15
-rw-r--r--design-documents/035-regional-currencies.rst15
-rw-r--r--design-documents/036-currency-conversion-service.rst103
-rw-r--r--design-documents/037-wallet-transactions-lifecycle.rst58
-rw-r--r--design-documents/039-taler-browser-integration.rst109
-rw-r--r--design-documents/041-wallet-balance-amount-definitions.rst14
-rw-r--r--design-documents/044-ci-system.rst81
-rw-r--r--design-documents/046-mumimo-contracts.rst15
-rw-r--r--design-documents/048-wallet-exchange-lifecycle.rst28
-rw-r--r--design-documents/050-libeufin-nexus.rst79
-rw-r--r--design-documents/051-fractional-digits.rst94
-rw-r--r--design-documents/052-libeufin-bank-2fa.rst136
-rw-r--r--design-documents/053-wallet-ui.rst355
-rw-r--r--design-documents/054-dynamic-form.rst201
-rw-r--r--design-documents/055-wallet-problem-report.rst85
-rw-r--r--design-documents/index.rst4
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw-confirm.pngbin0 -> 193455 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw.pngbin0 -> 237544 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet133-withdraw-confirm-bank.pngbin0 -> 231969 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-view22-balances.pngbin0 -> 234937 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirm.pngbin0 -> 357675 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirmed.pngbin0 -> 357108 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-register.pngbin0 -> 338618 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-send-money.pngbin0 -> 464966 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-withdraw.pngbin0 -> 505046 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw-confirm.pngbin0 -> 202047 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw.pngbin0 -> 246405 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet131-tos.pngbin0 -> 317496 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet133-withdraw-confirm-bank.pngbin0 -> 230382 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view10-empty-wallet.pngbin0 -> 169741 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view22-balances.pngbin0 -> 239045 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-amount.pngbin0 -> 173529 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-1.pngbin0 -> 292949 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-2.pngbin0 -> 407510 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-3.pngbin0 -> 331196 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount.pngbin0 -> 215793 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount2.pngbin0 -> 214738 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-tos.pngbin0 -> 116707 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF.pngbin0 -> 304402 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF2.pngbin0 -> 420238 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ.pngbin0 -> 309949 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ2.pngbin0 -> 413992 bytes
-rw-r--r--design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-withdraw-tos.pngbin0 -> 170387 bytes
48 files changed, 1122 insertions, 309 deletions
diff --git a/design-documents/014-merchant-backoffice-ui.rst b/design-documents/014-merchant-backoffice-ui.rst
index eaf435a4..1f744a15 100644
--- a/design-documents/014-merchant-backoffice-ui.rst
+++ b/design-documents/014-merchant-backoffice-ui.rst
@@ -139,11 +139,3 @@ Story #4: Manage inventory
- change product description / price / etc.
- delete products from inventory
-
-
-Story #5: Manage rewards
-------------------------
-
-- set up reward reserve
-
-- check reward reserve status
diff --git a/design-documents/020-backoffice-rewards-management.rst b/design-documents/020-backoffice-rewards-management.rst
index 1eef39b1..8345a3b9 100644
--- a/design-documents/020-backoffice-rewards-management.rst
+++ b/design-documents/020-backoffice-rewards-management.rst
@@ -1,4 +1,4 @@
-DD 20: Backoffice Rewards Management
+XX 20: Backoffice Rewards Management
####################################
Summary
diff --git a/design-documents/023-taler-kyc.rst b/design-documents/023-taler-kyc.rst
index 4d8f2cbc..d34241d7 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -40,7 +40,7 @@ Taler needs to run KYC checks in the following circumstances:
* key: IBAN (encoded as payto:// URI)
-* Reserve is "opened" for invoicing or rewards.
+* Reserve is "opened" for invoicing.
* key: reserve (=KYC account) long term public key per wallet (encoded as payto:// URI)
diff --git a/design-documents/024-age-restriction.rst b/design-documents/024-age-restriction.rst
index 280a4f39..ee478ee1 100644
--- a/design-documents/024-age-restriction.rst
+++ b/design-documents/024-age-restriction.rst
@@ -600,9 +600,9 @@ The object ``ContractTerms`` is extended by an optional field
``minimum_age`` that can be any integer greater than 0. In reality
this value will not be smaller than, say, 8, and not larger than, say, 21.
-.. ts:def:: ContractTerms
+.. ts:def:: DD24ContractTerms
- interface ContractTerms {
+ interface DD24ContractTerms {
...
// If the order requires a minimum age greater than 0, this field is set
diff --git a/design-documents/028-deposit-policies.rst b/design-documents/028-deposit-policies.rst
index 956945ee..1bdf4801 100644
--- a/design-documents/028-deposit-policies.rst
+++ b/design-documents/028-deposit-policies.rst
@@ -41,7 +41,19 @@ The policies shall be implemented as *extensions* to the exchange (see
Motivation
**********
-TODO
+GNU Taler's initial set of API's (withdraw, deposit, refresh) support most
+payment situations in which customers pay for goods and services within an
+otherwise unconditioned transaction. (A notable exception from this the
+ability to provide refunds, which will be re-factored into a policy extension).
+
+However, in many payments depend on additional conditions to be met. GNU Taler
+already supports payments with age restriction applied, but there are other
+scenarious that we want to support.
+
+Our aim is to provide an API for extensions of GNU Taler that implement
+particular policies and policy-handling for payments (also called *conditioned
+payments*).
+
Background and Requirements
***************************
@@ -56,9 +68,16 @@ TODO, explain:
- C-structs for policy extensions (esp. the handlers)
- Naming conventions for policy extensions
- Deadlines and -handling
-- API-endpoints (``/extensions/policy_...``)
- Typical choreography of a deposit with policy and its fulfillment
+
+API-Endpoints of the Exchange
+=============================
+
+TODO
+
+
+
Database-schema
===============
diff --git a/design-documents/031-invoicing.rst b/design-documents/031-invoicing.rst
index cfe776ed..0fcc88fd 100644
--- a/design-documents/031-invoicing.rst
+++ b/design-documents/031-invoicing.rst
@@ -4,9 +4,7 @@ DD 31: Invoicing
Summary
=======
-This document proposes new endpoints to support invoicing,
-that incidentally also address the long-standing rewards
-reserve expiration problem.
+This document proposes new endpoints to support invoicing.
Motivation
@@ -36,10 +34,7 @@ Requirements
* Reasonable UX and overall design impact.
* Wallets may want to pay for the reserve with coins
- (reserve fresh, not created via bank transfer), while
- rewarding merchants likely want to pay from the reserve
- balance itself. So both styles of payment should be
- supported.
+ (reserve fresh, not created via bank transfer).
Unclear in the current proposal are:
@@ -62,12 +57,10 @@ charge the ``account_fee``, bump the number of open purses threshold in the
``reserves`` table and stop auto-closing of the reserve. This will ensure that
the users can withdraw the reserve balance into their wallet even after a
longer time period. This helps if the invoice is paid after a significant
-delay, and also addresses the unwanted reward reserve closure
-problem. Introduce a way to force an immediate closure of a reserve, allowing
+delay. Introduce a way to force an immediate closure of a reserve, allowing
P2P reserve from invoices to be send to a bank account (this allows a wallet
to be used for convenient invoicing and not strictly require the wallet to
-receive the funds) and also allowing the user to recover funds from a reward
-reserve after rewards are no longer issued.
+receive the funds).
The solution needs three new tables for:
diff --git a/design-documents/035-regional-currencies.rst b/design-documents/035-regional-currencies.rst
index 0b4553e6..3d62dcc3 100644
--- a/design-documents/035-regional-currencies.rst
+++ b/design-documents/035-regional-currencies.rst
@@ -30,6 +30,11 @@ Requirements
* Regional currencies should be easy to use as well
* It must be easy to integrate regional/official currencies with the existing
Taler auditor/exchange structure
+* Wallet users should be able to see disagregated balance between global currencies
+ and regional currencies supported by different exchanges even if the currency
+ name is equal.
+* Merchants should be able to accept regional and global currencies based on the
+ supported exchange list.
Proposed Solution
=================
@@ -144,6 +149,16 @@ The last part should probably be hidden by default. There might be nicer ways t
this, such as some hoverable (?) icon after the amount that shows details about what currencies the merchant
accepts.
+Wallet-core API for scope management
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* ``listGlobalCurrencyExchanges`` lists all ``(currency, exchangeUrl, exchangePub)`` triples
+ where funds are considered to be in global scope (i.e. non-regional).
+* ``listGlobalCurrencyAuditors`` lists all ``(currency, auditorUrl, auditorPub)`` triples
+ where funds are considered to be in global scope (i.e. non-regional).
+* ``addGlobalCurrencyExchange`` and ``removeGlobalCurrencyExchange`` adds/removes a ``(currency, exchangeUrl, exchangePub)``
+* ``addGlobalCurrencyAuditor`` and ``removeGlobalCurrencyAuditor`` adds/removes a ``(currency, auditorUrl, auditorPub)``
+
Implementation Breakdown
^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/design-documents/036-currency-conversion-service.rst b/design-documents/036-currency-conversion-service.rst
index 72a504c5..92d88499 100644
--- a/design-documents/036-currency-conversion-service.rst
+++ b/design-documents/036-currency-conversion-service.rst
@@ -35,74 +35,63 @@ currency.
Requirements
============
-* CCS must not impact the Nexus structure.
+* CCS must not impact the libeufin-nexus structure.
* CCS must trigger Taler withdrawls every time a customer buys the
- regional currency ('buy-in' operation).
+ regional currency ('cash-in' operation).
* CCS must offer cash-out operations.
-* CCS should react as soon as possible to buy-in and cash-out operations.
+* CCS should react as soon as possible to cash-in and cash-out operations.
* CCS must show its state to administrators and offer management tools.
* CCS must link every fiat-side of a cash-out to its regional currency
counterpart. In particular, because every cash-out starts with a
payment *P* from regio-user to regio-issuer and ends with another
- payment *Q* from fiat-issuer to fiat-target, CCS must link P and Q.
+ payment *Q* from fiat-issuer to fiat-target, CCS must link P and Q.
Proposed Solution
=================
-The following design assumes that CCS is coded into libeufin Sandbox.
+The following design assumes that CCS is coded in libeufin-bank and that
+libeufin-bank and libeufin-nexus share the same database with separate
+schemas. The solution relies on SQL triggers to atomically synchronise
+cash-in and cash-out operations between the two schemas.
+
+SQL triggers and conversion operations
+--------------------------------------
+
+Libeufin-bank controls the conversion support and sets up or removes
+conversion SQL triggers when necessary. In order for the SQL triggers to
+perform the conversion operations, the configurable rates/fees are stored
+in the database and the conversion operations are performed using stored
+SQL procedures. The SQL triggers and conversion procedures are stored in
+the libeufin-bank schema.
Cash-out operation
------------------
-The libeufin Sandbox component learns instantly about a cash-out
-operation, because it's *the* service offering such feature.
-Therefore, as soon as a cash-out operation gets TAN-confirmed,
-Sandbox performs a first wire transfer from regio-user to regio-issuer
-by specifying the amount without any rates/fees applied. Along
-the same database transaction, Sandbox stores the *instructions*
-of another payment *P* from fiat-issuer to fiat-target, but this time
-**with** the cash-out rates/fees. Notably, P includes the **current**
-fiat-target and the rates/fees, since these are configurable.
-
-Asynchronously, a background task picks P and sends it to the fiat bank.
-Finally, fiat bank conducts P and fiat-target receives the wanted
-amount. The same background task should also retry previous payments
-like P that failed to be submitted to fiat bank.
-
-CCS offers management endpoints for prepared fiat-transactions.
-Through them, adminisrators can see, retry, or cancel every fiat-transaction
-that was prepared to pay fiat-target.
-
-Buy-in operation
-----------------
-
-A buy-in operation starts as soon as the customer sends a fiat
-payment from fiat-customer to fiat-issuer. Sandbox is responsible to
-detect such an incoming payment in a timely fashion. The detection
-happens by long polling on the Nexus JSON API. Nexus is ultimately
-responsible to query the fiat bank via EBICS every X seconds. X
-should match the tightest interval allowed by the bank.
-
-When Sandbox detects one incoming payment on fiat-issuer, it applies the
-**current** buy-in rates/fees and wires the resuling amount from regio-issuer
-to regio-exchange. At this point, Nexus detects the incoming payment on
-regio-exchange and makes the exchange aware via the Taler Wire Gateway API.
-From now on, the system proceeds like it always did in Taler.
-
-Milestones to a MVP
-===================
-
-* Refactor configuration in Sandbox: `7527 <https://bugs.gnunet.org/view.php?id=7527>`_, `7515 <https://bugs.gnunet.org/view.php?id=7515>`_.
-* Make rates/fees and TAN channels configurable in Sandbox: `7694 <https://bugs.gnunet.org/view.php?id=7694>`_.
-* Long polling in Nexus to serve TWG: `6987 <https://bugs.gnunet.org/view.php?id=6987>`_, `6383 <https://bugs.gnunet.org/view.php?id=6383>`_.
-* Long polling in Nexus to serve fiat-transactions via native API: `7693 <https://bugs.gnunet.org/view.php?id=7693>`_.
-* Long polling in Sandbox to ask Nexus fiat-transactions via native API.
-* Serve transactions with date ranges in Sandbox Access API: `7685 <https://bugs.gnunet.org/view.php?id=7685>`_
-* Implement JSON-based "bank connection" in Nexus. That's how Nexus
- gets regio-transactions to serve in the TWG.
-* Implement fiat-bank's EBICS flavor.
-* Ask transactions with date ranges in such flavor in Nexus: `7686 <https://bugs.gnunet.org/view.php?id=7686>`_.
-* Implement fiat-transactions management tools.
-
-.. note::
- The list can be incomplete and not necessarily ordered.
+Libeufin-bank learns instantly about a cash-out operation, because it's
+*the* service offering such feature. Therefore, as soon as a cash-out
+operation gets TAN-confirmed, libeufin-bank performs a wire transfer from
+regio-user to regio-issuer by specifying the amount without any rates/fees
+applied. Along the same database transaction, a SQL trigger store the
+*instructions* of another payment *P* from fiat-issuer to fiat-target,
+but this time **with** the cash-out rates/fees.
+
+Asynchronously, a libeufin-nexus background task picks P and sends it to
+the fiat bank. Finally, fiat bank conducts P and fiat-target receives the
+wanted amount. The same libeufin-nexus background task should also retry
+previous payments like P that failed to be submitted to fiat bank.
+
+Cash-in operation
+-----------------
+
+A cashin-in operation starts as soon as the customer sends a fiat
+payment from fiat-customer to fiat-issuer.
+
+The libeufin-nexus component is responsible to query the fiat bank
+via EBICS every X seconds. X should match the tightest interval allowed
+by the bank.
+
+When libeufin-nexus registers an incoming payment on fiat-issuer in the
+database, a SQL trigger applies the **current** cash-in rates/fees and
+performs a wire transfer from regio-issuer to regio-exchange. Libeufin-bank
+makes the exchange aware via the Taler Wire Gateway API and from now on,
+the system proceeds like it always did in Taler.
diff --git a/design-documents/037-wallet-transactions-lifecycle.rst b/design-documents/037-wallet-transactions-lifecycle.rst
index 9d749595..7a8cfacd 100644
--- a/design-documents/037-wallet-transactions-lifecycle.rst
+++ b/design-documents/037-wallet-transactions-lifecycle.rst
@@ -525,64 +525,6 @@ the same as if the double-spending transaction had been deleted by the user.
.. image:: ../images/transaction-refresh-states.png
-
-Transaction Type: Reward
-------------------------
-
-* ``pending(user)``
-
- We have downloaded the metadata for the reward. This is the initial state for a
- reward transaction. The user needs to accept/refuse the reward.
-
- * ``[reward-expired] => expired``
- * ``[action:accept] => pending(pickup)``
-
-* ``pending(pickup)``
-
- We are picking up the reward.
-
- * ``[failure] => failed``: any type of failure, including expiration.
- * ``[processed-kyc-required] => pending(kyc-required)``
- * ``[success] => done``
- * ``[action:suspend] => suspended(pickup)``
-
-* ``suspended(pickup)``
-
- The user suspended the operation while the reward was being picked up.
-
- * ``[reward-expired] => failed``
- * ``[action:resume] => pending(pickup)``
-
-* ``pending(kyc)``
-
- The user needs to perform a KYC check to continue. This usually should only
- happen if the wallet balance exceeds some threshold.
-
- * ``[poll-success] => pending(pickup)``
- * ``[action:suspend] => suspended(kyc)``
-
-* ``suspended(kyc)``
-
- The user suspended the KYC operation. Note that we do not time out here if
- the reward expires, as the wallet balance threshold KYC likely applies even
- without the reward.
-
- * ``[action:resume] => pending(kyc)``
-
-* ``done``
-
- The reward operation completed.
-
- * ``[action:delete] => deleted``
-
-* ``deleted``
-
- All memory of the reward operation is lost, but of course the resulting fresh
- coins are preserved.
-
-.. image:: ../images/transaction-reward-states.png
-
-
Transaction Type: Deposit
-------------------------
diff --git a/design-documents/039-taler-browser-integration.rst b/design-documents/039-taler-browser-integration.rst
index 71feb1c6..980f3f25 100644
--- a/design-documents/039-taler-browser-integration.rst
+++ b/design-documents/039-taler-browser-integration.rst
@@ -54,13 +54,7 @@ The problems with individual browsers are:
either.
Another issue is that Websites can't easily find out whether a browser
-extension handling the ``taler://`` protocol is installed. To avoid using this
-information for fingerprinting, anchors could provide an alternative ``href``
-in case the main one is not handled, such as:
-
-.. code:: html
-
- <a href="taler://pay/..." handler-unavailable-href="https://wallet.taler.net/">...</a>
+extension handling the ``taler://`` protocol is installed.
Requirements
============
@@ -81,32 +75,87 @@ Requirements
should work smoothly with future browsers that
have native, built-in support for Taler payments.
+Proposed Solution
+=================
-Alternatives
-============
+.. note::
+
+ As of 2023-01-23, we've decided to go ahead with the approach
+ described in this section.
+
+Overview
+^^^^^^^^
+
+The following integration approaches between Websites and the Taler Wallet webextension
+are provided:
+
+1. Directly triggering a ``taler://...`` URI on page load (via a meta tag).
+2. Overriding ``<a href="taler://..." onclick=...>`` tags to trigger the wallet.
+ The onclick handler (which must call preventDefault) can implement behavior
+ that happens only when the webextension is not available.
+3. Future (possibly post-1.0): A ``window.taler`` JavaScript API that is injected
+ into every page that requests it via a meta tag. This is useful for SPAs that
+ want to programmatically trigger the Taler wallet.
+
+
+Usage
+^^^^^
+
+To directly trigger the handling of a ``taler://`` URI on page load, the following meta tag can be used:
+
+.. code::
+
+ <meta name="taler-uri" content="taler://...">
+
+
+To enable additional communication features between a website and the GNU Taler Wallet webextension, the page must
+include the following meta tag:
+
+.. code::
+
+ <meta name="taler-support" content="$features">
-* JavaScript API: The WebExtension could inject a JavaScript API into Websites
- that allow interacting with the Taler wallet. This is the approach taken by
- the MetaMask crypto wallet. It requires excessive permissions, may break
- some Websites (https://github.com/brave/browser-laptop/issues/13711) and
- requires merchants to include extra JavaScript.
-
- * This type of interaction is useful for Single Page Apps and
- might be provided by the GNU Taler wallet reference implementation,
- at least when the user grants additional permissions.
- * Unfortunately, browsers currently do not provide a safe way
- for the communication between a WebExtension and the page
- without excessive permissions. This especially applies
- if the Website does not know the extension's ID. Hard-coding
- the extension IDs would violate the "no vendor lock-in requirement".
-
-* Handling ``taler://`` URIs by overriding the onclick handler of ``a`` HTML elements.
- This requires excessive permissions but would be a viable work-around,
- at least on pages that opt in with a special ``<meta name="taler-support" content="uri">`` tag.
- It does not work in all use-cases, for example when a navigation
+where ``$features`` is a comma-separated list of features.
+
+The following features are supported:
+
+* ``uri`` will hijack anchor elements (``<a href="taler://..." onclick=...>``) and replace their onclick handler
+ with a different handler that lets the webexension wallet handle the ``taler://`` URI.
+
+* (future): ``api`` will inject the ``window.taler`` API into the page
+
+
+Caveats and Comments
+^^^^^^^^^^^^^^^^^^^^
+
+* Anchor tag hijacking does not work in all use-cases, for example when a navigation
to a ``taler://`` URI is initiated programmatically or by pasting
the URI in the browser's address bar.
+* The ``window.taler`` API injection may break some websites
+ (https://github.com/brave/browser-laptop/issues/13711).
+
+* All these approaches require excessive permissions, as unfortunately,
+ browsers currently do not provide a safe way for the communication between a
+ WebExtension and the page without excessive permissions. This especially
+ applies if the Website does not know the extension's ID. Hard-coding the
+ extension IDs would violate the "no vendor lock-in requirement".
+
+* A neat feature of the anchor hijacking is that the ``taler://`` URI can be always be copied
+ in the browser (via "copy link address"). Clicking the link always results in either:
+
+ * The native URI handler, if no Taler Wallet webextension is installed and no onclick handler is defined
+ * The execution of the websites onclick handler if no Taler Wallet webextension is installed
+ * Triggering the webextension wallet to handle the ``taler://`` URI.
+
+* Future ``window.taler`` injection should be based on user preferences on
+ sites where the user has explicitly accepted to disclose that is owner of a
+ Taler wallet.
+
+Other Alternatives
+==================
+
+
* Triggering interactions with the ``taler://`` URI in a ``Taler:`` HTTP
header. This approach would allow browsers with native Taler support
(or a WebExtension) to handle payment/withdrawal initiations directly,
@@ -133,6 +182,10 @@ Alternatives
the Web Payments API would not support the withdrawal flow
(``taler://withdraw`` URIs).
+* Browsers could provide anchor elements with a fallback when the protocol isn't supported, such as
+ ``<a href="taler://pay/..." handler-unavailable-href="https://wallet.taler.net/">...</a>``.
+
+
Related Work and References
===========================
diff --git a/design-documents/041-wallet-balance-amount-definitions.rst b/design-documents/041-wallet-balance-amount-definitions.rst
index 1c89d634..9943d482 100644
--- a/design-documents/041-wallet-balance-amount-definitions.rst
+++ b/design-documents/041-wallet-balance-amount-definitions.rst
@@ -245,20 +245,6 @@ REFUND
Is there a way that the merchant can initiate a refund of purchase + refund_fee so
the wallet will get the same effective_amount?
-REWARD
- raw amount is the amount that the merchant send as reward
-
- ``instructed_amount`` = reward.amount
-
- ``raw_amount`` = instructed_amount + withdrawal_fee
-
- ``effective_amount`` = instructed_amount
-
- .. note::
- We should not show fee for rewards in the wallet since the merchant is the one choosing
- the exchange and we can assume that those rewards are paid by the merchant.
- So the wallet only care about the effective.
-
Coin selection algorithm
------------------------
diff --git a/design-documents/044-ci-system.rst b/design-documents/044-ci-system.rst
index e777f345..e38632c0 100644
--- a/design-documents/044-ci-system.rst
+++ b/design-documents/044-ci-system.rst
@@ -6,7 +6,7 @@ Summary
This documents describes Taler's CI system based on Buildbot.
-This document uses `RFC 2119 <https://tools.ietf.org/html/rfc2119>`_
+This document uses `RFC 2119 <https://tools.ietf.org/html/rfc2119>`_
keywords throughout.
Motivation
@@ -43,27 +43,28 @@ Example directory structure:
::
- ci
- ├── ci.sh
- ├── Containerfile
- └── jobs
- ├── 0-codespell
- │   ├── config.ini
- │   ├── dictionary.txt
- │   └── job.sh
- ├── 1-build
- │   ├── build.sh
- │   └── job.sh
- └── 2-docs
- ├── docs.sh
- └── job.sh
-
-Job directories **MUST** follow this pattern:
-``<repo_root>/ci/jobs/<n-job_name>/``
+ contrib
+ └── ci
+ ├── ci.sh
+ ├── Containerfile
+ └── jobs
+ ├── 0-codespell
+ │   ├── config.ini
+ │   ├── dictionary.txt
+ │   └── job.sh
+ ├── 1-build
+ │   ├── build.sh
+ │   └── job.sh
+ └── 2-docs
+ ├── docs.sh
+ └── job.sh
+
+Job directories **MUST** follow this pattern:
+``<repo_root>/contrib/ci/jobs/<n-job_name>/``
``n`` is an integer used for ordering the build steps.
-Job directories **MUST** contain a script named ``job.sh`` which **MAY**
+Job directories **MUST** contain a script named ``job.sh`` which **MAY**
execute other scripts.
Config files may optionally be created, and MUST be named ``config.ini`` and
@@ -78,11 +79,12 @@ Available config options:
WARN_ON_FAILURE = True|False
CONTAINER_BUILD = True|False
CONTAINER_NAME = <string>
+ CONTAINER_ARCH = <string>
Unless *all* jobs specify a "CONTAINER_NAME" in their custom config a
-container file **MUST** be present at ``<repo_root>/ci/Containerfile``.
-The container file will be built and used to run all of a repo's jobs
+container file **MUST** be present at ``<repo_root>/contrib/ci/Containerfile``.
+The container file will be built and used to run all of a repo's jobs
by default.
All projects SHOULD have a ``build`` step and a ``test`` step, at a minimum.
@@ -92,24 +94,31 @@ Running CI Locally
Running the CI scripts locally can be useful for development and testing.
-*Be aware that custom configs for a given job may specify a alternate
-container.*
-
-
-Example of building the environment and running a job locally:
+Included in each CI directory is a script which simplifies running jobs
+in the same way the CI Worker does, in containers, using ``podman``.
::
- # From root of repo directory, build the container:
- docker build -t <local_name_for_container> -f ci/Containerfile . # <- don't forget the "."
-
- # Then to run one of the job scripts. For example:
- docker run --rm --volume $PWD:/workdir --workdir /workdir <local_name_for_container> ci/jobs/1-build/job.sh
-
- # or to get an interactive shell in the container, with the repo mounted at /workdir:
- docker run -ti --rm --volume $PWD:/workdir --workdir /workdir <local_name_for_container> /bin/bash
-
-
+ # Usage:
+ ./contrib/ci/ci.sh <job-name>
+
+ # For example, if the CI jobs tree looks like this:
+ ./contrib/ci/jobs
+ ├── 0-codespell/
+ ├── 1-build/
+ ├── 2-test/
+ ├── 3-docs/
+ ├── 4-deb-package/
+ └── 5-deploy-package/
+
+ # Then you can run job '0-codespell' as follows:
+ ./contrib/ci/ci.sh 0-codespell
+
+ # If you are using podman and have "qemu-user-binfmt" installed
+ # then you may attempt to run any job under an alternative CPU
+ # architecture by providing a second argument.
+ # For example:
+ ./contrib/ci/ci.sh 0-codespell arm64
Additional Builders
diff --git a/design-documents/046-mumimo-contracts.rst b/design-documents/046-mumimo-contracts.rst
index 5bc3d25a..fcb7f2b1 100644
--- a/design-documents/046-mumimo-contracts.rst
+++ b/design-documents/046-mumimo-contracts.rst
@@ -472,10 +472,7 @@ consumes an available discount token, that contract should be moved up in the
list.
Which specific alternative contract was chosen by the user is indicated in the
-subcontract index field of the :ref:`TALER_DepositRequestPS`.
-
-FIXME-DOLD: Should we also sign over this in the
-:ref:`TALER_DepositConfirmationPS`?
+subcontract index field of the :ref:`TALER_DepositRequestPS <taler_depositrequestps>`.
Output Commitments
@@ -483,8 +480,9 @@ Output Commitments
When a contract has outputs, the wallet must send an array of blinded tokens,
coins or tax receipts together with the payment request. The order in the
-array must match the order in the outputs field of the contract. For currency outputs, one array element must include all of the required planchets for a batch withdrawal,
-but of course not the reserve signature.
+array must match the order in the outputs field of the contract. For currency
+outputs, one array element must include all of the required planchets for a
+batch withdrawal, but of course not the reserve signature.
.. note::
@@ -492,10 +490,7 @@ but of course not the reserve signature.
batch-withdraw API to only use a single reserve signature.
This array of blinded values is hashed to create the output commitment hash
-(``h_outputs``) in the :ref:`TALER_DepositRequestPS`.
-
-FIXME-DOLD: Should we also sign over this in the
-:ref:`TALER_DepositConfirmationPS`?
+(``h_outputs``) in the :ref:`TALER_DepositRequestPS <taler_depositrequestps>`.
diff --git a/design-documents/048-wallet-exchange-lifecycle.rst b/design-documents/048-wallet-exchange-lifecycle.rst
index b3df4d8a..75ec3afb 100644
--- a/design-documents/048-wallet-exchange-lifecycle.rst
+++ b/design-documents/048-wallet-exchange-lifecycle.rst
@@ -67,14 +67,24 @@ Update Status
~~~~~~~~~~~~~
* ``initial``: Not updated, no need to update
-* ``initial(update)``: Update pending, possibly with error
+* ``initial-update``: Update pending, possibly with error
* ``suspended``: Exchange was manually disabled, should not be contacted
anymore, but record is kept in the wallet. Mostly useful for testing.
-* ``failed``: Updating the exchange info failed permanently, the exchange is
- not usable for any operations.
-* ``outdated(update)``
+* ``unavailable-update``: The exchange is currently unavailable to be used for withdrawals,
+ but it is possible that the exchange starts working again in the future.
+ The wallet will re-try contacting the exchange. The wallet will still try
+ operations that *spend* coins, but the user might be warned about the bad
+ exchange status.
+
+ Examples:
+
+ * The exchange updated to a new protocol version that is incompatible with the wallet
+ * The exchange advertises a new master public key. This might be a temporary
+ configuration issue or malicious attack.
+ * The exchange only advertises outdated denomination keys, making new withdrawals
+ impossible.
* ``ready``: Exchange is useable.
-* ``ready(update)``: Exchange is useable, but currently being updated.
+* ``ready-update``: Exchange is useable, but currently being updated.
ToS Status
~~~~~~~~~~
@@ -125,4 +135,10 @@ Definition of Done
Discussion / Q&A
================
-(This should be filled in with results from discussions on mailing lists / personal communication.)
+* Should there be a "permanently failed" update state?
+
+ * dold => I don't think so, as it means that temporary configuration issues on the side of the
+ exchange might *permanently* brick users' wallets.
+ The wallet should always re-try contacting the exchange and of course possibly report
+ information to the auditor.
+
diff --git a/design-documents/050-libeufin-nexus.rst b/design-documents/050-libeufin-nexus.rst
index 779e0b58..6049bda6 100644
--- a/design-documents/050-libeufin-nexus.rst
+++ b/design-documents/050-libeufin-nexus.rst
@@ -59,11 +59,11 @@ Configuration file
HOST_ID = mybank
USER_ID = myuser
PARTNER_ID = myorg
- SYSTEM_ID = banksys
- ACCOUNT_NUMBER = DE1234567890 # This value must identify with how the bank calls the bank account
+ IBAN = MY-IBAN
+ BIC = MY-BIC
+ NAME = MY NAME
BANK_PUBLIC_KEYS_FILE = enc-auth-keys.json
CLIENT_PRIVATE_KEYS_FILE = my-private-keys.json
- ACCOUNT_META_DATA_FILE = ebics-meta.json
BANK_DIALECT = postfinance # EBICS+ISO20022 style used by the bank.
[nexus-postgres]
@@ -112,15 +112,6 @@ JSON with:
* submitted_ini (boolean)
* submitted_hia (boolean)
-File contents: ACCOUNT_META_DATA_FILE
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-JSON with:
-
- * account_holder_iban
- * bank_code
- * account_holder_name
-
Database schema
---------------
@@ -194,15 +185,6 @@ The ebics-setup tool performs the following:
accept them (or auto-accept via --auto-accept-keys). If the user accepted
the public key, update the flag to "accepted".
- * If all of the above has happened and we have accepted public keys from the
- bank, try to download the list of bank accounts associated with the
- connection and check that the configured account number is among them. On
- success, store the associated meta data in the account meta data file. On
- failure, show an error message with the list of available accounts (also
- show this list via --show-associated-accounts). If the configured account
- number is available, show a brief "setup ready" message.
-
-
nexus-ebics-fetch
-----------------
@@ -214,6 +196,23 @@ nexus-ebics-fetch
over (before committing any transactions with the next day!) also fetches a
final statement of the previous day, thus ensuring we get a statement
every day plus intra-day reports.
+
+ .. note::
+
+ (1) "from that day forward (inclusive)" must **not** rely on EBICS returning
+ the unseen messages: that's because they might **already** be downloaded but
+ never made it to the database.
+
+ (2) "and when the day rolls over". When does a day roll over? => A day rolls
+ over when the current time is at least on the day after the transaction with the
+ most recent timestamp that's stored in the database.
+
+ (3) "Afterwards, fetches reports". This must happen **only after** any possible
+ previous statement got downloaded.
+
+ To summarize: at any point in time the database must contain (the content of) any
+ possible statement up to the current time, plus any possible report up to the current
+ time (in case that's not covered by any statement so far).
* Bounces transactions with mal-formed wire transfer subjects.
@@ -315,3 +314,41 @@ Discussion / Q&A
the bank response, may lead double-submission even if the HTTP talk ended
well: it suffices to crash after having received a "200 OK" response but
before setting the submitted flag to the database.
+
+* the ebics-submit section mentions the EBICS order ID. The following excerpt
+ was found however at page 88 of the EBICS 3 specifications:
+
+ ``OrderID is only present if a file is transmitted to the bank relating to an order with an
+ already existing order number (only allowed for AdminOrderType = HVE or HVS)``
+
+ Nexus does not support HVE or HVS.
+
+* As of private communication, the responsibility of submitting idempotent payments
+ relies on the use of ``request_uid`` (a database column of the initiated payment)
+ as the ``MsgId`` value of the corresponding pain.001 document.
+
+* ``submitted`` column of an initiated payment evolved into the following enum:
+
+ .. code-block:: shell-session
+
+ CREATE TYPE submission_state AS ENUM (
+ 'unsubmitted'
+ ,'transient_failure'
+ ,'permanent_failure'
+ ,'success'
+ ,'never_heard_back'
+ );
+
+ * ``unsubmitted``: default state when a payment is initiated
+ * ``transient_failure``: submission failed but can be retried, for example after a network issue.
+ * ``permanent_failure``: EBICS- or bank-technical error codes were not EBICS_OK (nor any tolerated EBICS code like EBICS_NO_DOWNLOAD_DATA_AVAILABLE), never retry.
+ * ``never_heard_back``: the payment initiation submission has **been** ``success`` but it was never confirmed by any outgoing transaction (from a camt.5x document) or any pain.002 report. It is responsability of a garbage collector to set this state after a particular time period.
+
+* the initiated_outgoing_transactions table takes two more columns:
+ ``last_submission_date``, a timestamp in microseconds, and a
+ ``submission_counter``. Both of them would serve to decide retry
+ policies.
+
+* the ``failure_text`` column at the initiated_outgoing_transactions table
+ should contain a JSON object that contains any useful detail about the problem.
+ That *could* be modeled after the Taler `ErrorDetail <https://docs.taler.net/core/api-common.html#tsref-type-ErrorDetail>`_, where at least the error code and the hint fields are provided.
diff --git a/design-documents/051-fractional-digits.rst b/design-documents/051-fractional-digits.rst
index 31e2959d..4321fd53 100644
--- a/design-documents/051-fractional-digits.rst
+++ b/design-documents/051-fractional-digits.rst
@@ -19,33 +19,30 @@ end-user apps should follow these guidelines.
Requirements
============
-There is already a specification for ScopedCurrencyInfo - this needs to change
+There was already a specification for ScopedCurrencyInfo - which got renamed to CurrencySpecification.
We need three core characteristics for fractional digits for each currency:
-e) the number of fractional digits e in [0..8] the user may 'e'nter in a TextInputField
+ e) the number of fractional digits e in [0..8] the user may 'e'nter in a TextInputField
-n) the number of fractional digits n in [0..8] to be rendered as 'n'ormal characters (same font and size as the integer digits).
- All additional fractional digits will be rendered as SuperScriptDigits as known from gas filling stations.
- The UI should never round or truncate any amount, but always render all existing digits (except trailing zeroes, see c).
+ n) the number of fractional digits n in [0..8] to be rendered as 'n'ormal characters (same font and size as the integer digits). All additional fractional digits will be rendered as SuperScriptDigits as known from gas filling stations. The UI should never round or truncate any amount, but always render all existing digits (except trailing zeroes, see c).
-z) the number of fractional digits z in [0..8] to be rendered as trailing 'z'eroes (including SuperScript digits).
- E.g. if z = 2 (and n = 2), then render $5 as “$ 5.00”.
- If z = 3 (and n = 2), then render $5 as “$ 5.00⁰” with two normal trailing zeroes and one superscript trailing zero.
+ z) the number of fractional digits z in [0..8] to be rendered as trailing 'z'eroes (including SuperScript digits). E.g. if z = 2 (and n = 2), then render $5 as ``$ 5.00``. If z = 3 (and n = 2), then render $5 as ``$ 5.00⁰`` with two normal trailing zeroes and one superscript trailing zero.
The values e, n, and z are independent from each other. Each could be any value
from 0 to 8. However, when a user enters an amount, s/he should be able to input
all normal fractionals. Thus e should never be smaller than n.
Usually, all these three numbers have the same value (e = n = z), which means
-that in case of e.g. “2” (used for €,$,£) the user can enter cent/penny values
+that in case of e.g. '2' (used for €,$,£) the user can enter cent/penny values
(but not a fraction of those), these cents/pennies are always shown (even if
they are 0) as two normal digits after the decimal separator, and fractions of
a cent/penny are rendered as SuperScriptDigits, but appear only if they are not
trailing zeroes.
For japanese ¥, all three values could be 0, which means that the user cannot
-enter fractionals at all. Fractions would never be rendered as normal digits
-but always as SuperScript, and appear only if they are not trailing zeroes.
+enter fractions at all. If there are fractions they would never be rendered as
+normal digits but always as SuperScript, and appear only if they are not
+trailing zeroes.
Additionally, some cryptocurrencies have such huge units, that they are
commonly rendered in milli-units, such as mBTC (milliBTC, 1/1000 of a BTC),
@@ -57,20 +54,6 @@ could also make sense for inflated currencies in some cases. So we probably
should also have the ability to ship such a conversion map.
-
-iOS has a built-in currency formatter, which knows how to deal with
-thousands-separators and where to apply them (e.g. India uses a mixture of
-hundreds and thousands instead of putting the separator after each 3 digits
-like western currencies). However, this formatter will round after two (or
-three) fractional digits and thus cannot be used for the whole amount. But it
-could be used to convert the integer part plus the fractional part to be
-rendered as normal digits (n) into a string, and then remaining fractional
-digits (if not zero, or if trailing SuperScript zeroes should be shown)
-could be added as SuperScript digits to this formatted string.
-
-(please add information about Android and WebEx here)
-
-
Proposed Solution
=================
@@ -78,7 +61,7 @@ Protocol considerations
-----------------------
The exchange, bank and merchant backends would need to be configured (via
-their configuration files) to return the following ScopedCurrencyInfo in their
+their configuration files) to return the following CurrencySpecification in their
``/config`` and/or ``/keys`` endpoints. The bank returns this so that the
bank SPA can render amounts correctly, the exchange informs the wallets about
the desired way to render the currency, and the merchant backend informs the
@@ -88,34 +71,37 @@ provisioned by all three services.
.. code-block:: swift
- public struct ScopedCurrencyInfo: Codable, Sendable {
+ public struct CurrencySpecification: Codable, Sendable {
// e.g. “Japanese Yen” or "Bitcoin (Mainnet)"
let name: String
- // e.g. “.” for $ and ¥; “,” for €
- let decimal_separator: String
- // how many digits the user may enter after the decimalSeparator
- let num_fractional_input_digits: Integer
+ // how many digits the user may enter after the decimal separator
+ let fractional_input_digits: Int
// €,$,£: 2; some arabic currencies: 3, ¥: 0
- let num_fractional_normal_digits: Int
- // usually same as numFractionalNormalDigits, but e.g. might be 2 for ¥
- let num_fractional_trailing_zero_digits: Int
- // true for “$ 3.50”; false for “3,50 €”
- let is_currency_name_leading: Bool
- // map of powers of 10 to alternative currency names / symbols, must
- // always have an entry under "0" that defines the base name,
- // e.g. "0 => €" or "3 => k€". For BTC, would be "0 => BTC, -3 => mBTC".
+ let fractional_normal_digits: Int
+ // usually same as fractionalNormalDigits, but e.g. might be 2 for ¥
+ let fractional_trailing_zero_digits: Int
+ // map of powers of 10 to alternative currency names / symbols,
+ // must always have an entry under "0" that defines the base name,
+ // e.g. "0 : €" or "3 : k€". For BTC, would be "0 : BTC, -3 : mBTC".
// This way, we can also communicate the currency symbol to be used.
- let alt_unit_names: Map<Int, String>
+ let alt_unit_names: [Int : String]
}
+(Note: decimal_separator, group_separator and is_currency_name_leading were
+removed from this struct since they should always be taken from the user's
+locale.)
+
+
+
+
For very large (2400000) or very tiny amounts (0.000056) the software would
then first represent the number compactly without any fraction (so for our
examples above, 24 * 10^6 and 56 * 10^-6) and then search for the nearest fit
in the alt_unit_names table. The result might then be 24000 KGELD or 0.056
mGELD, assuming the map had entries for 3 and -3 respectively. Depending on
-the table, the result could also be 24 MGELD (6 => MGELD), or 5.6 nGELD
-(assuming -6 => nGeld). Fractional rendering rules would still be applied
-to the alternative unit name, alas the "num_fractional_input_digits" would
+the table, the result could also be 24 MGELD (6 : MGELD), or 5.6 nGELD
+(assuming -6 : nGeld). Fractional rendering rules would still be applied
+to the alternative unit name, alas the "fractional_input_digits" would
always apply to the unit currency and may need to be adjusted if amounts
are input using an alternative unit name.
@@ -132,52 +118,52 @@ section. The map could be given directly in JSON. For example:
ENABLED = YES
name = "Euro"
code = "EUR"
- decimal_separator = ","
fractional_input_digits = 2
fractional_normal_digits = 2
fractional_trailing_zero_digits = 2
- is_currency_name_leading = NO
alt_unit_names = {"0":"€"}
[currency-japanese-yen]
ENABLED = YES
name = "Japanese Yen"
code = "JPY"
- decimal_separator = "."
fractional_input_digits = 2
fractional_normal_digits = 0
fractional_trailing_zero_digits = 2
- is_currency_name_leading = YES
alt_unit_names = {"0":"¥"}
[currency-bitcoin-mainnet]
ENABLED = NO
name = "Bitcoin (Mainnet)"
code = "BITCOINBTC"
- decimal_separator = "."
fractional_input_digits = 8
fractional_normal_digits = 3
fractional_trailing_zero_digits = 0
- is_currency_name_leading = NO
alt_unit_names = {"0":"BTC","-3":"mBTC"}
[currency-ethereum]
ENABLED = NO
name = "WAI-ETHER (Ethereum)"
code = "EthereumWAI"
- decimal_separator = "."
fractional_input_digits = 0
fractional_normal_digits = 0
fractional_trailing_zero_digits = 0
- is_currency_name_leading = NO
alt_unit_names = {"0":"WAI","3":"KWAI","6":"MWAI","9":"GWAI","12":"Szabo","15":"Finney","18":"Ether","21":"KEther","24":"MEther"}
Implementation considerations
-----------------------------
-For iOS, we plan to format the integer part of the amount with the built-in
-currency formatter, then add the fractional part according to this document.
+iOS has a built-in currency formatter, which can be configured from a locale.
+It knows how to deal with group-separators and where to apply them (e.g. India
+uses a mixture of thousands and hundreds instead of putting the separator after
+each 3 digits like western currencies).
+Set the formatter's parameter 'maximumFractionDigits' to 8, then it will not
+round the value and thus can be used for the whole amount.
+Set its parameter 'minimumFractionDigits' to 'z' (fractionalTrailingZeroDigits)
+to let it automatically add trailing zeroes.
+Then convert all fractional digits after 'n' (fractionalNormalDigits) to
+SuperScript digits.
(please add information about Android and WebEx here)
@@ -213,7 +199,7 @@ Discussion / Q&A
We probably should NOT have the decimalSeparator in this definition. Instead that
should be taken from the locale of the user, so they see currency amounts formatted
like they're used to.
-If we really keep this, then we would also need the thousandsSeparator to ensure it is
+If we really keep this, then we would also need the groupSeparator to ensure it is
not identical to the decimalSeparator.
Better to leave this can of worms to the operating system our app runs on, and render
according to the user's preferences (locale)...
diff --git a/design-documents/052-libeufin-bank-2fa.rst b/design-documents/052-libeufin-bank-2fa.rst
new file mode 100644
index 00000000..3d0900e2
--- /dev/null
+++ b/design-documents/052-libeufin-bank-2fa.rst
@@ -0,0 +1,136 @@
+DD 52: LibEufin Bank Two-factor authentification
+################################################
+
+Summary
+=======
+
+This document proposes designs for supporting 2-FA for more operations in
+libeufin-bank.
+
+Motivation
+==========
+
+Currently, only cashout operations are protected using 2-FA and we want to also
+protects withdrawal, transactions, account reconfiguration and account deletion.
+
+Requirements
+============
+
+* Support future TAN channels (YubiKey, trusted devices, etc) without API-breaking changes
+* Support multiple TAN channels per user
+
+Proposed Solutions
+==================
+
+2 kinds of operations
+^^^^^^^^^^^^^^^^^^^^^
+
+We have two kinds of operations we would like to protect:
+
+* state-machine operations that already have a ``pending`` and ``confirmed`` status and require multiple endpoint calls to complete (cashout and withdrawal).
+* one-shot operations that are currently completed using a single endpoint call (transaction, account reconfiguration and account deletion).
+
+Fine-grained or coarse-grained authentification
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Fine-grained authorization is when one challenge is linked to a unique unalterable operation. They are the most secure and have the usability advantage that clients can show users exactly what they are allowing. They are complicated to implement especially for one-shot operations.
+* Coarse-grained authorization is when each challenge allows to perform one or many protected operations of any kind. They are the simplest to implement and might be enough for our needs.
+
+We should also take in consideration how hard it would be to maintain the solution and how hard it would be to protect a new kind of operation in the future.
+
+State machines operations only
+------------------------------
+
+If we transform all operations to become state-machine ones, we can use the same design currently used for cashout operations. All operations are created in a ``pending`` state and need to be confirmed later. The TAN challenge code is sent when the operation is created and checked during confirmation. Operation creation is idempotent and can be used to trigger code retransmission.
+
+The good
+^^^^^^^^
+
++ Fine-grained authorization
+
+The bad
+^^^^^^^
+
+- Requires to store pending operations in the database, requires new tables to store pending state for one-shot ones
+- Requires to add many endpoints to track operations status, list pending operations, confirm operations, etc
+- Requires to mix TAN challenge logic with operation logic, this means asking for TAN channel alongside operation data and returning TAN specific error in all operation creation and confirmation endpoints, therefore TAN logic changes can impact all those endpoints
+- Operation logic rewrite
+- Big backend and database change (new table or column and new API per operation)
+
+
+Centralized 2FA endpoints
+-------------------------
+
+To improve upon the previous design we can separate endpoints to perform TAN challenges from operation ones. When creating operations they return a challenge ID that can be used with TAN-specific endpoints to receive and solve a challenge. Those endpoints will handle the TAN channel choice and TAN-specific errors. Protected endpoints will error when a pending challenge hasn't been solved.
+
+The good
+^^^^^^^^
+
++ Fine-grained authorization
++ Centralized TAN challenge logic and error handling, TAN logic changes only impact TAN-specific endpoints
+
+The bad
+^^^^^^^
+
+- Requires to store pending operations in the database
+- Requires adding many endpoints to track operations status, confirm operations, list pending operations, etc.
+- Operation logic rewrite
+- Big backend and database change (new table or column and new API per operation)
+
+2FA tokens
+----------
+
+To improve upon the previous design, if coarse-grained authorization is enough, we can have a simpler design where a successful challenge produces a one-use 2FA token. Protected endpoints will error when a 2FA token is required and the token is provided through an HTTP header.
+
+We could require a 2FA token when confirming state-machine operations or when performing one-shot ones. Removing the need for new database tables and operation endpoints.
+
+The good
+^^^^^^^^
+
++ Existing database tables stay the same
++ Centralized TAN challenge logic and error handling
++ Most endpoints stay the same except the cashout API
++ Can protect new operations without changing their logic but need to add token consumption logic to the database transaction
++ Small backend and database change per operation (token consumption logic)
+
+The bad
+^^^^^^^
+
+- Using a nonstandard header can be complicated for some clients
+- The pending state of one-shot operations is kept at the client level, this is a simplification for the backend but we do not want to lose this state. This might be easy to do as all oneshot operations are simple ones and the token can be obtained in advance.
+- Coarse-grained authorization, one token for any operation. We could fix this by adding a ``kind`` field and an optional ``operation_id`` (state-machine operation) or ``operation_body`` (one-shot operations) field per challenge but this is ugly.
+
+2FA auth tokens
+---------------
+To improve upon the previous design, we could reuse the existing authentification token logic and create a new scope, ``2fa``, that works as an augmented ``readwrite``. Those auth tokens would be valid for a short amount of time (~3 minute) and would not be refreshable.
+
+The good
+^^^^^^^^
+
++ Existing database tables stay the same
++ Centralized TAN challenge logic and error handling
++ Most endpoints stay the same except the cashout API
++ Can protect new operations without changing their logic
++ Trivial backend and database change per operation (one line of code per operation)
+
+The bad
+^^^^^^^
+
+- Having a short-term token in addition to a long-term refreshable token can be confusing for clients.
+- We still keep the pending state of one-shot operations at the client level.
+- Coarse-grained authorization, one token for any operation for a short amount of time.
+
+Q / A
+=====
+
+* Q: Where do we want to handle TAN challenges logic and error handling, in each operation API or a TAN-specific API?
+
+ * In each operation means fewer API calls and TAN-specific means more API calls but better/cleaner logic separation.
+
+* Q: Where do we want to store pending states for oneshot transactions in the client or the backend database?
+
+ * In the client makes things simpler for the backend but is incompatible with coarse-grained authorization.
+
+* Q: Do we need coarse-grained authorization or fine-grained is enough?
+
+ * Coarse-grained authorization requires that we store pending states for operations even for the ones that are currently oneshot. We could use a different strategy for each kind. \ No newline at end of file
diff --git a/design-documents/053-wallet-ui.rst b/design-documents/053-wallet-ui.rst
new file mode 100644
index 00000000..c36d4759
--- /dev/null
+++ b/design-documents/053-wallet-ui.rst
@@ -0,0 +1,355 @@
+DD 53: Wallet UI Design
+#######################
+
+Summary
+=======
+
+This document proposes designs wallet UI. It defines what Android, iOS and
+WebExtension should follow in order to have a coherent UI between platforms.
+
+Motivation
+==========
+
+We want user to be able to help each others independent of the implementation
+they are using.
+We want user to be able to capitalize the effort of learning how to use one
+wallet and be able to use a different one without the need to learn
+anything new.
+Currently development of different platform specific implementation are independent
+and every developer needs to choose the layout, texts and buttons and navigation.
+
+Requirements
+============
+
+Every screen MUST be defined in a document with the following information:
+
+* **Identifiable UI screens**: every UI should have an unique identifier that will
+ be use for development discussion and bug reports. There should be an option
+ in the application to enable an active rendering of the id.
+
+* **Description**: the reason to be of the screen, should help to define what will
+ be included into, what is going to left for other screens and when and from
+ where should be linked.
+
+The screen MAY also have:
+
+* **Predefined assets**: every implementation should resue the same icons, images,
+ fonts and sounds.
+
+Additionaly the document COULD defined the components of the UI. If one of this
+properties is defined in the spec the implementation must implement it. The specification
+should be minimal to achieve the objective in the description.
+
+* **Info**: Spec of information that the user should have access. The type of info
+ could be a field (id and value) or a banner (information and instructions).
+ The spec will help to reuse the text for i18n across apps and defined
+
+* **Inputs**: Spec of information need to provide in current screen. The type of input,
+ range of values and validation should be defined if necessary.
+
+* **Actions**: Spec of buttons and interactable elements that will have a significant
+ change in the current state. It should also mention navigation when applicable.
+
+* **Layout**: Spec position of elements when needed. The spec should be "soft" in a sense
+ that elements should be easy to find following directions like "close to X" or
+ "at the start/end of the screen".
+
+Screen should be defined using the most relaxed definition that are good enough to
+be clear for the user. Platform will use this definition and adapt to the differences
+on the platform taking advantange of platform API and screen sizes.
+
+When a screen have multiple uses for the same purpose, a substate section should be
+included with the difference with the main definition.
+
+Part of the screens that are reused shoud also be defined in this document as screen.
+
+Common definition:
+ * navigation between screen should not happen if the user didn't take any action
+
+
+Proposed Solutions
+==================
+
+List of all screens with the defined properties.
+
+cta-withdraw
+------------
+
+``Description``: this screen is used for the confirmation of a manual withdrawal,
+bank-integrated witdrawals and exchange withdrawals.
+the success of this operation will be an increase of the balance in the wallet.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * exchange to be used showing the URL
+ * table of details of the operation: use the ``operation-table-details`` screen
+ * starting currency: if the exchange has the currency conversion service enabled user should be able to the details based on the wire transfer currency
+ * taler URI: show copy button or QR to complete the operation with another device
+
+``Inputs``:
+ * age restriction: allow the selection of the restriction in the age group possible by the exchange
+ * service provider: allow the selection of different exchange
+
+``Actions``:
+ * confirm operation: on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * review and confirm ToS: if the current selected exchange has a version of ToS that the user didn't yet accepted, use the ``accept-tos`` screen
+ * cancel: user will be redirected to ``balance``
+
+.. attention::
+ User should be able to play with the amount, not possible in the current design
+
+cta-wire-transfer
+-----------------
+
+``Description``: this screen is used to show the user the information for
+the wire transfer to complete a manual withdrawal operation.
+
+``Info``:
+ * wire transfer subject to be used (first, most important)
+ * target bank account to transfer funds to (e.g. IBAN)
+ * total amount to transfer in the wire transfer currency
+ * button to copy ``payto://`` URI with the information to clipboard
+
+``Actions``:
+ * abort: aborts the withdrawal operation
+ * menu: go back to the main balances list (operation continues in background)
+ * automatic: screen changes to "cta-withdraw-done" upon completion
+
+.. image:: ../screenshots/cta-wire-transfer-firefox-latest.png
+
+cta-withdraw-done
+-----------------
+
+``Description``: this screen is used to show the user the information for
+a completed withdraw operation (bank-integrated or manual)
+
+``Info``:
+ * amount wired (hidden if no fees)
+ * fees paid (hidden if no fees)
+ * total amount withdrawn into wallet (effective balance change)
+ * exchange base URL
+ * date
+
+``Actions``:
+ * delete: deletes information about the withdrawal operation
+
+.. image:: ../screenshots/cta-withdraw-done-firefox-latest.png
+
+
+cta-url-entry
+-------------
+
+``Description``: this screen allows the user to scan a QR code, scan an NFC
+tag, or enter a taler://-URL. Its implementation may differ significantly
+between platforms. For example, scanning NFC tags may be fully automated,
+scanning QR codes may involve some system applications, and maybe the dialog
+only allows the URL entry *or* the camera but not both at the same time,
+depending on implementation specifics.
+
+``Info``:
+ * camera with current image to enable user to focus on QR code
+ * current URL, with information if it is not well-formed for GNU Taler
+ * possibly status information on NFC reader (if available)
+
+``Actions``:
+ * open: if entered manually, open URL as-entered (otherwise open is automatic)
+ * back: return to previous view
+
+.. image:: ../screenshots/cta-url-entry-firefox-latest.png
+
+
+cta-payment
+-----------
+
+``Description``: this screen is used for the confirmation of a payment to a merchant.
+the success of this operation will be an decrease of the balance in the wallet
+and save a ticket/invoice of the purchase.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * merchant offering the order showing the URL
+ * order summary
+ * table of details of the operation: use the ``operation-table-details`` screen
+ * receipt: order id
+ * payment deadline: absolute time before the claimed order expires
+ * taler URI: show copy button or QR to complete the operation with another device
+ * cant pay desc: if the user has enough balance but unable to use it
+ * payment status: if the
+
+``Actions``:
+ * confirm operation: if the payment is possible, on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * get more cash: if there is not enough balance, it will be redirected to ``cta-witddraw``
+ * cancel: user will be redirected to ``balance``
+
+.. image:: ../screenshots/cta-payment-firefox-latest.png
+
+cta-payment-paid
+----------------
+
+``Description``: this screen is used to show information with details
+about a historic payment.
+
+``Info``:
+ * merchant offering the order showing the URL
+ * order summary
+ * table of details of the operation: use the ``operation-table-details`` screen
+ * receipt: order id
+ * payment status: if the order was refunded
+
+``Actions``:
+ * delete: delete information about the transaction
+ * back: user will be redirected to ``balance``
+
+.. image:: ../screenshots/cta-payment-paid-firefox-latest.png
+
+cta-deposit
+------------
+
+``Description``: this screen is used for the confirmation of a deposit.
+the success of this operation will be an decrease of the balance in the wallet
+and save a deposit ticket for reference.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * bank account where the money is going to
+ * table of details of the operation: use the ``operation-table-details`` screen
+
+``Actions``:
+ * confirm operation: on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * cancel: user will be redirected to ``balance``
+
+.. attention::
+ User should be able to play with the amount, not possible in the current design
+
+
+cta-peer-pull-initiate
+----------------------
+
+``Description``: this screen is used for the confirmation of the creation of
+a peer pull transaction or invoice to request money from another wallet.
+the success of this operation will not change the balance immediately in the wallet
+and allow the user to share a taler URI to the payer.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * exchange to be used showing the URL
+ * table of details of the operation: use the ``operation-table-details`` screen
+
+``Inputs``:
+ * subject: short description of the transaction
+ * expiration: absolute time/date after which the invoice is not valid anymore
+ * service provider: allow the selection of different exchange
+
+``Actions``:
+ * confirm operation: on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * review and confirm ToS: if the current selected exchange has a version of ToS that the user didn't yet accepted, use the ``accept-tos`` screen
+ * cancel: user will be redirected to ``balance``
+
+.. attention::
+ Is the invoice creation always free of charge or does the exchange have a mechanism
+ to impose a fee to pay on creation?
+
+
+cta-peer-pull-confirm
+---------------------
+
+``Description``: this screen is used for the confirmation of the payment of
+a peer pull transaction or invoice to send money from another wallet.
+the success of this operation will be an will decrease the balance in the wallet.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * exchange to be used showing the URL
+ * subject: short description of the transaction
+ * table of details of the operation: use the ``operation-table-details`` screen
+ * expiration: absolute time/date after which the invoice is not valid anymore
+
+``Actions``:
+ * confirm operation: if the payment is possible, on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * get more cash: if there is not enough balance, it will be redirected to ``cta-witddraw``
+ * cancel: user will be redirected to ``balance``
+
+cta-peer-push-initiate
+----------------------
+
+``Description``: this screen is used for the confirmation of the creation of
+a peer push transaction or transfer money to another wallet.
+the success of this operation will reduce the balance immediately in the wallet
+and allow the user to share a taler URI to the receiver.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * table of details of the operation: use the ``operation-table-details`` screen
+
+``Inputs``:
+ * subject: short description of the transaction
+ * expiration: absolute time/date after which the transfer is not valid anymore
+
+``Actions``:
+ * confirm operation: on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * cancel: user will be redirected to ``balance``
+
+cta-peer-push-confirm
+---------------------
+
+``Description``: this screen is used for the confirmation of the acceptance of
+a peer push transaction or transfer money to this wallet.
+the success of this operation will be an will decrease the balance in the wallet.
+fee, restrictions and ETA should be clear for the user.
+
+``Info``:
+ * subject: short description of the payment
+ * expiration: absolute time/date after which the invoice is not valid anymore
+ * table of details of the operation: use the ``operation-table-details`` screen
+
+``Actions``:
+ * confirm operation: on success will be redirected to the ``transaction-details`` screen where the detail of the current transaction will be displayed
+ * review and confirm ToS: if the current selected exchange has a version of ToS that the user didn't yet accepted, use the ``accept-tos`` screen
+ * cancel: user will be redirected to ``balance``
+
+
+operation-table-details
+-----------------------
+
+``Description``: with the table it should be clear how much the operation will cost,
+the initial amount and the final amount with all the items related to the operations (like fee)
+
+``labels``: initial amount of the operation, and final amount are always shown.
+Fee should be shown as an extra row in the table if it is non-zero.
+Converted amount should be shown as an extra row if initial amount currency is not the same
+as the final amount currency.
+
+Initial amount label by operation:
+
+ * payment -> Price
+ * deposit -> Send
+ * peer-pull-credit -> Invoice
+ * peer-pull-debit -> Invoice
+ * peer-push-debit -> Send
+ * peer-push-credit -> Transfer
+ * withdrawal -> Transfer
+ * refund -> Refund
+
+
+accept-tos
+----------
+
+``Description``: this screen can be use everytime that the user is going to interact
+with an exchange. since at any moment wallet may find that ToS changed the user needs
+to be prevented from continue before reading/accepting new rules. If possible, this
+screen should be used inplace of other actions and hidden if not required (for example,
+user already accepted ToS)
+
+``Inputs``:
+ * format: allow the selection of a ToS format
+ * languange: allow the selection of a languange different from system lang
+
+``Actions``:
+ * accept tos: will mark this version as accepted in wallet core and redirect the user to the screen from where it was invoked
+ * save/print tos: will save the ToS outside of the wallet
+
+.. image:: ../screenshots/cta-accept-tos-firefox-latest.png
+
+
+Q / A
+=====
diff --git a/design-documents/054-dynamic-form.rst b/design-documents/054-dynamic-form.rst
new file mode 100644
index 00000000..6ff84d41
--- /dev/null
+++ b/design-documents/054-dynamic-form.rst
@@ -0,0 +1,201 @@
+DD 54: Dynamic Web Form
+#######################
+
+Summary
+=======
+
+This document outlines the approach for implementing a dynamic web form feature.
+
+Motivation
+==========
+
+Currently, creating a new form for a web app involves coding a new
+page with HTML, CSS, and JS. Exchange AML requires multiple forms,
+and different instances may have distinct forms based on jurisdiction.
+
+
+Requirements
+============
+
+A form consist of a layout and a set of fields.
+
+Layout requirements
+-------------------
+
+* **editable by system admin**: System admins should be able to create new forms
+ or edit current one shipped with the source.
+
+* **accesibility**: Forms should meet accessibility level AA.
+
+* **responsive**: Forms should be responsive and function on all devices.
+
+* **metadata**: Generated form information should contain enough data
+ to handle multiple form versions.
+
+Fields requirements
+-------------------
+
+* **validations**: Each field may require custom validation
+
+* **custom data type**: A field may consist of a list, string, number, or a
+ complex composite structure.
+
+
+Proposed Solutions
+==================
+
+Forms are initialized using a flexible structure defined by the
+TypeScript interface FormType<T>. This interface comprises properties
+such as value (current form data), initial (initial form data for resetting),
+readOnly (flag to disable input), onUpdate (callback on form data update),
+and computeFormState (function to derive the form state based on current data).
+
+
+.. code-block:: javascript
+
+ interface FormType<T extends object> {
+ value: Partial<T>;
+ initial?: Partial<T>;
+ readOnly?: boolean;
+ onUpdate?: (v: Partial<T>) => void;
+ computeFormState?: (v: Partial<T>) => FormState<T>;
+ }
+
+
+``T``: is the type of the result object
+``value``: is a reference to the current value of the result
+``initial``: data for resetting
+``readOnly``: when true, fields won't allow input
+``onUpdate``: notification of the result update
+``computeFormState``: compute a new state of the form based on the current value
+
+Form state have the same shape of ``T`` but every field type is ``FieldUIOptions``.
+
+Fields type can be:
+ * strings
+ * numbers
+ * boolean
+ * arrays
+ * object
+
+The field type ``AmountJson`` and ``AbsoluteTime`` are opaque since field is used as a whole.
+
+The form can be instanciated using
+
+.. code-block:: javascript
+
+ import { FormProvider } from "@gnu-taler/web-util/browser";
+
+
+Then the field component can access all the properties by the ``useField(name)`` hook,
+which will return
+
+.. code-block:: javascript
+
+ interface InputFieldHandler<Type> {
+ value: Type;
+ onChange: (s: Type) => void;
+ state: FieldUIOptions;
+ isDirty: boolean;
+ }
+
+
+``value``: the current value of the field
+``onChange``: a function to call anytime the user want to change the value
+``state``: the state of the field (hidden, error, etc..)
+``isDirty``: if the user already tried to change the value
+
+A set of common form field exist in ``@gnu-taler/web-util``:
+
+ * InputAbsoluteTime
+ * InputAmount
+ * InputArray
+ * InputFile
+ * InputText
+ * InputToggle
+
+and should be used inside a ``Form`` context.
+
+.. code-block:: javascript
+
+ function MyFormComponent():VNode {
+ return <FormProvider >
+ <InputAmount name="amount" />
+ <InputText name="subject" />
+ <button type="submit"> Confirm </button>
+ </FormProvider>
+ }
+
+
+Example
+--------
+
+Consider a form shape represented by the TypeScript type:
+
+.. code-block:: javascript
+
+ type TheFormType = {
+ name: string,
+ age: number,
+ savings: AmountJson,
+ nextBirthday: AbsoluteTime,
+ pets: string[],
+ addres: {
+ street: string,
+ city: string,
+ }
+ }
+
+An example instance of this form could be:
+
+.. code-block:: javascript
+
+ const theFormValue: TheFormType = {
+ name: "Sebastian",
+ age: 15,
+ pets: ["dog","cat"],
+ address: {
+ street: "long",
+ city: "big",
+ }
+ }
+
+
+For such a form, a valid state can be computed using a function like
+``computeFormStateBasedOnFormValues``, returning an object indicating
+the state of each field, including properties such as ``hidden``,
+``disabled``, and ``required``.
+
+
+.. code-block:: javascript
+
+ function computeFormStateBasedOnFormValues(formValues): {
+ //returning fixed state as an example
+ //the return state will be commonly be computed from the values of the form
+ return {
+ age: {
+ hidden: true,
+ },
+ pets: {
+ disabled: true,
+ elements: [{
+ disabled: false,
+ }],
+ },
+ address: {
+ street: {
+ required: true,
+ error: "the street name was not found",
+ },
+ city: {
+ required: true,
+ },
+ },
+ }
+ }
+
+
+
+
+Q / A
+=====
diff --git a/design-documents/055-wallet-problem-report.rst b/design-documents/055-wallet-problem-report.rst
new file mode 100644
index 00000000..84c6159a
--- /dev/null
+++ b/design-documents/055-wallet-problem-report.rst
@@ -0,0 +1,85 @@
+DD 55: Wallet Problem Reports
+#############################
+
+.. note::
+
+ **Status**: Early work in progress / DD number reservation.
+
+Summary
+=======
+
+This design document specifies global error reports generated/managed by wallet-core
+and rendered by the wallet UIs.
+
+Motivation
+==========
+
+Sometimes the wallet encounters issues that go beyond the scope of single transaction.
+
+Requirements
+============
+
+* problem reports must have a clear lifecycle
+* problem reports must have some type of identification that allows to
+ easily find out if a new problem report needs to be created when an
+ error happens or whether an existing one has been created
+
+Proposed Solution
+=================
+
+Report identification
+---------------------
+
+The report identifier serves multiple purposes:
+
+1. Usage as a reference in wallet-core APIs
+2. De-duplication. The report ID should allow easy identification of an already existing report for a particular problem.
+
+New wallet-core requests
+------------------------
+
+* ``listProblemReports``
+* ``acknowledgeProblemReport``: Mark a problem report as read.
+* ``deleteProblemReport``: Delete the problem report.
+
+New wallet-core notification type
+---------------------------------
+
+* ``problem-report`` to notify clients about status changes or an error report
+ (including creation!)
+
+
+Types of reports
+----------------
+
+* money lost due to the exchange stopping to offer a denomination
+* money locked behind a (long) pending refresh
+* money lost due to a permanently failing refresh
+* money lost due to expired denominations (auto-refresh wasn't done fast enough)
+* exchange changed its master public key
+* a denomination changed its info (expiration, fees)
+
+
+Definition of Done
+==================
+
+TBD.
+
+Alternatives
+============
+
+TBD.
+
+Drawbacks
+=========
+
+TBD.
+
+Discussion / Q&A
+================
+
+* When is a report amended vs a new report created?
+
+ * example: Exchange stops offering denomination D1. Later, it stops offering D2.
+ Are two reports generated or is the first report changed?
+
diff --git a/design-documents/index.rst b/design-documents/index.rst
index eba03307..454564d0 100644
--- a/design-documents/index.rst
+++ b/design-documents/index.rst
@@ -63,4 +63,8 @@ Design documents that start with "XX" are considered deprecated.
049-auth.rst
050-libeufin-nexus.rst
051-fractional-digits.rst
+ 052-libeufin-bank-2fa.rst
+ 053-wallet-ui.rst
+ 054-dynamic-form.rst
+ 055-wallet-problem-report.rst
999-template
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw-confirm.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw-confirm.png
new file mode 100644
index 00000000..11dd9db0
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw-confirm.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw.png
new file mode 100644
index 00000000..d46f0e5c
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet130-withdraw.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet133-withdraw-confirm-bank.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet133-withdraw-confirm-bank.png
new file mode 100644
index 00000000..5d7dd8cd
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-sheet133-withdraw-confirm-bank.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-view22-balances.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-view22-balances.png
new file mode 100644
index 00000000..473621e8
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/CHF/cta-withdraw-view22-balances.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirm.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirm.png
new file mode 100644
index 00000000..4441777a
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirm.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirmed.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirmed.png
new file mode 100644
index 00000000..c356eb13
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-confirmed.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-register.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-register.png
new file mode 100644
index 00000000..e7b7c1f9
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-register.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-send-money.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-send-money.png
new file mode 100644
index 00000000..788ae7ab
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-send-money.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-withdraw.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-withdraw.png
new file mode 100644
index 00000000..74e1efff
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-bank-withdraw.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw-confirm.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw-confirm.png
new file mode 100644
index 00000000..22c57d66
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw-confirm.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw.png
new file mode 100644
index 00000000..4f893fd4
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet130-withdraw.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet131-tos.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet131-tos.png
new file mode 100644
index 00000000..1aafc03e
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet131-tos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet133-withdraw-confirm-bank.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet133-withdraw-confirm-bank.png
new file mode 100644
index 00000000..94ad63b1
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-sheet133-withdraw-confirm-bank.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view10-empty-wallet.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view10-empty-wallet.png
new file mode 100644
index 00000000..a6737b9f
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view10-empty-wallet.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view22-balances.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view22-balances.png
new file mode 100644
index 00000000..bd83cb8f
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-bankIntegrated/cta-withdraw-view22-balances.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-amount.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-amount.png
new file mode 100644
index 00000000..9a51cb78
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-amount.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-1.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-1.png
new file mode 100644
index 00000000..1d9fdbfd
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-1.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-2.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-2.png
new file mode 100644
index 00000000..3ea5b9ca
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-2.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-3.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-3.png
new file mode 100644
index 00000000..c15f9a5e
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet-wireTransfer-CHF-3.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount.png
new file mode 100644
index 00000000..4db97e7c
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount2.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount2.png
new file mode 100644
index 00000000..8c0d7f2a
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-amount2.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-tos.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-tos.png
new file mode 100644
index 00000000..b71d7dcf
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-tos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF.png
new file mode 100644
index 00000000..8a467161
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF2.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF2.png
new file mode 100644
index 00000000..24bb4881
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-CHF2.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ.png
new file mode 100644
index 00000000..7423411a
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ2.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ2.png
new file mode 100644
index 00000000..80843838
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-wireTransfer-NETZ2.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-withdraw-tos.png b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-withdraw-tos.png
new file mode 100644
index 00000000..21056f08
--- /dev/null
+++ b/design-documents/wallet-screenshots/ios-wallet/withdraw-exchange/cta-withdrawExchange-sheet135-withdraw-tos.png
Binary files differ