summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2024-03-20 14:32:20 +0100
committerChristian Grothoff <christian@grothoff.org>2024-03-20 14:32:20 +0100
commitef283376590c382c5c46d9b9d551b085b14fdb4f (patch)
tree138e0aa45fb34c320283b26efaa0137b37aaa3ec
parentdef59c1ee59268688fd2a9a01691d0a9bf26c671 (diff)
parentf6dfc9b3218e582511f6352180d0af86deac25ae (diff)
downloaddocs-ef283376590c382c5c46d9b9d551b085b14fdb4f.tar.gz
docs-ef283376590c382c5c46d9b9d551b085b14fdb4f.tar.bz2
docs-ef283376590c382c5c46d9b9d551b085b14fdb4f.zip
Merge branch 'master' of git+ssh://git.taler.net/docs
-rw-r--r--.gitignore3
-rw-r--r--checklists/checklist-demo-upgrade.rst (renamed from checklist-demo-upgrade.rst)10
-rw-r--r--checklists/checklist-release.rst (renamed from checklist-release.rst)16
-rw-r--r--checklists/qa-0.10.rst233
-rw-r--r--checklists/qa-0.9.4.rst228
-rw-r--r--conf.py47
-rw-r--r--core/api-auditor.rst25
-rw-r--r--core/api-bank-conversion-info.rst26
-rw-r--r--core/api-bank-integration.rst13
-rw-r--r--core/api-bank-revenue.rst62
-rw-r--r--core/api-bank-wire.rst33
-rw-r--r--core/api-challenger.rst6
-rw-r--r--core/api-common.rst33
-rw-r--r--core/api-corebank.rst119
-rw-r--r--core/api-donau.rst27
-rw-r--r--core/api-exchange.rst318
-rw-r--r--core/api-mailbox.rst3
-rw-r--r--core/api-merchant.rst967
-rw-r--r--core/api-nonce2ecash.rst170
-rw-r--r--core/api-sync.rst6
-rw-r--r--core/api-taldir.rst2
-rw-r--r--core/index-bank-apis.rst1
-rw-r--r--core/index.rst2
-rw-r--r--core/intro-bank-apis.rst134
-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.rst196
-rw-r--r--design-documents/024-age-restriction.rst6
-rw-r--r--design-documents/031-invoicing.rst15
-rw-r--r--design-documents/035-regional-currencies.rst15
-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/046-mumimo-contracts.rst172
-rw-r--r--design-documents/053-wallet-ui.rst721
-rw-r--r--design-documents/054-dynamic-form.rst14
-rw-r--r--design-documents/055-wallet-problem-report.rst114
-rw-r--r--design-documents/index.rst1
-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
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/READE22
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/1-balance.pngbin0 -> 30910 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/10-testkudos-in-the-list.pngbin0 -> 32709 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/11-select-test-kudos.pngbin0 -> 49363 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/2-click-get-cash.pngbin0 -> 36330 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/3-click-add-exchange.pngbin0 -> 42139 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/4-input-URL.pngbin0 -> 56001 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/5-click-next.pngbin0 -> 37919 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/6-review-tos.pngbin0 -> 72501 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/7-accept-tos.pngbin0 -> 37051 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/8-confirm.pngbin0 -> 30910 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/add-exchange/9-click-get-cash.pngbin0 -> 36330 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/1-balance.pngbin0 -> 35087 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/10-balance.pngbin0 -> 47824 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/2-click-send.pngbin0 -> 47464 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/3-click-deposit.pngbin0 -> 35569 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/4-click-add-account.pngbin0 -> 54335 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/5-complete-form.pngbin0 -> 60639 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/6-click-add.pngbin0 -> 59490 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/7-confirm-deposit.pngbin0 -> 60419 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/8-show-transaction.pngbin0 -> 65622 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/deposit/9-after-deposit-confirmed.pngbin0 -> 76645 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/dev-tools.pngbin0 -> 95380 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/1-balance.pngbin0 -> 36026 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/10-confirm-transfer.pngbin0 -> 55732 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/11-show-history.pngbin0 -> 49646 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/2-click-add.pngbin0 -> 48365 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/3-input-six.pngbin0 -> 48827 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/4-click-invoice.pngbin0 -> 62019 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/5-complete-form.pngbin0 -> 64943 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/6-create-invoice.pngbin0 -> 73127 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/7-copy-qr-open-qr-page.pngbin0 -> 48070 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/8-paste-URI.pngbin0 -> 63650 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/invoice/9-click-open.pngbin0 -> 52823 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/1-load-shop.pngbin0 -> 2449960 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/10-click-article-URL.pngbin0 -> 76691 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/2-click-first-article.pngbin0 -> 83759 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/3-confirm-payment.pngbin0 -> 442385 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/4-click-refund.pngbin0 -> 101347 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/5-click-request-refund.pngbin0 -> 41768 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/6-accept-refund.pngbin0 -> 85837 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/7-click-refund-detail.pngbin0 -> 69279 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/8-show-history.pngbin0 -> 81889 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/payment/9-click-receipt.pngbin0 -> 85837 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/scan-qr-code.pngbin0 -> 36358 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/settings-developer-mode.pngbin0 -> 170233 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/settings-normal-mode.pngbin0 -> 47851 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/store-installed.pngbin0 -> 32548 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/store-payment.pngbin0 -> 28060 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/store-withdraw.pngbin0 -> 20772 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/1-initial-balance.pngbin0 -> 36311 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/10-open-URI.pngbin0 -> 51973 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/11-accept-transfer.pngbin0 -> 49787 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/12-show-history.pngbin0 -> 47985 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/2-click-send.pngbin0 -> 47235 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/3-amount-five.pngbin0 -> 47547 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/4-send-wallet.pngbin0 -> 56300 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/5-complete-form.pngbin0 -> 58617 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/6-confirm-transfer.pngbin0 -> 77092 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/7-show-history.pngbin0 -> 55329 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/8-scan-qr.pngbin0 -> 48384 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/transfer/9-paste-URI.pngbin0 -> 64510 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/10-transaction-completed.pngbin0 -> 44344 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/11-history-after-withdraw.pngbin0 -> 35260 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/2-empty-wallet.pngbin0 -> 29113 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/3-get-digital-cash.pngbin0 -> 36120 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/4-select-kudos.pngbin0 -> 47910 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/5-set-amount-five.pngbin0 -> 48389 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/6-withdraw-from-bank.pngbin0 -> 52203 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/7-review-tos.pngbin0 -> 69841 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/8-accept-tos.pngbin0 -> 50475 bytes
-rw-r--r--design-documents/wallet-screenshots/webex-wallet/withdrawal/9-confirm-withdraw.pngbin0 -> 148862 bytes
-rw-r--r--frags/apt-install-libeufin-bank.rst6
-rw-r--r--frags/apt-install-libeufin-nexus.rst6
-rw-r--r--frags/deploying-tos.rst45
-rw-r--r--frags/ebics-setup.rst63
-rw-r--r--frags/libeufin-config-cli.rst10
-rw-r--r--frags/nexus-ebics-setup.rst87
-rw-r--r--frags/regional-manual-architecture.rst48
-rw-r--r--frags/regional-manual-use.rst99
-rw-r--r--frags/regional-system-on.rst28
-rw-r--r--images/Makefile7
-rw-r--r--images/grafana-postgres-exporter.pngbin0 -> 244971 bytes
-rw-r--r--images/kuma.pngbin0 -> 244687 bytes
-rw-r--r--images/kyc-process.pdf (renamed from kyc-process.pdf)bin24633 -> 24633 bytes
-rw-r--r--images/kyc-process.png (renamed from kyc-process.png)bin44435 -> 44435 bytes
-rw-r--r--images/kyc-process.tex (renamed from kyc-process.tex)0
-rw-r--r--images/regional-arch.dot36
-rw-r--r--images/regional-arch.pngbin0 -> 117525 bytes
-rw-r--r--images/taler-monitoring-infrastructure.pngbin0 -> 85006 bytes
-rw-r--r--images/transaction-reward-states.dot11
-rw-r--r--images/uptime-kuma-edit.pngbin0 -> 116550 bytes
-rw-r--r--images/uptime-kuma-from-grafana.pngbin0 -> 345702 bytes
-rw-r--r--index.rst15
-rw-r--r--libeufin/bank-manual.rst237
-rw-r--r--libeufin/index.rst23
-rw-r--r--libeufin/nexus-manual.rst237
-rw-r--r--libeufin/regional-automated-manual.rst259
-rw-r--r--libeufin/regional-custom-manual.rst181
-rw-r--r--libeufin/regional-manual.rst482
-rw-r--r--manpages/challenger.conf.5.rst2
-rw-r--r--manpages/libeufin-bank.1.rst10
-rw-r--r--manpages/libeufin-bank.conf.5.rst24
-rw-r--r--manpages/libeufin-nexus.1.rst50
-rw-r--r--manpages/libeufin-nexus.conf.5.rst33
-rw-r--r--manpages/libeufin-sandbox.1.rst8
-rw-r--r--manpages/taler-exchange-dbinit.1.rst4
-rw-r--r--manpages/taler-exchange-offline.1.rst8
-rw-r--r--manpages/taler-merchant-depositcheck.1.rst6
-rw-r--r--manpages/taler-merchant-exchange.1.rst6
-rw-r--r--manpages/taler-merchant-setup-reserve.1.rst119
-rw-r--r--manpages/taler-merchant-webhook.1.rst6
-rw-r--r--manpages/taler-merchant-wirewatch.1.rst10
-rw-r--r--manpages/taler-wallet-cli.1.rst2
-rw-r--r--manpages/taler.conf.5.rst25
-rw-r--r--orphaned/taler-nfc-guide.rst4
-rw-r--r--screenshots/balance-list-1-ios-0.pngbin0 -> 395744 bytes
l---------screenshots/balance-list-1-ios-latest.png1
-rw-r--r--screenshots/balance-list-2-ios-0.pngbin0 -> 427641 bytes
l---------screenshots/balance-list-2-ios-latest.png1
-rw-r--r--screenshots/balance-list-android-0.pngbin0 -> 47885 bytes
l---------screenshots/balance-list-android-latest.png1
-rw-r--r--screenshots/balance-list-firefox-0.pngbin0 -> 44775 bytes
l---------screenshots/balance-list-firefox-latest.png1
-rw-r--r--screenshots/create_orders.png (renamed from libeufin/create_orders.png)bin131092 -> 131092 bytes
-rw-r--r--screenshots/cta-accept-tos-android-0.pngbin0 -> 118553 bytes
l---------screenshots/cta-accept-tos-android-latest.png1
-rw-r--r--screenshots/cta-accept-tos-firefox-0.pngbin0 -> 105184 bytes
l---------screenshots/cta-accept-tos-firefox-latest.png1
-rw-r--r--screenshots/cta-accept-tos-ios-0.pngbin0 -> 334259 bytes
l---------screenshots/cta-accept-tos-ios-latest.png1
-rw-r--r--screenshots/cta-deposit-1-ios-0.pngbin0 -> 155427 bytes
l---------screenshots/cta-deposit-1-ios-latest.png1
-rw-r--r--screenshots/cta-deposit-2-ios-0.pngbin0 -> 174391 bytes
l---------screenshots/cta-deposit-2-ios-latest.png1
-rw-r--r--screenshots/cta-deposit-android-0.pngbin0 -> 54746 bytes
l---------screenshots/cta-deposit-android-latest.png1
-rw-r--r--screenshots/cta-deposit-firefox-0.pngbin0 -> 59490 bytes
l---------screenshots/cta-deposit-firefox-latest.png1
-rw-r--r--screenshots/cta-payment-android-0.pngbin0 -> 59747 bytes
l---------screenshots/cta-payment-android-latest.png1
-rw-r--r--screenshots/cta-payment-firefox-0.pngbin0 -> 43899 bytes
l---------screenshots/cta-payment-firefox-latest.png1
-rw-r--r--screenshots/cta-payment-ios-0.pngbin0 -> 198398 bytes
l---------screenshots/cta-payment-ios-latest.png1
-rw-r--r--screenshots/cta-payment-paid-1-ios-0.pngbin0 -> 197183 bytes
l---------screenshots/cta-payment-paid-1-ios-latest.png1
-rw-r--r--screenshots/cta-payment-paid-2-ios-0.pngbin0 -> 294874 bytes
l---------screenshots/cta-payment-paid-2-ios-latest.png1
-rw-r--r--screenshots/cta-payment-paid-android-0.pngbin0 -> 55338 bytes
l---------screenshots/cta-payment-paid-android-latest.png1
-rw-r--r--screenshots/cta-payment-paid-firefox-0.pngbin0 -> 36529 bytes
l---------screenshots/cta-payment-paid-firefox-latest.png1
-rw-r--r--screenshots/cta-peer-pull-initiate-android-0.pngbin0 -> 54340 bytes
l---------screenshots/cta-peer-pull-initiate-android-latest.png1
-rw-r--r--screenshots/cta-peer-pull-initiate-firefox-0.pngbin0 -> 62019 bytes
l---------screenshots/cta-peer-pull-initiate-firefox-latest.png1
-rw-r--r--screenshots/cta-peer-pull-initiate-ios-0.pngbin0 -> 186311 bytes
l---------screenshots/cta-peer-pull-initiate-ios-latest.png1
-rw-r--r--screenshots/cta-peer-push-initiate-android-0.pngbin0 -> 50363 bytes
l---------screenshots/cta-peer-push-initiate-android-latest.png1
-rw-r--r--screenshots/cta-peer-push-initiate-firefox-0.pngbin0 -> 56300 bytes
l---------screenshots/cta-peer-push-initiate-firefox-latest.png1
-rw-r--r--screenshots/cta-peer-push-initiate-ios-0.pngbin0 -> 176120 bytes
l---------screenshots/cta-peer-push-initiate-ios-latest.png1
-rw-r--r--screenshots/cta-url-entry-1-android-0.pngbin0 -> 87037 bytes
l---------screenshots/cta-url-entry-1-android-latest.png1
-rw-r--r--screenshots/cta-url-entry-2-android-0.pngbin0 -> 23916 bytes
l---------screenshots/cta-url-entry-2-android-latest.png1
-rw-r--r--screenshots/cta-url-entry-firefox-0.pngbin0 -> 37619 bytes
l---------screenshots/cta-url-entry-firefox-latest.png1
-rw-r--r--screenshots/cta-wire-transfer-1-android-0.pngbin0 -> 68795 bytes
l---------screenshots/cta-wire-transfer-1-android-latest.png1
-rw-r--r--screenshots/cta-wire-transfer-1-ios-0.pngbin0 -> 292949 bytes
l---------screenshots/cta-wire-transfer-1-ios-latest.png1
-rw-r--r--screenshots/cta-wire-transfer-2-android-0.pngbin0 -> 60355 bytes
l---------screenshots/cta-wire-transfer-2-android-latest.png1
-rw-r--r--screenshots/cta-wire-transfer-2-ios-0.pngbin0 -> 407510 bytes
l---------screenshots/cta-wire-transfer-2-ios-latest.png1
-rw-r--r--screenshots/cta-wire-transfer-3-ios-0.pngbin0 -> 331196 bytes
l---------screenshots/cta-wire-transfer-3-ios-latest.png1
-rw-r--r--screenshots/cta-wire-transfer-firefox-0.pngbin0 -> 75735 bytes
l---------screenshots/cta-wire-transfer-firefox-latest.png1
-rw-r--r--screenshots/cta-withdraw-1-android-0.pngbin0 -> 42897 bytes
l---------screenshots/cta-withdraw-1-android-latest.png1
-rw-r--r--screenshots/cta-withdraw-2-android-0.pngbin0 -> 43977 bytes
l---------screenshots/cta-withdraw-2-android-latest.png1
-rw-r--r--screenshots/cta-withdraw-done-android-0.pngbin0 -> 44643 bytes
l---------screenshots/cta-withdraw-done-android-latest.png1
-rw-r--r--screenshots/cta-withdraw-done-firefox-0.pngbin0 -> 30061 bytes
l---------screenshots/cta-withdraw-done-firefox-latest.png1
-rw-r--r--screenshots/cta-withdraw-done-ios-0.pngbin0 -> 310883 bytes
l---------screenshots/cta-withdraw-done-ios-latest.png1
-rw-r--r--screenshots/cta-withdraw-firefox-0.pngbin0 -> 35550 bytes
-rw-r--r--screenshots/cta-withdraw-firefox-1.pngbin0 -> 50475 bytes
l---------screenshots/cta-withdraw-firefox-latest.png1
-rw-r--r--screenshots/cta-withdraw-ios-0.pngbin0 -> 193455 bytes
l---------screenshots/cta-withdraw-ios-latest.png1
-rw-r--r--screenshots/enter_instance_details.png (renamed from libeufin/enter_instance_details.png)bin63262 -> 63262 bytes
-rw-r--r--screenshots/instance_iban_config.png (renamed from libeufin/instance_iban_config.png)bin59170 -> 59170 bytes
-rw-r--r--screenshots/merchant_first_login.png (renamed from libeufin/merchant_first_login.png)bin201140 -> 201140 bytes
-rw-r--r--screenshots/no_default_account_yet.png (renamed from libeufin/no_default_account_yet.png)bin54464 -> 54464 bytes
-rw-r--r--screenshots/payment_links.png (renamed from libeufin/payment_links.png)bin227921 -> 227921 bytes
-rw-r--r--screenshots/transaction-list-android-0.pngbin0 -> 83906 bytes
l---------screenshots/transaction-list-android-latest.png1
-rw-r--r--screenshots/transaction-list-firefox-0.pngbin0 -> 47985 bytes
l---------screenshots/transaction-list-firefox-latest.png1
-rw-r--r--screenshots/transaction-list-ios-0.pngbin0 -> 474321 bytes
l---------screenshots/transaction-list-ios-latest.png1
-rw-r--r--taler-auditor-manual.rst9
-rw-r--r--taler-challenger-manual.rst168
-rw-r--r--taler-developer-manual.rst131
-rw-r--r--taler-exchange-manual.rst751
-rw-r--r--taler-merchant-api-tutorial.rst75
-rw-r--r--taler-merchant-manual.rst428
-rw-r--r--taler-merchant-pos-terminal.rst45
-rw-r--r--taler-monitoring-infrastructure.rst197
-rw-r--r--taler-user-guide.rst187
-rw-r--r--taler-wallet.rst114
-rw-r--r--wallet/wallet-core.md518
285 files changed, 5708 insertions, 3106 deletions
diff --git a/.gitignore b/.gitignore
index 7dab94e6..03767229 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,6 @@ images/deposit.png
images/reserve.png
*.png
texinfo/
+
+!/design-documents/wallet-screenshots/**/*.png
+!/screenshots/*.png
diff --git a/checklist-demo-upgrade.rst b/checklists/checklist-demo-upgrade.rst
index c45c1847..d8724030 100644
--- a/checklist-demo-upgrade.rst
+++ b/checklists/checklist-demo-upgrade.rst
@@ -136,7 +136,6 @@ Merchant SPA
- |democheck| edit template to add TOTP device, set price to fixed, summary to be entered
- |democheck| scan template QR code, edit summary and pay
- |democheck| check displayed TOTP code matches TOTP app
-- |democheck| create reserve for rewards
- |democheck| do manual wire transfer in bank to establish reserve funding
- |democheck| check that partially refunded order is marked as awaiting wire transfer
- |democheck| check bank wired funds to merchant (if needed, wait)
@@ -148,14 +147,6 @@ Merchant SPA
- |democheck| check that orders are marked as completed
-Survey/Rewards
-^^^^^^^^^^^^^^
-
-- |democheck| Visit https://survey.demo.taler.net/ and receive a reward.
-- |democheck| Verify that the survey stats page (https://survey.demo.taler.net/survey-stats) is working,
- and that the survey reserve has sufficient funds.
-
-
P2P payments
^^^^^^^^^^^^
@@ -180,4 +171,3 @@ Shutdown
- |democheck| enter bank account (if possible)
- |democheck| wallet balance goes to zero
- |democheck| specified bank account receives remaining balance
-
diff --git a/checklist-release.rst b/checklists/checklist-release.rst
index a51c165d..eaefd0b9 100644
--- a/checklist-release.rst
+++ b/checklists/checklist-release.rst
@@ -17,7 +17,7 @@ For exchange:
- |releasecheck| make dist for release
- |releasecheck| verify dist builds from source
- |releasecheck| upgrade 'demo.taler.net'
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| tag repo.
- |releasecheck| use 'deployment.git/packaging/\*-docker/' to build Debian and Ubuntu packages
- |releasecheck| upload packages to 'deb.taler.net' (note: only Florian/Christian can sign)
@@ -36,7 +36,7 @@ For merchant (C backend):
- |releasecheck| make dist for release.
- |releasecheck| verify dist builds from source
- |releasecheck| upgrade 'demo.taler.net'
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| tag repo.
- |releasecheck| use 'deployment.git/packaging/\*-docker/' to build Debian and Ubuntu packages
- |releasecheck| upload packages to 'deb.taler.net' (note: only Florian/Christian can sign)
@@ -54,7 +54,7 @@ For sync:
- |releasecheck| make dist for release
- |releasecheck| verify dist builds from source
- |releasecheck| upgrade 'demo.taler.net'
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| tag repo.
- |releasecheck| use 'deployment.git/packaging/\*-docker/' to build Debian and Ubuntu packages
- |releasecheck| upload packages to 'deb.taler.net' (note: only Florian/Christian can sign)
@@ -83,7 +83,7 @@ For taler-twister:
- |releasecheck| make dist for release.
- |releasecheck| verify dist builds from source
- |releasecheck| upgrade 'demo.taler.net'
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| tag repo.
- |releasecheck| Upload triplet to ftp-upload.gnu.org/incoming/ftp or /incoming/alpha
@@ -92,7 +92,7 @@ For libeufin:
- |releasecheck| update SPA of bank
- |releasecheck| build libeufin
- |releasecheck| upgrade 'demo.taler.net'
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| make dist for release.
- |releasecheck| verify dist builds from source
- |releasecheck| tag repo.
@@ -104,7 +104,7 @@ For libeufin:
For Python merchant frontend:
- |releasecheck| upgrade 'demo.taler.net'
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| change 'demo.taler.net' deployment to use new tag.
Wallet-core:
@@ -122,14 +122,14 @@ Wallet-core:
Android-Wallet:
- |releasecheck| build wallet
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| tag repo.
- |releasecheck| upload new wallet release to app store
Webextension-Wallet:
- |releasecheck| build wallet
-- |releasecheck| run :doc:`demo upgrade checklist <checklist-demo-upgrade>`
+- |releasecheck| run :doc:`demo upgrade checklist </checklists/checklist-demo-upgrade>`
- |releasecheck| tag repo.
- |releasecheck| upload new wallet release to app store
diff --git a/checklists/qa-0.10.rst b/checklists/qa-0.10.rst
new file mode 100644
index 00000000..262f44f5
--- /dev/null
+++ b/checklists/qa-0.10.rst
@@ -0,0 +1,233 @@
+Taler 0.9.4 QA Plan
+-------------------
+
+Wallet Platforms
+^^^^^^^^^^^^^^^^
+
+Platforms listed here are the officially supported platforms for this release.
+
+* Overview / Installation Page
+
+ * https://taler.net/en/wallet.html
+
+* Android
+
+ * Google Play: https://play.google.com/store/apps/details?id=net.taler.wallet
+ * F-Droid: https://f-droid.org/en/packages/net.taler.wallet.fdroid/
+ * APK Download: TBD
+
+* Browser
+
+ * Chrome: https://chromewebstore.google.com/detail/gnu-taler-wallet/millncjiddlpgdmkklmhfadpacifaonc
+ * Firefox: https://addons.mozilla.org/en-US/firefox/addon/taler-wallet/
+
+* iOS
+
+
+Running Deployments
+^^^^^^^^^^^^^^^^^^^
+
+These deployments are maintained by us and should work for the release:
+
+* Sandcastle-based:
+
+ * demo.taler.net
+
+ * test.taler.net
+
+* Regio-based:
+
+ * regio-taler.fdold.eu
+
+
+Wallet Flows
+^^^^^^^^^^^^
+
+* Bank-integrated withdrawal
+
+ * webext: "Continue with Mobile Wallet" flow
+
+* Manual withdrawal
+
+ * ``taler://withdraw-exchange`` flow
+
+ * Currency conversion withdrawal
+
+* Peer push payments ("Send Money")
+
+* Peer pull payments ("Receive Money")
+
+* Deposit into bank account
+
+ * Check that deposit arrived
+
+* Payment at merchant
+
+ * on blog merchant
+ * on survey
+ * directly initiated via merchant SPA
+ * webext: "Pay with Mobile Wallet" flow
+
+* Pay templates
+
+ * Payment TOTP codes
+
+* Exchange management
+
+ * Reloading exchange keys
+ * Deleting an exchange
+
+* Offline handling
+
+ * Check error messages for other flows when internet connectivity
+ is bad or device is completely offline.
+
+
+libeufin-bank Flows
+^^^^^^^^^^^^^^^^^^^
+
+* Admin functionality
+
+ * Login
+
+ * Credential change
+
+ * Conversion settings
+
+ * Bank account creation
+
+ * Test transfers
+
+* Normal account functionality
+
+ * Transfers
+
+ * Transfer to the exchange should bounce
+
+ * Withdrawals
+
+ * (conversion-only): Test cash-in
+
+ * (conversion-only): Test cash-out
+
+ * Lower cash-out limit enforced
+
+ * 2FA for withdrawals, cash-out
+
+
+Merchant Backend SPA Flows
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Instance creation
+
+* Simple bank account setup
+
+* Order creation
+
+ * Pay order (with short wire transfer deadline)
+
+ * Check that money from order arrive at the bank with the right subject
+
+* Extended bank account setup
+
+ * Add Taler Bank Revenue API
+
+ * Check bank transfer list (for wire transfer of previously paid+wired order)
+
+ * Check order payment status goes to "final" automatically
+
+* TOTP Device Management
+
+ * Add device
+
+ * Edit device (set new secret, export new secret as QR code)
+
+ * Delete device
+
+* Templates
+
+ * Add template
+
+ * Edit template
+
+ * Add TOTP device to template
+
+ * Edit TOTP device associated with template
+
+ * Pay template
+
+ * Check TOTP code matches
+
+ * Remove TOTP device from template
+
+ * Delete template
+
+
+
+Regio Deployment
+^^^^^^^^^^^^^^^^
+
+* Deployment Automation (deployment.git/regional-currency)
+
+ * Test with Debian bookworm
+
+ * Test with Ubuntu mantic
+
+ * Check logs for errors
+
+ * Test with telesign (SMS)
+
+ * Set up EBICS integration
+
+ * Check that ToS is configured
+
+* Deployment Functionality
+
+ * All flows of the wallet should work (see ``Wallet Flows`` above)
+
+ * All flows of libeufin-bank should work (see ``libeufin-bank Flows`` above)
+
+ * Merchant backend should work (see ``Merchant Backend SPA Flows`` above)
+
+ * Check logs
+
+
+Android Merchant PoS
+^^^^^^^^^^^^^^^^^^^^
+
+* Test against demo.taler.net
+
+
+Android Cashier App
+^^^^^^^^^^^^^^^^^^^
+
+* Test against demo.taler.net
+
+
+CI
+^^
+
+* https://buildbot.taler.net/#/waterfall
+* CI should pass
+
+
+Debian Repository
+^^^^^^^^^^^^^^^^^
+
+* Debian
+
+ * repo at https://deb.taler.net/apt/debian/
+ * supported codename(s): bookworm
+
+
+* Ubuntu:
+
+ * repo at https://deb.taler.net/apt/ubuntu/
+ * supported codename(s): mantic
+
+
+GNU Release
+^^^^^^^^^^^
+
+* Release announcement
+* FTP upload
diff --git a/checklists/qa-0.9.4.rst b/checklists/qa-0.9.4.rst
new file mode 100644
index 00000000..77e51081
--- /dev/null
+++ b/checklists/qa-0.9.4.rst
@@ -0,0 +1,228 @@
+Taler 0.9.4 QA Plan
+-------------------
+
+Wallet Platforms
+^^^^^^^^^^^^^^^^
+
+Platforms listed here are the officially supported platforms for this release.
+
+* Overview / Installation Page
+
+ * https://taler.net/en/wallet.html
+
+* Android
+
+ * Google Play: https://play.google.com/store/apps/details?id=net.taler.wallet
+ * F-Droid: https://f-droid.org/en/packages/net.taler.wallet.fdroid/
+ * APK Download: TBD
+
+* Browser
+
+ * Chrome: https://chromewebstore.google.com/detail/gnu-taler-wallet/millncjiddlpgdmkklmhfadpacifaonc
+ * Firefox: https://addons.mozilla.org/en-US/firefox/addon/taler-wallet/
+
+* iOS
+
+
+Running Deployments
+^^^^^^^^^^^^^^^^^^^
+
+These deployments are maintained by us and should work for the release:
+
+* Sandcastle-based:
+
+ * demo.taler.net
+
+ * test.taler.net
+
+* Regio-based:
+
+ * regio-taler.fdold.eu
+
+
+Wallet Flows
+^^^^^^^^^^^^
+
+* Bank-integrated withdrawal
+
+ * webext: "Continue with Mobile Wallet" flow
+
+* Manual withdrawal
+
+ * ``taler://withdraw-exchange`` flow
+
+ * Currency conversion withdrawal
+
+* Peer push payments ("Send Money")
+
+* Peer pull payments ("Receive Money")
+
+* Deposit into bank account
+
+ * Check that deposit arrived
+
+* Payment at merchant
+
+ * on blog merchant
+ * on survey
+ * directly initiated via merchant SPA
+ * webext: "Pay with Mobile Wallet" flow
+
+* Pay templates
+
+ * Payment TOTP codes
+
+* Exchange management
+
+ * Reloading exchange keys
+ * Deleting an exchange
+
+
+libeufin-bank Flows
+^^^^^^^^^^^^^^^^^^^
+
+* Admin functionality
+
+ * Login
+
+ * Credential change
+
+ * Conversion settings
+
+ * Bank account creation
+
+ * Test transfers
+
+* Normal account functionality
+
+ * Transfers
+
+ * Transfer to the exchange should bounce
+
+ * Withdrawals
+
+ * (conversion-only): Test cash-in
+
+ * (conversion-only): Test cash-out
+
+ * Lower cash-out limit enforced
+
+ * 2FA for withdrawals, cash-out
+
+
+Merchant Backend SPA Flows
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+* Instance creation
+
+* Simple bank account setup
+
+* Order creation
+
+ * Pay order (with short wire transfer deadline)
+
+ * Check that money from order arrive at the bank with the right subject
+
+* Extended bank account setup
+
+ * Add Taler Bank Revenue API
+
+ * Check bank transfer list (for wire transfer of previously paid+wired order)
+
+ * Check order payment status goes to "final" automatically
+
+* TOTP Device Management
+
+ * Add device
+
+ * Edit device (set new secret, export new secret as QR code)
+
+ * Delete device
+
+* Templates
+
+ * Add template
+
+ * Edit template
+
+ * Add TOTP device to template
+
+ * Edit TOTP device associated with template
+
+ * Pay template
+
+ * Check TOTP code matches
+
+ * Remove TOTP device from template
+
+ * Delete template
+
+
+
+Regio Deployment
+^^^^^^^^^^^^^^^^
+
+* Deployment Automation (deployment.git/regional-currency)
+
+ * Test with Debian bookworm
+
+ * Test with Ubuntu mantic
+
+ * Check logs for errors
+
+ * Test with telesign (SMS)
+
+ * Set up EBICS integration
+
+ * Check that ToS is configured
+
+* Deployment Functionality
+
+ * All flows of the wallet should work (see ``Wallet Flows`` above)
+
+ * All flows of libeufin-bank should work (see ``libeufin-bank Flows`` above)
+
+ * Merchant backend should work (see ``Merchant Backend SPA Flows`` above)
+
+ * Check logs
+
+
+Android Merchant PoS
+^^^^^^^^^^^^^^^^^^^^
+
+* Test against demo.taler.net
+
+
+Android Cashier App
+^^^^^^^^^^^^^^^^^^^
+
+* Test against demo.taler.net
+
+
+CI
+^^
+
+* https://buildbot.taler.net/#/waterfall
+* CI should pass
+
+
+Debian Repository
+^^^^^^^^^^^^^^^^^
+
+* Debian
+
+ * repo at https://deb.taler.net/apt/debian/
+ * supported codename(s): bookworm
+
+
+* Ubuntu:
+
+ * repo at https://deb.taler.net/apt/ubuntu/
+ * supported codename(s): mantic
+
+
+GNU Release
+^^^^^^^^^^^
+
+* Release announcement
+* FTP upload
diff --git a/conf.py b/conf.py
index 1aae2c40..db8a4069 100644
--- a/conf.py
+++ b/conf.py
@@ -78,7 +78,7 @@ master_doc = "index"
# General information about the project.
project = "GNU Taler"
-copyright = "2014-2022 Taler Systems SA (GPLv3+ or GFDL 1.3+)"
+copyright = "2014-2024 Taler Systems SA (GPLv3+ or GFDL 1.3+)"
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
@@ -87,7 +87,7 @@ copyright = "2014-2022 Taler Systems SA (GPLv3+ or GFDL 1.3+)"
# The short X.Y version.
version = "0.9"
# The full version, including alpha/beta/rc tags.
-release = "0.9.0"
+release = "0.9.4"
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -638,13 +638,6 @@ man_pages = [
1,
),
(
- "manpages/taler-merchant-setup-reserve.1",
- "taler-merchant-setup-reserve",
- "setup reserve for rewards at a Taler merchant backend",
- "GNU Taler contributors",
- 1,
- ),
- (
"manpages/taler-exchange-wire-gateway-client.1",
"taler-exchange-wire-gateway-client",
"trigger a transfer at the bank",
@@ -772,54 +765,54 @@ texinfo_documents = [
"taler-auditor",
"Taler Auditor Manual",
"GNU Taler team",
- "MENU ENTRY",
- "DESCRIPTION",
- "CATEGORY",
+ "GNU Taler Auditor",
+ "External audit for Taler Exchange operation",
+ "Network applications",
),
(
"taler-exchange-manual",
"taler-exchange",
"Taler Exchange Manual",
"GNU Taler team",
- "MENU ENTRY",
- "DESCRIPTION",
- "CATEGORY",
+ "GNU Taler Exchange",
+ "Taler payment service provider",
+ "Network applications",
),
(
"taler-challenger-manual",
"challenger",
"Taler Challenger Manual",
"GNU Taler team",
- "MENU ENTRY",
- "DESCRIPTION",
- "CATEGORY",
+ "GNU Taler Challenger",
+ "Customer address validation service",
+ "Network applications",
),
(
"taler-merchant-manual",
"taler-merchant",
"Taler Merchant Manual",
"GNU Taler team",
- "MENU ENTRY",
- "DESCRIPTION",
- "CATEGORY",
+ "GNU Taler Merchant",
+ "Backend for merchants accepting Taler payments",
+ "Network applications",
),
(
"taler-merchant-api-tutorial",
"taler-merchant-api-tutorial",
"Taler Merchant API Tutorial",
"GNU Taler team",
- "MENU ENTRY",
- "DESCRIPTION",
- "CATEGORY",
+ "GNU Taler Merchant API",
+ "Tutorial for using the merchant backend API",
+ "Network applications",
),
(
"taler-developer-manual",
"taler-developer-manual",
"Taler Developer Manual",
"GNU Taler team",
- "MENU ENTRY",
- "DESCRIPTION",
- "CATEGORY",
+ "GNU Taler Development",
+ "Manual for GNU Taler contributors",
+ "Network applications",
),
]
diff --git a/core/api-auditor.rst b/core/api-auditor.rst
index 9c2416a9..61e448b8 100644
--- a/core/api-auditor.rst
+++ b/core/api-auditor.rst
@@ -25,6 +25,7 @@ The `glossary <https://docs.taler.net/glossary.html#glossary>`_
defines all specific terms used in this section.
.. contents:: Table of Contents
+ :local:
.. _authentication:
@@ -55,6 +56,7 @@ know-your-customer (KYC) registration before issuing contracts.
.. http:get:: /config
Get the protocol version and some meta data about the auditor.
+ This specification corresponds to ``current`` protocol being version **1**.
**Response:**
@@ -74,11 +76,19 @@ know-your-customer (KYC) registration before issuing contracts.
// protocol is versioned independently of the exchange's protocol.
version: string;
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v0, may become mandatory in the future.
+ implementation?: string;
+
// Return which currency this auditor is auditing for.
currency: string;
// EdDSA master public key of the auditor.
auditor_public_key: EddsaPublicKey;
+
+ // EdDSA master public key of the exchange.
+ // Added in protocol v1.
+ exchange_master_public_key: EddsaPublicKey;
}
.. note::
@@ -225,6 +235,7 @@ paid out first.
// Master public key of the exchange corresponding to ``master_sig``.
// Identifies the exchange this is about.
+ // @deprecated since v1 (now ignored, global per auditor)
master_pub: EddsaPublicKey;
// When does the validity of the exchange_pub end?
@@ -340,14 +351,14 @@ This API is used to obtain a list of all the balances that are stored by the aud
**Details:**
- .. ts:def:: Balances
+ .. ts:def:: BalanceList
interface BalanceList {
// Total amount reported
- auditor_total_reported_balance: taler_amount;
+ auditor_total_reported_balance: Amount;
// Amount potentially missing
- auditor_missing_balance: taler_amount;
+ auditor_missing_balance: Amount;
//...
}
@@ -391,16 +402,16 @@ This API is used by the auditor to obtain a list of pending denominations
interface PendingDenomination {
// Balance of denomination.
- denom_balance: taler_amount;
+ denom_balance: Amount;
// Amount that was lost due to failures by the exchange.
- denom_loss: taler_amount;
+ denom_loss: Amount;
// Amount at risk of loss due to recoup operations.
- denom_risk: taler_amount;
+ denom_risk: Amount;
// Amount actually lost due to recoup operations after a revocation.
- recoup_loss: taler_amount;
+ recoup_loss: Amount;
}
.. note::
diff --git a/core/api-bank-conversion-info.rst b/core/api-bank-conversion-info.rst
index 834cac46..322e9403 100644
--- a/core/api-bank-conversion-info.rst
+++ b/core/api-bank-conversion-info.rst
@@ -48,10 +48,14 @@ is used by wallets for withdrawals that involve a currency conversion.
// https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
// The format is "current:revision:age".
version: string;
-
+
// Name of the API.
name: "taler-conversion-info";
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v4, may become mandatory in the future.
+ implementation?: string;
+
// Currency used by this bank.
regional_currency: string;
@@ -65,9 +69,9 @@ is used by wallets for withdrawals that involve a currency conversion.
fiat_currency_specification: CurrencySpecification;
// Additional information on conversion rates.
- // Those informations should never be used to perform conversions,
+ // Those informations should never be used to perform conversions,
// use /cashin-rate or /cashout-rate instead.
- // Conversion rates can change at any time. Clients must deal with
+ // Conversion rates can change at any time. Clients must deal with
// any resulting errors and call /cashin-rate or /cashout-rate again
// to use the new rates.
conversion_rate: ConversionRate;
@@ -91,7 +95,7 @@ is used by wallets for withdrawals that involve a currency conversion.
deducted from their fiat bank account.
or
-
+
:query amount_credit: this is the amount that the user will receive
in their regional bank account.
@@ -100,7 +104,7 @@ is used by wallets for withdrawals that involve a currency conversion.
:http:statuscode:`200 OK`:
Response is a `CashinConversionResponse`.
:http:statuscode:`400 Bad request`:
- * ``TALER_EC_GENERIC_PARAMETER_MISSING`` : none of the parameters have been provided.
+ * ``TALER_EC_GENERIC_PARAMETER_MISSING`` : none of the parameters have been provided.
* ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` : both of the parameters have been provided or one of them is not a valid Taler amount.
* ``TALER_EC_GENERIC_CURRENCY_MISMATCH`` : the parameter is in the wrong currency.
:http:statuscode:`409 Conflict`:
@@ -137,7 +141,7 @@ is used by wallets for withdrawals that involve a currency conversion.
deducted from their regional bank account.
or
-
+
:query amount_credit: this is the amount that the user will receive
in their fiat bank account.
@@ -146,7 +150,7 @@ is used by wallets for withdrawals that involve a currency conversion.
:http:statuscode:`200 OK`:
Response is a `CashoutConversionResponse`.
:http:statuscode:`400 Bad request`:
- * ``TALER_EC_GENERIC_PARAMETER_MISSING`` : none of the parameters have been provided.
+ * ``TALER_EC_GENERIC_PARAMETER_MISSING`` : none of the parameters have been provided.
* ``TALER_EC_GENERIC_PARAMETER_MALFORMED`` : both of the parameters have been provided or one of them is not a valid Taler amount.
* ``TALER_EC_GENERIC_CURRENCY_MISMATCH`` : the parameter is in the wrong currency.
:http:statuscode:`409 Conflict`:
@@ -169,17 +173,17 @@ is used by wallets for withdrawals that involve a currency conversion.
.. http:post:: /conversion-rate
- This endpoint allows the administrator to update
+ This endpoint allows the administrator to update
the exchange rate between the regional currency
and the fiat currency of the banking system.
**Request:**
.. ts:def:: ConversionRate
-
+
interface ConversionRate {
// Exchange rate to buy regional currency from fiat
- cashin_ratio: DecimalNumber;
+ cashin_ratio: DecimalNumber;
// Regional amount fee to subtract after applying the cashin ratio.
cashin_fee: Amount;
@@ -194,7 +198,7 @@ is used by wallets for withdrawals that involve a currency conversion.
cashin_rounding_mode: "zero" | "up" | "nearest";
// Exchange rate to sell regional currency for fiat
- cashout_ratio: DecimalNumber;
+ cashout_ratio: DecimalNumber;
// Fiat amount fee to subtract after applying the cashout ratio.
cashout_fee: Amount;
diff --git a/core/api-bank-integration.rst b/core/api-bank-integration.rst
index 598ad82f..4131a28a 100644
--- a/core/api-bank-integration.rst
+++ b/core/api-bank-integration.rst
@@ -50,6 +50,10 @@ to tightly integrate with GNU Taler.
// The format is "current:revision:age".
version: string;
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v2, may become mandatory in the future.
+ implementation?: string;
+
// Currency used by this bank.
currency: string;
@@ -115,6 +119,7 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
// URL that the user needs to navigate to in order to
// complete some final confirmation (e.g. 2FA).
+ // Only applicable when ``status`` is ``selected`` or ``pending``.
// It may contain withdrawal operation id
confirm_transfer_url?: string;
@@ -169,7 +174,7 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
:http:statuscode:`404 Not found`:
The bank does not know about a withdrawal operation with the specified ``WITHDRAWAL_ID``.
:http:statuscode:`409 Conflict`:
- * ``TALER_EC_BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT`` :
+ * ``TALER_EC_BANK_WITHDRAWAL_OPERATION_RESERVE_SELECTION_CONFLICT`` :
The wallet selected a different exchange or reserve public key under the same withdrawal ID.
* ``TALER_EC_BANK_DUPLICATE_RESERVE_PUB_SUBJECT`` : the reserve public key is already used.
* ``TALER_EC_BANK_UNKNOWN_ACCOUNT`` : the selected exchange account was not found.
@@ -190,7 +195,7 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
// URL that the user needs to navigate to in order to
// complete some final confirmation (e.g. 2FA).
//
- // Only applicable when ``status`` is ``selected``.
+ // Only applicable when ``status`` is ``selected`` or ``pending``.
// It may contain withdrawal operation id
confirm_transfer_url?: string;
@@ -208,9 +213,9 @@ for the withdrawal operation (the ``WITHDRAWAL_ID``) to interact with the withdr
**Response:**
- :http:statuscode:`204 No content`:
+ :http:statuscode:`204 No content`:
The withdrawal operation has been aborted.
:http:statuscode:`404 Not found`:
The withdrawal operation was not found.
- :http:statuscode:`409 Conflict`:
+ :http:statuscode:`409 Conflict`:
The withdrawal operation has been confirmed previously and can't be aborted.
diff --git a/core/api-bank-revenue.rst b/core/api-bank-revenue.rst
index 05daa40b..98b38113 100644
--- a/core/api-bank-revenue.rst
+++ b/core/api-bank-revenue.rst
@@ -22,6 +22,38 @@ Taler Bank Revenue HTTP API
This section describes an API offered by libeufin-nexus and libeufin-bank. The API is
used by the merchant (or other parties) to query for incoming transactions to their account.
+.. http:get:: /config
+
+ Return the protocol version and configuration information about the bank.
+ This specification corresponds to ``current`` protocol being version **0**.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The exchange responds with a `RevenueConfig` object. This request should
+ virtually always be successful.
+
+ **Details:**
+
+ .. ts:def:: RevenueConfig
+
+ interface RevenueConfig {
+ // Name of the API.
+ name: "taler-revenue";
+
+ // libtool-style representation of the Bank protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+
+ // Currency used by this gateway.
+ currency: string;
+
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v0, may become mandatory in the future.
+ implementation?: string;
+ }
+
--------------
Authentication
@@ -36,14 +68,9 @@ Querying the transaction history
.. http:get:: /history
- Return a list of transactions made from an exchange to the merchant.
-
- Incoming transactions must contain a valid wire transfer identifier and
- exchange base URL. If a bank transaction does not conform to the right
- syntax, the wire gateway must not report it to the merchant via this
- endpoint.
+ Return a list of transactions made to an account.
- The bank account of the merchant is determined via the base URL and/or the
+ The bank account is determined via the base URL and/or the
user name in the ``Authorization`` header. In fact, the transaction history
might come from a "virtual" account, where multiple real bank accounts are
merged into one history.
@@ -83,7 +110,7 @@ Querying the transaction history
**Response:**
:http:statuscode:`200 OK`:
- JSON object of type `MerchantIncomingHistory`.
+ JSON object of type `RevenueIncomingHistory`.
:http:statuscode:`400 Bad request`:
Request malformed. The bank replies with an `ErrorDetail` object.
:http:statuscode:`401 Unauthorized`:
@@ -93,23 +120,21 @@ Querying the transaction history
**Details:**
- .. ts:def:: MerchantIncomingHistory
+ .. ts:def:: RevenueIncomingHistory
- interface MerchantIncomingHistory {
+ interface RevenueIncomingHistory {
// Array of incoming transactions.
- incoming_transactions : MerchantIncomingBankTransaction[];
+ incoming_transactions : RevenueIncomingBankTransaction[];
// Payto URI to identify the receiver of funds.
- // This must be one of the merchant's bank accounts.
// Credit account is shared by all incoming transactions
// as per the nature of the request.
credit_account: string;
-
}
- .. ts:def:: MerchantIncomingBankTransaction
+ .. ts:def:: RevenueIncomingBankTransaction
- interface MerchantIncomingBankTransaction {
+ interface RevenueIncomingBankTransaction {
// Opaque identifier of the returned record.
row_id: SafeUint64;
@@ -122,9 +147,6 @@ Querying the transaction history
// Payto URI to identify the sender of funds.
debit_account: string;
- // Base URL of the exchange where the transfer originated form.
- exchange_url: string;
-
- // The wire transfer identifier.
- wtid: WireTransferIdentifierRawP;
+ // The wire transfer subject.
+ subject: string;
}
diff --git a/core/api-bank-wire.rst b/core/api-bank-wire.rst
index 86422626..a76f5195 100644
--- a/core/api-bank-wire.rst
+++ b/core/api-bank-wire.rst
@@ -13,6 +13,8 @@
You should have received a copy of the GNU Affero General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+.. _taler-wire-gateway-http-api:
+
===========================
Taler Wire Gateway HTTP API
===========================
@@ -24,6 +26,37 @@ well as by the auditor to query incoming and outgoing transactions.
This API is currently implemented by the Taler Demo Bank, as well as by
LibEuFin (work in progress).
+.. http:get:: /config
+
+ Return the protocol version and configuration information about the bank.
+ This specification corresponds to ``current`` protocol being version **0**.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The exchange responds with a `WireConfig` object. This request should
+ virtually always be successful.
+
+ **Details:**
+
+ .. ts:def:: WireConfig
+
+ interface WireConfig {
+ // Name of the API.
+ name: "taler-wire-gateway";
+
+ // libtool-style representation of the Bank protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+
+ // Currency used by this gateway.
+ currency: string;
+
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v0, may become mandatory in the future.
+ implementation?: string;
+ }
--------------
Authentication
diff --git a/core/api-challenger.rst b/core/api-challenger.rst
index 00035c52..914d8d01 100644
--- a/core/api-challenger.rst
+++ b/core/api-challenger.rst
@@ -88,6 +88,7 @@ Using the ``/info`` endpoint the client can then finally obtain the (now)
verified address of the user.
.. contents:: Table of Contents
+ :local:
.. include:: tos.rst
@@ -98,6 +99,7 @@ Receiving Configuration
.. http:get:: /config
Obtain the key configuration settings of the storage service.
+ This specification corresponds to ``current`` protocol being version **0**.
**Response:**
@@ -114,6 +116,10 @@ Receiving Configuration
// The format is "current:revision:age".
version: string;
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v0, may become mandatory in the future.
+ implementation?: string;
+
}
.. _challenger-setup:
diff --git a/core/api-common.rst b/core/api-common.rst
index 7e342cb0..6d023b16 100644
--- a/core/api-common.rst
+++ b/core/api-common.rst
@@ -24,6 +24,8 @@
Conventions for Taler RESTful APIs
==================================
+.. contents:: Table of Contents
+ :local:
-------------------------
HTTP Request and Response
@@ -352,6 +354,14 @@ Integers
// JavaScript numbers restricted to integers.
type Integer = number;
+Floats
+^^^^^^
+
+.. ts:def:: Float
+
+ // JavaScript numbers.
+ type Float = number;
+
Ages
^^^^
@@ -543,7 +553,7 @@ Blinded coin
// coin's `public EdDSA key <eddsa-coin-pub>`.
interface RSACoinEnvelope {
cipher: "RSA" | "RSA+age_restricted";
- rsa_blinded_planchet: string; // Crockford `Base32` encoded
+ rsa_blinded_planchet: BlindedRsaSignature;
}
.. ts:def:: CSCoinEnvelope
@@ -567,6 +577,25 @@ Blinded coin
type DenominationBlindingKeyP = string;
+. _unblinded-coin:
+
+Unblinded coin
+^^^^^^^^^^^^^^
+
+.. ts:def:: UnblindedSignature
+
+ // The type of a coin's unblinded signature depends on the cipher that was used
+ // for signing with a denomination key.
+ // Note that for now, only RSA is supported.
+ type UnblindedSignature = RsaUnblindedSignature;
+
+.. ts:def:: RsaUnblindedSignature
+
+ interface RsaUnblindedSignature {
+ cipher: "RSA";
+ rsa_signature: RsaSignature;
+ }
+
.. _signature:
@@ -1024,7 +1053,7 @@ within the
};
-.. _TALER_DepositRequestPS:
+.. _taler_depositrequestps:
.. sourcecode:: c
diff --git a/core/api-corebank.rst b/core/api-corebank.rst
index 87c4f969..afab932c 100644
--- a/core/api-corebank.rst
+++ b/core/api-corebank.rst
@@ -1,7 +1,7 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014-2023 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -23,6 +23,7 @@ Taler Core Bank API
====================
.. contents:: Table of Contents
+ :local:
Introduction
------------
@@ -66,7 +67,7 @@ Config
**Response:**
- :http:statuscode:`200 OK`:
+ :http:statuscode:`200 OK`:
Response is a `Config`.
**Details:**
@@ -82,11 +83,16 @@ Config
// The format is "current:revision:age".
version: string;
+ // Bank display name to be used in user interfaces.
+ // For consistency use "Taler Bank" if missing.
+ // @since v4, will become mandatory in the next version.
+ bank_name?: string;
+
// If 'true' the server provides local currency conversion support
// If 'false' some parts of the API are not supported and return 501
allow_conversion: boolean;
- // If 'true' anyone can register
+ // If 'true' anyone can register
// If 'false' only admin can
allow_registrations: boolean;
@@ -104,7 +110,7 @@ Config
// Default debt limit for newly created accounts
default_debit_threshold: Amount;
-
+
// Currency used by this bank.
currency: string;
@@ -113,6 +119,11 @@ Config
// TAN channels supported by the server
supported_tan_channels: TanChannel[];
+
+ // Wire transfer type supported by the bank.
+ // Default to 'iban' is missing
+ // @since v4, will become mandatory in the next version.
+ wire_type?: string;
}
@@ -156,7 +167,7 @@ Account Management
// Addresses where to send the TAN for protected operations.
contact_data?: ChallengeContactData;
- // 'payto' URI of a fiat bank account with a 'receiver-name' parameter.
+ // IBAN 'payto' URI of a fiat bank account with a 'receiver-name' parameter.
// If 'receiver-name' is missing, ``name`` will be used instead.
// Payments will be sent to this bank account
// when the user wants to convert the regional currency
@@ -164,7 +175,8 @@ Account Management
cashout_payto_uri?: string;
// Internal payto URI of this bank account.
- // Used mostly for testing.
+ // Used mostly for testing, this field is ignored if the bank payment
+ // method is not IBAN.
payto_uri?: string;
// If present, set the max debit allowed for this user
@@ -252,7 +264,7 @@ Account Management
// Addresses where to send the TAN for protected operations.
contact_data?: ChallengeContactData;
- // 'payto' URI of a fiat bank account with a 'receiver-name' parameter.
+ // IBAN 'payto' URI of a fiat bank account with a 'receiver-name' parameter.
// If 'receiver-name' is missing, ``name`` will be used instead.
// Payments will be sent to this bank account
// when the user wants to convert the regional currency
@@ -298,7 +310,7 @@ Account Management
.. http:patch:: /accounts/$USERNAME/auth
Allows changing the account's password.
-
+
**Request:**
@@ -332,13 +344,13 @@ Account Management
Show those accounts whose histories are publicly visible. For example,
accounts from donation receivers. As such, this request is unauthenticated.
-
+
**Request:**
:query delta: *Optional.*
Takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries.
- :query start: *Optional.*
+ :query start: *Optional.*
Row number threshold, see ``delta`` for its interpretation. Defaults to smallest or biggest row id possible according to ``delta`` sign.
:query filter_name: *Optional.*
Pattern to filter on the account legal name. Given
@@ -375,6 +387,10 @@ Account Management
// Is this a taler exchange account?
is_taler_exchange: boolean;
+
+ // Opaque unique ID used for pagination.
+ // @since v4, will become mandatory in the next version.
+ row_id?: Integer;
}
.. http:get:: /accounts
@@ -388,7 +404,7 @@ Account Management
:query delta: *Optional.*
Takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries.
- :query start: *Optional.*
+ :query start: *Optional.*
Row number threshold, see ``delta`` for its interpretation. Defaults to smallest or biggest row id possible according to ``delta`` sign.
:query filter_name: *Optional.*
Pattern to filter on the account legal name. Given
@@ -444,6 +460,18 @@ Account Management
// Is this a taler exchange account?
is_taler_exchange: boolean;
+
+ // Opaque unique ID used for pagination.
+ // @since v4, will become mandatory in the next version.
+ row_id?: Integer;
+
+ // Current status of the account
+ // active: the account can be used
+ // deleted: the account has been deleted but is retained for compliance
+ // reasons, only the administrator can access it
+ // Default to 'active' is missing
+ // @since v4, will become mandatory in the next version.
+ status?: "active" | "deleted";
}
.. _bank-account-info:
@@ -487,8 +515,8 @@ Account Management
// as well.
contact_data?: ChallengeContactData;
- // 'payto' URI pointing the bank account
- // where to send cashouts. This field is optional
+ // IBAN 'payto' URI with a 'receiver-name' parameter of a fiat bank
+ // account where to send cashouts. This field is optional
// because not all the accounts are required to participate
// in the merchants' circuit. One example is the exchange:
// that never cashouts. Registering these accounts can
@@ -531,7 +559,7 @@ Transactions
:query delta: *Optional.*
Takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries.
- :query start: *Optional.*
+ :query start: *Optional.*
Row number threshold, see ``delta`` for its interpretation. Defaults to smallest or biggest row id possible according to ``delta`` sign.
:query long_poll_ms: Optional number to express how many milliseconds the server
should wait for at least one result to be shown. If not given, the server
@@ -606,6 +634,12 @@ Transactions
// query string parameter of the 'payto' field. In case it
// is given in both places, the payto_uri's takes the precedence.
amount: string;
+
+ // Nonce to make the request idempotent. Requests with the same
+ // ``request_uid`` that differ in any of the other fields
+ // are rejected.
+ // @since v4, will become mandatory in the next version.
+ request_uid?: ShortHashCode;
}
**Response:**
@@ -624,6 +658,7 @@ Transactions
* ``TALER_EC_BANK_SAME_ACCOUNT`` : creditor account is the same than ``USERNAME``.
* ``TALER_EC_BANK_UNKNOWN_CREDITOR`` : creditor account was not found.
* ``TALER_EC_BANK_UNALLOWED_DEBIT`` : the account does not have sufficient funds.
+ * ``TALER_EC_BANK_TRANSFER_REQUEST_UID_REUSED``: an operation with the same ``request_uid`` but different details has been submitted before.
**Details:**
@@ -697,16 +732,16 @@ Taler Withdrawals
**Response:**
- :http:statuscode:`204 No content`:
+ :http:statuscode:`204 No content`:
The withdrawal operation has been aborted.
:http:statuscode:`404 Not found`:
The withdrawal operation was not found.
- :http:statuscode:`409 Conflict`:
+ :http:statuscode:`409 Conflict`:
The withdrawal operation has been confirmed previously and can't be aborted.
.. http:get:: /withdrawals/$WITHDRAWAL_ID
- Retrieve public information about ``WITHDRAWAL_ID`` withdrawal operation.
+ Retrieve public information about ``WITHDRAWAL_ID`` withdrawal operation.
Does not require further authentication as knowledge of ``WITHDRAWAL_ID``
serves as an authenticator.
@@ -811,7 +846,7 @@ Cashouts
:http:statuscode:`200 OK`:
The cashout request was correctly created.
- This returns the `CashoutPending` response.
+ This returns the `CashoutResponse` response.
:http:statuscode:`202 Accepted`:
2FA is required for this operation. This returns the `Challenge` response.
:http:statuscode:`404 Not found`:
@@ -878,7 +913,7 @@ Cashouts
:query delta: *Optional.*
Takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries.
- :query start: *Optional.*
+ :query start: *Optional.*
Row number threshold, see ``delta`` for its interpretation. Defaults to smallest or biggest row id possible according to ``delta`` sign.
**Response:**
@@ -915,7 +950,7 @@ Cashouts
:query delta: *Optional.*
Takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` are returned. Defaults to ``-20`` to return the last 20 entries.
- :query start: *Optional.*
+ :query start: *Optional.*
Row number threshold, see ``delta`` for its interpretation. Defaults to smallest or biggest row id possible according to ``delta`` sign.
.. note::
@@ -980,7 +1015,7 @@ Cashouts
// Info of the last successful transmission of the TAN challenge.
tan_info: string;
}
-
+
.. ts:def:: Challenge
interface Challenge {
@@ -988,7 +1023,7 @@ Cashouts
// operation.
challenge_id: string;
}
-
+
.. ts:def:: TanChannel
enum TanChannel {
@@ -999,7 +1034,7 @@ Cashouts
.. http:post:: /accounts/$USERNAME/challenge/$CHALLENGE_ID/confirm
- Solves the ``CHALLENGE_ID`` challenge and performs the protected operation.
+ Solves the ``CHALLENGE_ID`` challenge and allows performing the protected operation.
When the challenge is confirmed, you can call the protected endpoint again with ``CHALLENGE_ID`` in the ``X-Challenge-Id`` HTTP header and an empty request body.
@@ -1025,7 +1060,7 @@ Cashouts
* ``TALER_EC_BANK_TAN_CHALLENGE_EXPIRED`` : expired TAN.
:http:statuscode:`429 Too many requests`:
Too many failed confirmation attempts, a new TAN must be requested.
-
+
Monitor
-------
@@ -1060,7 +1095,7 @@ Monitor
**Response:**
- :http:statuscode:`200 OK`:
+ :http:statuscode:`200 OK`:
The bank responds with `MonitorResponse`.
:http:statuscode:`400 Bad Request`:
This error may indicate that the *which* parameter is not appropriate for the selected *timeframe*. For example, timeframe=month and which=20 would result in this error.
@@ -1073,7 +1108,7 @@ Monitor
factors to serve different views to their users.
.. ts:def:: MonitorResponse
-
+
// Union discriminated by the "type" field.
type MonitorResponse =
| MonitorNoConversion
@@ -1089,7 +1124,7 @@ Monitor
// bank account.
talerInCount: Integer;
- // Overall volume that has been paid to a Taler
+ // Overall volume that has been paid to a Taler
// exchange by another bank account.
talerInVolume: Amount;
@@ -1097,7 +1132,7 @@ Monitor
// bank account.
talerOutCount: Integer;
- // Overall volume that has been paid by a Taler
+ // Overall volume that has been paid by a Taler
// exchange to another bank account.
talerOutVolume: Amount;
}
@@ -1108,7 +1143,7 @@ Monitor
interface MonitorWithConversion {
type: "with-conversions";
- // How many cashin operations were confirmed by a
+ // How many cashin operations were confirmed by a
// wallet owner. Note: wallet owners
// are NOT required to be customers of the libeufin-bank.
cashinCount: Integer;
@@ -1136,7 +1171,7 @@ Monitor
// bank account.
talerInCount: Integer;
- // Overall volume that has been paid to a Taler
+ // Overall volume that has been paid to a Taler
// exchange by another bank account.
talerInVolume: Amount;
@@ -1144,14 +1179,14 @@ Monitor
// bank account.
talerOutCount: Integer;
- // Overall volume that has been paid by a Taler
+ // Overall volume that has been paid by a Taler
// exchange to another bank account.
talerOutVolume: Amount;
}
-Taler Bank Integration API
---------------------------
+Endpoints for Integrated Sub-APIs
+---------------------------------
.. http:any:: /taler-integration/*
@@ -1159,8 +1194,6 @@ Taler Bank Integration API
:doc:`GNU Taler bank integration API </core/api-bank-integration>`.
This API handles the communication with Taler wallets.
-Taler Wire Gateway API
-----------------------
.. http:any:: /accounts/$USERNAME/taler-wire-gateway/*
@@ -1169,31 +1202,25 @@ Taler Wire Gateway API
The endpoints are only available for accounts configured with ``is_taler_exchange=true``.
-Taler Revenue API
------------------
.. http:any:: /accounts/$USERNAME/taler-revenue/*
All endpoints under this prefix are specified
by the :doc:`GNU Taler Revenue API </core/api-bank-revenue>`.
-Taler Conversion Info API
--------------------------
.. http:any:: /conversion-info/*
All endpoints under this prefix are specified
by the :doc:`GNU Taler Conversion Info API </core/api-bank-conversion-info>`.
-EBICS Host
-----------
-
-The Taler bank can be configured to serve bank account transactions and allow
-payment initiations via the EBICS protocol.
-
-This is an optional feature, not all implementations of the API support it.
.. http:post:: /ebicshost
EBICS base URL. This URL allows clients to make EBICS requests to one of
the configured EBICS hosts.
+
+ The Taler bank can be configured to serve bank account transactions and
+ allow payment initiations via the EBICS protocol.
+
+ This is an optional feature, not all implementations of the API support it.
diff --git a/core/api-donau.rst b/core/api-donau.rst
index 4f3ce390..09f644ec 100644
--- a/core/api-donau.rst
+++ b/core/api-donau.rst
@@ -15,6 +15,8 @@
@author Christian Grothoff
@author Pius Loosli
+ @author Lukas Matyja
+ @author Johannes Casaburi
=====================
The Donau RESTful API
@@ -26,6 +28,7 @@ The `glossary <https://docs.taler.net/glossary.html#glossary>`_
defines all specific terms used in this section.
.. contents:: Table of Contents
+ :local:
.. _donau-overview:
@@ -67,23 +70,11 @@ long-term offline signing key of the Donau, which clients should cache.
**Request:**
- :query last_issue_date: Optional argument specifying the maximum value of
- any of the ``stamp_start`` members of the
- donation unit keys of a ``/keys`` response that is
- already known to the client. Allows the Donau to
- only return keys that have changed since that
- timestamp. The given value must be an unsigned
- 64-bit integer representing seconds after 1970. If
- the timestamp does not exactly match the
- ``stamp_start`` of one of the donation unit keys, all
- keys are returned.
-
**Response:**
:http:statuscode:`200 OK`:
The Donau responds with a `DonauKeysResponse` object. This request should
- virtually always be successful. It only fails if the Donau is misconfigured or
- has not yet been provisioned with key signatures via ``taler-donau-offline``.
+ virtually always be successful. It only fails if the Donau is misconfigured.
**Details:**
@@ -228,7 +219,7 @@ long-term offline signing key of the Donau, which clients should cache.
**Response:**
:http:statuscode:`200 OK`:
- The body is a `VersionResponse`.
+ The body is a `DonauVersionResponse`.
.. ts:def:: DonauVersionResponse
@@ -554,6 +545,7 @@ The GET status requests require an authorized bearer token as well.
interface Charity {
charity_pub: EddsaPublicKey;
name: string;
+ url: string;
max_per_year: Amount;
receipts_to_date: Amount;
current_year: Integer;
@@ -579,8 +571,11 @@ The GET status requests require an authorized bearer token as well.
interface CharityRequest{
charity_pub: EddsaPublicKey;
- max_per_year: Amount;
name: string;
+ url: string;
+ max_per_year: Amount;
+ receipts_to_date: Amount;
+ current_year: Integer;
}
.. ts:def:: CharityResponse
@@ -613,7 +608,7 @@ The GET status requests require an authorized bearer token as well.
**Response:**
- :http:statuscode:`200 OK`:
+ :http:statuscode:`204 No content`:
The request was successful.
:http:statuscode:`403 Forbidden`:
diff --git a/core/api-exchange.rst b/core/api-exchange.rst
index 222d345e..5a734795 100644
--- a/core/api-exchange.rst
+++ b/core/api-exchange.rst
@@ -1,6 +1,6 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014-2023 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -25,6 +25,7 @@ The `glossary <https://docs.taler.net/glossary.html#glossary>`_
defines all specific terms used in this section.
.. contents:: Table of Contents
+ :local:
.. include:: tos.rst
@@ -61,6 +62,7 @@ possibly by using HTTPS.
as well as the list of possible KYC requirements. This endpoint is largely
for the SPA for AML officers. Merchants should use ``/keys`` which also
contains the protocol version and currency.
+ This specification corresponds to ``current`` protocol being **v19**.
**Response:**
@@ -78,6 +80,10 @@ possibly by using HTTPS.
// Name of the protocol.
name: "taler-exchange";
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since **v18**, may become mandatory in the future.
+ implementation?: string;
+
// Currency supported by this exchange, given
// as a currency code ("USD" or "EUR").
currency: string;
@@ -97,7 +103,7 @@ possibly by using HTTPS.
name: string;
// Code of the currency.
- // Deprecated in protocol v18 for the exchange
+ // Deprecated in protocol **v18** for the exchange
// and in protocol v6 for the merchant.
currency: string;
@@ -168,10 +174,9 @@ possibly by using HTTPS.
// Linear cost factor for the STEFAN curve used
// to (over) approximate fees payable by amount.
//
- // Note that the total to be paid is first to be
- // divided by the smallest denomination to obtain
- // the value to be multiplied with.
- stefan_lin: Amount;
+ // Note that this is a scalar, as it is multiplied
+ // with the actual amount.
+ stefan_lin: Float;
// Type of the asset. "fiat", "crypto", "regional"
// or "stock". Wallets should adjust their UI/UX
@@ -192,7 +197,8 @@ possibly by using HTTPS.
// Set to true if this exchange allows the use
// of reserves for rewards.
- rewards_allowed: boolean;
+ // @deprecated in protocol **v18**.
+ rewards_allowed: false;
// EdDSA master public key of the exchange, used to sign entries
// in ``denoms`` and ``signkeys``.
@@ -249,6 +255,90 @@ possibly by using HTTPS.
}
+ The specification for the account object is:
+
+ .. ts:def:: WireAccount
+
+ interface WireAccount {
+ // ``payto://`` URI identifying the account and wire method
+ payto_uri: string;
+
+ // URI to convert amounts from or to the currency used by
+ // this wire account of the exchange. Missing if no
+ // conversion is applicable.
+ conversion_url?: string;
+
+ // Restrictions that apply to bank accounts that would send
+ // funds to the exchange (crediting this exchange bank account).
+ // Optional, empty array for unrestricted.
+ credit_restrictions: AccountRestriction[];
+
+ // Restrictions that apply to bank accounts that would receive
+ // funds from the exchange (debiting this exchange bank account).
+ // Optional, empty array for unrestricted.
+ debit_restrictions: AccountRestriction[];
+
+ // Signature using the exchange's offline key over
+ // a `TALER_MasterWireDetailsPS`
+ // with purpose ``TALER_SIGNATURE_MASTER_WIRE_DETAILS``.
+ master_sig: EddsaSignature;
+
+ // Display label wallets should use to show this
+ // bank account.
+ // Since protocol **v19**.
+ bank_label?: string;
+
+ // *Signed* integer with the display priority for
+ // this bank account. Optional, 0 if missing.
+ // Since protocol **v19**.
+ priority?: Integer;
+
+ }
+
+ .. ts:def:: AccountRestriction
+
+ type AccountRestriction =
+ | RegexAccountRestriction
+ | DenyAllAccountRestriction
+
+ .. ts:def:: DenyAllAccountRestriction
+
+ // Account restriction that disables this type of
+ // account for the indicated operation categorically.
+ interface DenyAllAccountRestriction {
+
+ type: "deny";
+ }
+
+ .. ts:def:: RegexAccountRestriction
+
+ // Accounts interacting with this type of account
+ // restriction must have a payto://-URI matching
+ // the given regex.
+ interface RegexAccountRestriction {
+
+ type: "regex";
+
+ // Regular expression that the payto://-URI of the
+ // partner account must follow. The regular expression
+ // should follow posix-egrep, but without support for character
+ // classes, GNU extensions, back-references or intervals. See
+ // https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html
+ // for a description of the posix-egrep syntax. Applications
+ // may support regexes with additional features, but exchanges
+ // must not use such regexes.
+ payto_regex: string;
+
+ // Hint for a human to understand the restriction
+ // (that is hopefully easier to comprehend than the regex itself).
+ human_hint: string;
+
+ // Map from IETF BCP 47 language tags to localized
+ // human hints.
+ human_hint_i18n?: { [lang_tag: string]: string };
+
+ }
+
.. ts:def:: GlobalFees
interface GlobalFees {
@@ -536,114 +626,6 @@ possibly by using HTTPS.
Both the individual denominations *and* the denomination list is signed,
allowing customers to prove that they received an inconsistent list.
-.. _wire-req:
-
-.. http:get:: /wire
-
- Returns a list of payment methods supported by the exchange. The idea is
- that wallets may use this information to instruct users on how to perform
- wire transfers to top up their wallets.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- The exchange responds with a `WireResponse` object. This request should virtually always be successful.
-
- **Details:**
-
- .. ts:def:: WireResponse
-
- interface WireResponse {
-
- // Master public key of the exchange, must match the key returned in ``/keys``.
- master_public_key: EddsaPublicKey;
-
- // Array of wire accounts operated by the exchange for
- // incoming wire transfers.
- accounts: WireAccount[];
-
- // Object mapping names of wire methods (i.e. "iban" or "x-taler-bank")
- // to wire fees.
- fees: { method : AggregateTransferFee[] };
-
- // List of exchanges that this exchange is partnering
- // with to enable wallet-to-wallet transfers.
- wads: ExchangePartner[];
- }
-
- The specification for the account object is:
-
- .. ts:def:: WireAccount
-
- interface WireAccount {
- // ``payto://`` URI identifying the account and wire method
- payto_uri: string;
-
- // URI to convert amounts from or to the currency used by
- // this wire account of the exchange. Missing if no
- // conversion is applicable.
- conversion_url?: string;
-
- // Restrictions that apply to bank accounts that would send
- // funds to the exchange (crediting this exchange bank account).
- // Optional, empty array for unrestricted.
- credit_restrictions: AccountRestriction[];
-
- // Restrictions that apply to bank accounts that would receive
- // funds from the exchange (debiting this exchange bank account).
- // Optional, empty array for unrestricted.
- debit_restrictions: AccountRestriction[];
-
- // Signature using the exchange's offline key over
- // a `TALER_MasterWireDetailsPS`
- // with purpose ``TALER_SIGNATURE_MASTER_WIRE_DETAILS``.
- master_sig: EddsaSignature;
- }
-
- .. ts:def:: AccountRestriction
-
- type AccountRestriction =
- | RegexAccountRestriction
- | DenyAllAccountRestriction
-
- .. ts:def:: DenyAllAccountRestriction
-
- // Account restriction that disables this type of
- // account for the indicated operation categorically.
- interface DenyAllAccountRestriction {
-
- type: "deny";
- }
-
- .. ts:def:: RegexAccountRestriction
-
- // Accounts interacting with this type of account
- // restriction must have a payto://-URI matching
- // the given regex.
- interface RegexAccountRestriction {
-
- type: "regex";
-
- // Regular expression that the payto://-URI of the
- // partner account must follow. The regular expression
- // should follow posix-egrep, but without support for character
- // classes, GNU extensions, back-references or intervals. See
- // https://www.gnu.org/software/findutils/manual/html_node/find_html/posix_002degrep-regular-expression-syntax.html
- // for a description of the posix-egrep syntax. Applications
- // may support regexes with additional features, but exchanges
- // must not use such regexes.
- payto_regex: string;
-
- // Hint for a human to understand the restriction
- // (that is hopefully easier to comprehend than the regex itself).
- human_hint: string;
-
- // Map from IETF BCP 47 language tags to localized
- // human hints.
- human_hint_i18n?: { [lang_tag: string]: string };
-
- }
-
Aggregate wire transfer fees representing the fees the exchange
charges per wire transfer to a merchant must be specified as an
array in all wire transfer response objects under ``fees``. The
@@ -658,9 +640,6 @@ possibly by using HTTPS.
// Per transfer closing fee.
closing_fee: Amount;
- // Per exchange-to-exchange transfer (wad) fee.
- wad_fee: Amount;
-
// What date (inclusive) does this fee go into effect?
// The different fees must cover the full time period in which
// any of the denomination keys are valid without overlap.
@@ -685,6 +664,9 @@ possibly by using HTTPS.
// Public master key of the partner exchange.
partner_master_pub: EddsaPublicKey;
+ // Per exchange-to-exchange transfer (wad) fee.
+ wad_fee: Amount;
+
// Exchange-to-exchange wad (wire) transfer frequency.
wad_frequency: RelativeTime;
@@ -1131,6 +1113,16 @@ Management operations authorized by master key
// become active immediately! Used ONLY to detect replay attacks.
validity_start: Timestamp;
+ // Display label wallets should use to show this
+ // bank account.
+ // Since protocol **v19**.
+ bank_label?: string;
+
+ // *Signed* integer with the display priority for
+ // this bank account.
+ // Since protocol **v19**.
+ priority?: Integer;
+
}
.. http:post:: /management/wire/disable
@@ -3391,7 +3383,7 @@ the API during normal operation.
// Melt commitment. Hash over the various coins to be withdrawn.
// See also ``TALER_refresh_get_commitment()``.
- rc: TALER_RefreshCommitmentP;
+ rc: HashCode;
// Master seed for the Clause-schnorr R-value
// creation. Must match the /csr-melt request.
@@ -3538,10 +3530,7 @@ the API during normal operation.
.. ts:def:: RevealResponse
- interface RevealResponse {
- // List of the exchange's blinded RSA signatures on the new coins.
- ev_sigs : Array<{ ev_sig: BlindedDenominationSignature }>;
- }
+ type RevealResponse = BatchWithdrawResponse;
.. ts:def:: RevealConflictResponse
@@ -4863,9 +4852,18 @@ wallet-to-wallet payments. Only another exchange should access this endpoint.
KYC status updates
------------------
+This section describes endpoints used to set up, complete and
+inquire about KYC operations performed by an exchange for
+regulatory compliance.
+
.. http:post:: /kyc-wallet
Setup KYC identification for a wallet. Returns the KYC UUID.
+ This endpoint is used by compliant Taler wallets when they
+ are about to hit the balance threshold and thus need to have
+ the customer provide their personal details to the exchange.
+ The wallet is identified by its long-lived reserve public key
+ (which is used for P2P payments, not for withdrawals).
**Request:**
@@ -4922,15 +4920,18 @@ KYC status updates
.. http:get:: /kyc-check/$REQUIREMENT_ROW/$H_PAYTO/$USERTYPE
- Check or update KYC status of a particular payment target.
- Returns the current KYC status of the account and, if
- negative, returns the URL where the KYC process can be
- initiated. The ``$REQUIREMENT_ROW`` must have been
- returned previously from an exchange API endpoint that
- determined that KYC was needed. The ``$H_PATYO`` must be
- the hash of the payto:// URI of the payment target.
- The ``$USERTYPE`` states whether the entity to perform
- the KYC is an "individual" or "business".
+ Checks the KYC status of a particular payment target and possibly begins the
+ KYC process. This endpoint is used by wallets or merchants that have been
+ told about a KYC requirement and now want to check if the KYC requirement
+ has been fulfilled. Long-polling may be used to instantly observe a change
+ in the KYC requirement status.
+
+ Returns the current KYC status of the requirement process and, if negative,
+ returns the URL where the KYC process can be initiated. The
+ ``$REQUIREMENT_ROW`` must have been returned previously from an exchange API
+ endpoint that determined that KYC was needed. The ``$H_PATYO`` must be the
+ hash of the "payto://" URI of the payment target. The ``$USERTYPE`` states
+ whether the entity to perform the KYC is an "individual" or a "business".
**Request:**
@@ -4949,12 +4950,13 @@ KYC status updates
The response will be an `AccountKycStatus` object.
:http:statuscode:`202 Accepted`:
The user should be redirected to the provided location to perform
- the required KYC checks to open the account. Afterwards, the
- ``/kyc-check/`` request should be repeated.
+ the required KYC checks to satisfy the legal requirements. Afterwards, the
+ ``/kyc-check/`` request should be repeated to check whether the
+ user has completed the process.
The response will be an `AccountKycRedirect` object.
:http:statuscode:`204 No content`:
The exchange is not configured to perform KYC and thus
- generally all accounts are simply considered legitimate.
+ the legal requirements are already satisfied.
:http:statuscode:`402 Payment Required`:
The client must pay the KYC fee for the KYC process.
**This is currently not implemented, see #7365.**
@@ -4964,6 +4966,10 @@ KYC status updates
The payment target is unknown.
:http:statuscode:`451 Unavailable for Legal Reasons`:
The transaction cannot be completed due to AML rules.
+ Thus, the operation is currently not stuck on KYC, but
+ on exchange staff performing their AML review. The user
+ should be told to wait and/or contact the exchange operator
+ if the situation persists.
The response will be a `AccountAmlBlocked` object.
**Details:**
@@ -5034,10 +5040,18 @@ KYC status updates
.. http:get:: /kyc-proof/$PROVIDER_SECTION?state=$H_PAYTO
- Update KYC status of a particular payment target. Provides
+ Endpoint accessed from the user's browser at the *end* of a
+ KYC process, possibly providing the exchange with additional
+ credentials to obtain the results of the KYC process.
+ Specifically, the URL arguments should provide
information to the exchange that allows it to verify that the
user has completed the KYC process. The details depend on
- the logic, which is selected by the $PROVIDER_SECTION.
+ the logic, which is selected by the "$PROVIDER_SECTION".
+
+ While this is a GET (and thus safe, and idempotent), the operation
+ may actually trigger significant changes in the exchange's state.
+ In particular, it may update the KYC status of a particular
+ payment target.
**Request:**
@@ -5056,6 +5070,10 @@ KYC status updates
**Response:**
+ Given that the response is returned to a user using a browser and **not** to
+ a Taler wallet, the response format is in human-readable HTML and not in
+ machine-readable JSON.
+
:http:statuscode:`302 Found`:
The KYC operation succeeded and the
payment target is now authorized to transact.
@@ -5078,11 +5096,11 @@ KYC status updates
.. http:get:: /kyc-webhook/$LOGIC/*
.. http:post:: /kyc-webhook/$LOGIC/*
- Update KYC status of a particular payment target. Provides
- information to the KYC logic of the exchange that allows
- it to verify that the user has completed the KYC process.
- May be a GET or a POST request, depending on $LOGIC or
- $PROVIDER_SECTION.
+ All of the above endpoints can be used to update KYC status of a particular
+ payment target. They provide information to the KYC logic of the exchange
+ that allows it to verify that the user has completed the KYC process. May
+ be a GET or a POST request, depending on the specific "$LOGIC" and/or the
+ "$PROVIDER_SECTION".
**Request:**
@@ -5092,7 +5110,7 @@ KYC status updates
**Response:**
:http:statuscode:`204 No content`:
- The webhook succeeded.
+ The operation succeeded.
:http:statuscode:`404 Not found`:
The specified logic is unknown.
@@ -5102,12 +5120,12 @@ Reserve control
---------------
This section describes the reserve control API which can be used to (1)
-prevent a reserve from expiring (which is useful if the reserve is used for
-rewards), to (2) pay an annual fee to allow a number of purses to be created
-for the respective reserve without paying a purse fee each time, to (3) obtain
-KYC information associated with a reserve to prove the identity of the person
-sending an invoice to the payer, and to (4) close a reserve before it would
-naturally expire and possibly (5) wire the funds to a designated account.
+prevent a reserve from expiring, to (2) pay an annual fee to allow a number of
+purses to be created for the respective reserve without paying a purse fee
+each time, to (3) obtain KYC information associated with a reserve to prove
+the identity of the person sending an invoice to the payer, and to (4) close a
+reserve before it would naturally expire and possibly (5) wire the funds to a
+designated account.
.. note::
@@ -5115,7 +5133,7 @@ naturally expire and possibly (5) wire the funds to a designated account.
.. http:post:: /reserves/$RESERVE_PUB/open
- Request keeping a reserve open for rewards or invoicing.
+ Request keeping a reserve open for invoicing.
**Request:**
diff --git a/core/api-mailbox.rst b/core/api-mailbox.rst
index 33db482d..34d27ded 100644
--- a/core/api-mailbox.rst
+++ b/core/api-mailbox.rst
@@ -29,6 +29,9 @@ for all details not specified in the individual requests.
The `glossary <https://docs.taler.net/glossary.html#glossary>`_
defines all specific terms used in this section.
+.. contents:: Table of Contents
+ :local:
+
.. include:: tos.rst
-------------------------
diff --git a/core/api-merchant.rst b/core/api-merchant.rst
index ffaef0a2..d9c6611f 100644
--- a/core/api-merchant.rst
+++ b/core/api-merchant.rst
@@ -1,6 +1,6 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014-2023 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -25,7 +25,7 @@ Merchant Backend RESTful API
============================
.. contents:: Table of Contents
-
+ :local:
-----------------------
Base URLs and Instances
@@ -36,11 +36,13 @@ This is useful when multiple businesses want to share the same payment
infrastructure.
Merchant backends have one special ``default`` instance. This ``default``
-instance is used when no explicit instance is specified. Despite its name,
-this instance must be created after the installation. In case *no* default
-instance is found - or its credentials got lost -, the administrator can use
-the default instance's rights by resorting on the ``--auth`` command line option,
-or by restarting the service by providing an environment variable called
+instance is used when no explicit instance is specified. Note that using
+``/instances/default/$ANYTHING`` is deprecated and will result in a permanent
+redirect (HTTP status 308) to ``$ANYTHING``. a Despite its name, this instance
+must be created after the installation. In case *no* default instance is
+found - or its credentials got lost -, the administrator can use the default
+instance's rights by resorting on the ``--auth`` command line option, or by
+restarting the service by providing an environment variable called
``TALER_MERCHANT_TOKEN``.
Each instance (default and others) has a base URL. The resources under
@@ -74,10 +76,10 @@ Examples:
https://merchant-backend.example.com/instances/myinst/orders/ABCD
A private endpoint (explicit "default" instance):
- https://merchant-backend.example.com/instances/default/private/orders
+ https://merchant-backend.example.com/private/orders
A public endpoint (explicit "default" instance):
- https://merchant-backend.example.com/instances/default/orders
+ https://merchant-backend.example.com/orders
Endpoints to manage other instances (ONLY for implicit "default" instance):
https://merchant-backend.example.com/management/instances
@@ -121,7 +123,7 @@ such as the implemented version of the protocol and the currency used.
.. http:get:: /config
Return the protocol version and currency supported by this merchant backend.
- This specification corresponds to ``current`` protocol being version **6**.
+ This specification corresponds to ``current`` protocol being version **13**.
**Response:**
@@ -139,6 +141,10 @@ such as the implemented version of the protocol and the currency used.
// Name of the protocol.
name: "taler-merchant";
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since **v8**, may become mandatory in the future.
+ implementation?: string;
+
// Default (!) currency supported by this backend.
// This is the currency that the backend should
// suggest by default to the user when entering
@@ -160,7 +166,7 @@ such as the implemented version of the protocol and the currency used.
currencies: { currency : CurrencySpecification};
// Array of exchanges trusted by the merchant.
- // Since protocol v6.
+ // Since protocol **v6**.
exchanges: ExchangeConfigInfo[];
}
@@ -193,8 +199,7 @@ This section describes (public) endpoints that wallets must be able
to interact with directly (without HTTP-based authentication). These
endpoints are used to process payments (claiming an order, paying
for the order, checking payment/refund status and aborting payments),
-process refunds (checking refund status, obtaining the refund),
-and to pick up rewards.
+and to process refunds (checking refund status, obtaining the refund).
Claiming an order
@@ -283,17 +288,17 @@ Making the payment
Either the client request is malformed or some specific processing error
happened that may be the fault of the client as detailed in the JSON body
of the response.
+ This includes the case where the payment is insufficient (sum is below
+ the required total amount, for example because the wallet calculated the
+ fees wrong).
:http:statuscode:`402 Payment required`:
There used to be a sufficient payment, but due to refunds the amount effectively
paid is no longer sufficient. (If the amount is generally insufficient, we
- return "406 Not Acceptable", only if this is because of refunds we return 402.)
+ return "400 Bad Request", only if this is because of refunds we return 402.)
:http:statuscode:`403 Forbidden`:
One of the coin signatures was not valid.
:http:statuscode:`404 Not found`:
The merchant backend could not find the order or the instance and thus cannot process the payment.
- :http:statuscode:`406 Not acceptable`:
- The payment is insufficient (sum is below the required total amount).
- TODO: Should probably change to a different status code in the future as 406 is technically wrong.
:http:statuscode:`408 Request timeout`:
The backend took too long to process the request. Likely the merchant's connection
to the exchange timed out. Try again.
@@ -364,7 +369,7 @@ Making the payment
coin_pub: EddsaPublicKey;
// Signature made by the denomination public key.
- ub_sig: RsaSignature;
+ ub_sig: UnblindedSignature;
// The hash of the denomination public key associated with this coin.
h_denom: HashCode;
@@ -407,6 +412,7 @@ Querying payment status
merchant backend may return a response immediately.
:query await_refund_obtained=BOOLEAN: *Optional*. If set to "yes", poll for the order's pending refunds to be picked up. ``timeout_ms`` specifies how long we will wait for the refund.
:query refund=AMOUNT: *Optional*. Indicates that we are polling for a refund above the given AMOUNT. ``timeout_ms`` will specify how long we will wait for the refund.
+ :query allow_refunded_for_repurchase: *Optional*. Since protocol **v9** refunded orders are only returned under "already_paid_order_id" if this flag is set explicitly to "YES".
**Response:**
@@ -586,7 +592,7 @@ are for incomplete payments for an order and never for established contracts.
:http:statuscode:`200 OK`:
The merchant accepted the request, and passed it on to the exchange. The body is a
- a `merchant refund response <MerchantRefundResponse>`. Note that the exchange
+ a `abort response <AbortResponse>`. Note that the exchange
MAY still have encountered errors in processing. Those will then be part of
the body. Wallets MUST carefully consider errors for each of the coins as
returned by the exchange.
@@ -831,111 +837,6 @@ the contract. Refunds must be approved by the merchant's business logic.
}
-Picking up rewards
-------------------
-
-Rewards are a way for wallets to obtain e-cash from
-a website.
-
-.. http:get:: [/instances/$INSTANCE]/rewards/$REWARD_ID
-
- Handle request from wallet to provide details about a reward.
-
- This endpoint typically also supports requests with the "Accept" header
- requesting "text/html". In this case, an HTML response suitable for
- triggering the interaction with the wallet is returned. If the backend
- installation does not include the required HTML templates, a 406 status
- code is returned.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- A reward is being returned. The backend responds with a `RewardInformation`.
- :http:statuscode:`404 Not found`:
- The reward identifier is unknown.
- :http:statuscode:`406 Not acceptable`:
- The merchant backend could not load the template required to generate a reply in the desired format. (Likely HTML templates were not properly installed.)
- :http:statuscode:`410 Gone`:
- A reward has been fully claimed. The JSON reply still contains the `RewardInformation`.
-
- .. ts:def:: RewardInformation
-
- interface RewardInformation {
-
- // Exchange from which the reward will be withdrawn. Needed by the
- // wallet to determine denominations, fees, etc.
- exchange_url: string;
-
- // URL where to go after obtaining the reward.
- next_url: string;
-
- // (Remaining) amount of the reward (including fees).
- reward_amount: Amount;
-
- // Timestamp indicating when the reward is set to expire (may be in the past).
- // Note that rewards that have expired MAY also result in a 404 response.
- expiration: Timestamp;
- }
-
-
-.. http:post:: [/instances/$INSTANCE]/rewards/$REWARD_ID/pickup
-
- Handle request from wallet to pick up a reward.
-
- **Request:**
-
- The request body is a `RewardPickupRequest` object.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- A reward is being returned. The backend responds with a `RewardResponse`.
- :http:statuscode:`401 Unauthorized`:
- The reward amount requested exceeds the reward.
- :http:statuscode:`404 Not found`:
- The reward identifier is unknown.
- :http:statuscode:`409 Conflict`:
- Some of the denomination key hashes of the request do not match those currently available from the exchange (hence there is a conflict between what the wallet requests and what the merchant believes the exchange can provide).
- :http:statuscode:`410 Gone`:
- The reward has expired.
-
- .. ts:def:: RewardPickupRequest
-
- interface RewardPickupRequest {
-
- // List of planchets the wallet wants to use for the reward.
- planchets: PlanchetDetail[];
- }
-
- .. ts:def:: PlanchetDetail
-
- interface PlanchetDetail {
- // Hash of the denomination's public key (hashed to reduce
- // bandwidth consumption).
- denom_pub_hash: HashCode;
-
- // Coin's blinded public key.
- coin_ev: CoinEnvelope;
- }
-
- .. ts:def:: RewardResponse
-
- interface RewardResponse {
-
- // Blind RSA signatures over the planchets.
- // The order of the signatures matches the planchets list.
- blind_sigs: BlindSignature[];
- }
-
- .. ts:def:: BlindSignature
-
- interface BlindSignature {
-
- // The (blind) RSA signature. Still needs to be unblinded.
- blind_sig: BlindedRsaSignature;
- }
-
-
-------------------
Instance management
-------------------
@@ -1795,6 +1696,11 @@ Inspecting inventory
This is used to return the list of all items in the inventory.
+ **Request:**
+
+ :query limit: *Optional*. At most return the given number of results. Negative for descending by row ID, positive for ascending by row ID. Default is ``20``. Since protocol **v12**.
+ :query offset: *Optional*. Starting ``product_serial_id`` for an iteration. Since protocol **v12**.
+
**Response:**
:http:statuscode:`200 OK`:
@@ -1818,6 +1724,8 @@ Inspecting inventory
// Product identifier, as found in the product.
product_id: string;
+ // ``product_serial_id`` of the product in the database.
+ product_serial: integer;
}
@@ -2036,7 +1944,7 @@ Creating orders
// The session for which the payment is made (or replayed).
// Only set for session-based payments.
- // Since protocol v6.
+ // Since protocol **v6**.
session_id?: string;
// Specifies that some products are to be included in the
@@ -2082,14 +1990,14 @@ Creating orders
// Short summary of the order.
summary: string;
- // See documentation of fulfillment_url in ContractTerms.
+ // See documentation of fulfillment_url in `ContractTerms`.
// Either fulfillment_url or fulfillment_message must be specified.
// When creating an order, the fulfillment URL can
// contain ``${ORDER_ID}`` which will be substituted with the
// order ID of the newly created order.
fulfillment_url?: string;
- // See documentation of fulfillment_message in ContractTerms.
+ // See documentation of fulfillment_message in `ContractTerms`.
// Either fulfillment_url or fulfillment_message must be specified.
fulfillment_message?: string;
}
@@ -2165,12 +2073,14 @@ Inspecting orders
:query paid: *Optional*. If set to yes, only return paid orders, if no only unpaid orders. Do not give (or use "all") to see all orders regardless of payment status.
:query refunded: *Optional*. If set to yes, only return refunded orders, if no only unrefunded orders. Do not give (or use "all") to see all orders regardless of refund status.
:query wired: *Optional*. If set to yes, only return wired orders, if no only orders with missing wire transfers. Do not give (or use "all") to see all orders regardless of wire transfer status.
- :query delta: *Optional*. takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` and ``date_s`` are returned. Defaults to ``-20`` to return the last 20 entries (before ``start`` and/or ``date_s``).
+ :query delta: *Optional*. takes value of the form ``N (-N)``, so that at most ``N`` values strictly older (younger) than ``start`` and ``date_s`` are returned. Defaults to ``-20`` to return the last 20 entries (before ``start`` and/or ``date_s``). Deprecated in protocol **v12**. Use *limit* instead.
+ :query limit: *Optional*. At most return the given number of results. Negative for descending by row ID, positive for ascending by row ID. Default is ``20``. Since protocol **v12**.
:query date_s: *Optional.* Non-negative date in seconds after the UNIX Epoc, see ``delta`` for its interpretation. If not specified, we default to the oldest or most recent entry, depending on ``delta``.
- :query start: *Optional*. Row number threshold, see ``delta`` for its interpretation. Defaults to ``INT64_MAX``, namely the biggest row id possible in the database.
+ :query start: *Optional*. Row number threshold, see ``delta`` for its interpretation. Defaults to ``INT64_MAX``, namely the biggest row id possible in the database. Deprecated in protocol **v12**. Use *offset* instead.
+ :query offset: *Optional*. Starting ``product_serial_id`` for an iteration. Since protocol **v12**.
:query timeout_ms: *Optional*. Timeout in milliseconds to wait for additional orders if the answer would otherwise be negative (long polling). Only useful if delta is positive. Note that the merchant MAY still return a response that contains fewer than ``delta`` orders.
- :query session_id: *Optional*. Since protocol v6. Filters by session ID.
- :query fulfillment_url: *Optional*. Since protocol v6. Filters by fulfillment URL.
+ :query session_id: *Optional*. Since protocol **v6**. Filters by session ID.
+ :query fulfillment_url: *Optional*. Since protocol **v6**. Filters by fulfillment URL.
**Response:**
@@ -2227,8 +2137,9 @@ Inspecting orders
**Request:**
:query session_id: *Optional*. Session ID that the payment must be bound to. If not specified, the payment is not session-bound.
- :query transfer: *Deprecated in protocol V6*. *Optional*. If set to "YES", try to obtain the wire transfer status for this order from the exchange. Otherwise, the wire transfer status MAY be returned if it is available.
+ :query transfer: Deprecated in protocol **V6**. *Optional*. If set to "YES", try to obtain the wire transfer status for this order from the exchange. Otherwise, the wire transfer status MAY be returned if it is available.
:query timeout_ms: *Optional*. Timeout in milliseconds to wait for a payment if the answer would otherwise be negative (long polling).
+ :query allow_refunded_for_repurchase: *Optional*. Since protocol **v9** refunded orders are only returned under "already_paid_order_id" if this flag is set explicitly to "YES".
**Response:**
@@ -2291,7 +2202,7 @@ Inspecting orders
// Reports about trouble obtaining wire transfer details,
// empty array if no trouble were encountered.
- // @deprecated in protocol v6
+ // @deprecated in protocol **v6**.
wire_reports: TransactionWireReport[];
// The refund details for this order. One entry per
@@ -2692,418 +2603,6 @@ once we got a reply from the exchange.
The transfer cannot be deleted anymore.
------------------------
-Backend: Giving rewards
------------------------
-
-Rewards are a way for websites to give small amounts of e-cash to visitors (for
-example as a financial reward for providing information or viewing
-advertisements). Rewards are non-contractual: neither merchant nor consumer
-have any contractual information about the other party as a result of the
-reward.
-
-
-Create reserve
---------------
-
-Reserves are basically funds a merchant has provided to an exchange for a
-rewards campaign. Each reserve has a limited lifetime (say 2--4 weeks). Any
-funds not used to reward customers will automatically be wired back from the
-exchange to the originating account.
-
-Before handing out rewards, a merchant must tell the backend to set up a
-reserve. The backend will return a reserve public key which must be used as
-the wire transfer subject when wiring the reward campaign funds to the
-exchange.
-
-.. _rewards:
-.. http:post:: [/instances/$INSTANCE]/private/reserves
-
- Create a reserve for rewards.
-
- This request is **not** idempotent. However, while repeating
- it will create another reserve, that is generally pretty harmless
- (assuming only one of the reserves is filled with a wire transfer).
- Clients may want to eventually delete the unused reserves to
- avoid clutter.
-
- **Request:**
-
- The request body is a `ReserveCreateRequest` object.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- The backend is waiting for the reserve to be established. The merchant
- must now perform the wire transfer indicated in the `ReserveCreateConfirmation`.
- :http:statuscode:`408 Request timeout`:
- The exchange did not respond on time.
- :http:statuscode:`409 Conflict`:
- The exchange does not support the requested wire method or does not allow rewards.
- :http:statuscode:`502 Bad gateway`:
- We could not obtain ``/wire`` details from the specified exchange base URL.
- :http:statuscode:`504 Gateway timeout`:
- The merchant's interaction with the exchange took too long.
- The client might want to try again later.
-
- .. ts:def:: ReserveCreateRequest
-
- interface ReserveCreateRequest {
- // Amount that the merchant promises to put into the reserve.
- initial_balance: Amount;
-
- // Exchange the merchant intends to use for rewards.
- exchange_url: string;
-
- // Desired wire method, for example "iban" or "x-taler-bank".
- wire_method: string;
- }
-
- .. ts:def:: ReserveCreateConfirmation
-
- interface ReserveCreateConfirmation {
- // Public key identifying the reserve.
- reserve_pub: EddsaPublicKey;
-
- // Wire accounts of the exchange where to transfer the funds.
- accounts: WireAccount[];
- }
-
-.. http:get:: [/instances/$INSTANCE]/private/reserves
-
- Obtain list of reserves that have been created for rewards.
-
- **Request:**
-
- :query after: *Optional*. Only return reserves created after the given timestamp in milliseconds.
- :query active: *Optional*. Only return active/inactive reserves depending on the boolean given.
- :query failures: *Optional*. Only return reserves where we disagree with the exchange about the initial balance.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- Returns a list of known reward reserves.
- The body is a `RewardReserveStatus`.
-
- .. ts:def:: RewardReserveStatus
-
- interface RewardReserveStatus {
- // Array of all known reserves (possibly empty!).
- reserves: ReserveStatusEntry[];
- }
-
- .. ts:def:: ReserveStatusEntry
-
- interface ReserveStatusEntry {
- // Public key of the reserve.
- reserve_pub: EddsaPublicKey;
-
- // Timestamp when it was established.
- creation_time: Timestamp;
-
- // Timestamp when it expires.
- expiration_time: Timestamp;
-
- // Initial amount as per reserve creation call.
- merchant_initial_amount: Amount;
-
- // Initial amount as per exchange, 0 if exchange did
- // not confirm reserve creation yet.
- exchange_initial_amount: Amount;
-
- // Amount picked up so far.
- pickup_amount: Amount;
-
- // Amount approved for rewards that exceeds the pickup_amount.
- committed_amount: Amount;
-
- // Is this reserve active (false if it was deleted but not purged)?
- active: boolean;
- }
-
-
-Query funds remaining
----------------------
-
-.. http:get:: [/instances/$INSTANCE]/private/reserves/$RESERVE_PUB
-
- Obtain information about a specific reserve that have been created for rewards.
-
- **Request:**
-
- :query rewards: *Optional*. If set to "yes", returns also information about all of the rewards created.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- Returns the `ReserveDetail`.
- :http:statuscode:`404 Not found`:
- The reward reserve is not known.
- :http:statuscode:`502 Bad gateway`:
- We are having trouble with the request because of a problem with the exchange.
- Likely returned with an "exchange_code" in addition to a "code" and
- an "exchange_http_status" in addition to our own HTTP status. Also usually
- includes the full exchange reply to our request under "exchange_reply".
- This is only returned if there was actual trouble with the exchange, not
- if the exchange merely did not respond yet or if it responded that the
- reserve was not yet filled.
- :http:statuscode:`504 Gateway timeout`:
- The merchant's interaction with the exchange took too long.
- The client might want to try again later.
-
- .. ts:def:: ReserveDetail
-
- interface ReserveDetail {
- // Timestamp when it was established.
- creation_time: Timestamp;
-
- // Timestamp when it expires.
- expiration_time: Timestamp;
-
- // Initial amount as per reserve creation call.
- merchant_initial_amount: Amount;
-
- // Initial amount as per exchange, 0 if exchange did
- // not confirm reserve creation yet.
- exchange_initial_amount: Amount;
-
- // Amount picked up so far.
- pickup_amount: Amount;
-
- // Amount approved for rewards that exceeds the pickup_amount.
- committed_amount: Amount;
-
- // Array of all rewards created by this reserves (possibly empty!).
- // Only present if asked for explicitly.
- rewards?: RewardStatusEntry[];
-
- // Is this reserve active (false if it was deleted but not purged)?
- active: boolean;
-
- // Array of wire accounts of the exchange that could
- // be used to fill the reserve, can be NULL
- // if the reserve is inactive or was already filled
- accounts?: WireAccount[];
-
- // URL of the exchange hosting the reserve,
- // NULL if the reserve is inactive
- exchange_url: string;
- }
-
- .. ts:def:: RewardStatusEntry
-
- interface RewardStatusEntry {
-
- // Unique identifier for the reward.
- reward_id: HashCode;
-
- // Total amount of the reward that can be withdrawn.
- total_amount: Amount;
-
- // Human-readable reason for why the reward was granted.
- reason: string;
- }
-
-
-Authorizing rewards
--------------------
-
-.. http:post:: [/instances/$INSTANCE]/private/reserves/$RESERVE_PUB/authorize-reward
-
- Authorize creation of a reward from the given reserve.
-
- **Request:**
-
- The request body is a `RewardCreateRequest` object.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- A reward has been created. The backend responds with a `RewardCreateConfirmation`.
- :http:statuscode:`404 Not found`:
- The instance or the reserve is unknown to the backend.
- :http:statuscode:`412 Precondition failed`:
- The reward amount requested exceeds the available reserve balance for rewards.
-
- .. ts:def:: RewardCreateRequest
-
- interface RewardCreateRequest {
- // Amount that the customer should be rewarded.
- amount: Amount;
-
- // Justification for giving the reward.
- justification: string;
-
- // URL that the user should be directed to after receiving the reward,
- // will be included in the reward_token.
- next_url: string;
- }
-
- .. ts:def:: RewardCreateConfirmation
-
- interface RewardCreateConfirmation {
- // Unique reward identifier for the reward that was created.
- reward_id: HashCode;
-
- // taler://reward URI for the reward.
- taler_reward_uri: string;
-
- // URL that will directly trigger processing
- // the reward when the browser is redirected to it.
- reward_status_url: string;
-
- // When does the reward expire?
- reward_expiration: Timestamp;
- }
-
-
-.. http:post:: [/instances/$INSTANCE]/private/rewards
-
- Authorize creation of a reward, with
- automatic selection of a working reserve of the instance by the
- backend. Intentionally otherwise identical to the ``/authorize-reward``
- endpoint given above.
-
- **Request:**
-
- The request body is a `RewardCreateRequest` object.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- A reward has been created. The backend responds with a `RewardCreateConfirmation`.
- :http:statuscode:`404 Not found`:
- The instance is unknown to the backend.
- :http:statuscode:`412 Precondition failed`:
- The reward amount requested exceeds the available reserve balance for rewards
- in all of the reserves of the instance.
-
-
-Deleting reserves
------------------
-
-.. http:delete:: [/instances/$INSTANCE]/private/reserves/$RESERVE_PUB
-
- Delete information about a reserve. Fails if the reserve still has
- committed to rewards that were not yet picked up and that have not yet
- expired.
-
- **Request:**
-
- :query purge: *Optional*. If set to YES, the reserve and all information
- about rewards it issued will be fully deleted.
- Otherwise only the private key would be deleted.
-
- **Response:**
-
- :http:statuscode:`204 No content`:
- The backend has successfully deleted the reserve.
- :http:statuscode:`404 Not found`:
- The backend does not know the instance or the reserve.
- :http:statuscode:`409 Conflict`:
- The backend refuses to delete the reserve (committed rewards awaiting pickup).
-
-
-Checking reward status
-----------------------
-
-.. http:get:: [/instances/$INSTANCE]/private/rewards/$REWARD_ID
-
- Obtain information about a particular reward.
-
- **Request:**
-
- :query pickups: *Optional*. If set to "yes", returns also information about all of the pickups.
- :query min_amount: *Optional*. Minimum pick-up amount the client is interested in.
- :query timeout_ms=NUMBER: *Optional.* If specified, the merchant backend will
- wait up to ``timeout_ms`` milliseconds for rewards of at least min_pick_up to be
- picked up. A client must never rely on this behavior, as the
- merchant backend may return a response immediately.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- The reward is known. The backend responds with a `RewardDetails` message.
- :http:statuscode:`404 Not found`:
- The reward is unknown to the backend.
-
- .. ts:def:: RewardDetails
-
- interface RewardDetails {
- // Amount that we authorized for this reward.
- total_authorized: Amount;
-
- // Amount that was picked up by the user already.
- total_picked_up: Amount;
-
- // Human-readable reason given when authorizing the reward.
- reason: string;
-
- // Timestamp indicating when the reward is set to expire (may be in the past).
- expiration: Timestamp;
-
- // Reserve public key from which the reward is funded.
- reserve_pub: EddsaPublicKey;
-
- // Array showing the pickup operations of the wallet (possibly empty!).
- // Only present if asked for explicitly.
- pickups?: PickupDetail[];
- }
-
- .. ts:def:: PickupDetail
-
- interface PickupDetail {
- // Unique identifier for the pickup operation.
- pickup_id: HashCode;
-
- // Number of planchets involved.
- num_planchets: Integer;
-
- // Total amount requested for this pickup_id.
- requested_amount: Amount;
- }
-
-
-.. http:get:: [/instances/$INSTANCE]/private/rewards
-
- Return the list of all rewards.
-
- **Request:**
-
- :query include_expired: *Optional*. If set to "yes", the result includes expired rewards also. Otherwise, only active rewards are returned.
-
- :query limit: *Optional*. At most return the given number of results. Negative for descending in database row id, positive for ascending in database row id.
-
- :query offset: *Optional*. Starting ``row_id`` for an iteration.
-
- **Response:**
-
- :http:statuscode:`200 OK`:
- The backend has successfully found the list of rewards. The backend responds
- with a `RewardsResponse`.
-
- .. ts:def:: RewardsResponse
-
- interface RewardsResponse {
-
- // List of rewards that are present in the backend.
- rewards: Reward[];
- }
-
- .. ts:def:: Reward
-
- interface Reward {
-
- // ID of the reward in the backend database.
- row_id: number;
-
- // Unique identifier for the reward.
- reward_id: HashCode;
-
- // (Remaining) amount of the reward (including fees).
- reward_amount: Amount;
- }
-
-----------
OTP Devices
-----------
@@ -3137,11 +2636,19 @@ to validate that a customer made a payment.
// Human-readable description for the device.
otp_device_description: string;
- // A base64-encoded key
+ // A key encoded with RFC 3548 Base32.
+ // IMPORTANT: This is not using the typical
+ // Taler base32-crockford encoding.
+ // Instead it uses the RFC 3548 encoding to
+ // be compatible with the TOTP standard.
otp_key: string;
// Algorithm for computing the POS confirmation.
- otp_algorithm: Integer;
+ // "NONE" or 0: No algorithm (no pos confirmation will be generated)
+ // "TOTP_WITHOUT_PRICE" or 1: Without amounts (typical OTP device)
+ // "TOTP_WITH_PRICE" or 2: With amounts (special-purpose OTP device)
+ // The "String" variants are supported @since protocol **v7**.
+ otp_algorithm: Integer | string;
// Counter for counter-based OTP devices.
otp_ctr?: Integer;
@@ -3173,8 +2680,12 @@ to validate that a customer made a payment.
// Human-readable description for the device.
otp_device_description: string;
- // A base64-encoded key
- otp_key: string;
+ // A key encoded with RFC 3548 Base32.
+ // IMPORTANT: This is not using the typical
+ // Taler base32-crockford encoding.
+ // Instead it uses the RFC 3548 encoding to
+ // be compatible with the TOTP standard.
+ otp_key?: string;
// Algorithm for computing the POS confirmation.
otp_algorithm: Integer;
@@ -3218,6 +2729,17 @@ to validate that a customer made a payment.
This is used to obtain detailed information about a specific OTP device.
+ The client can provide additional inputs in the query to allow the backend
+ to compute and return a sample OTP code. Note that it is not an error if
+ the client provides query arguments that are not being used *or* that are
+ insufficient for the server to compute the ``otp_code``: If the client
+ provides inadequate query parameters, the ``otp_code`` is simply omitted
+ from the response.
+
+ **Query:**
+
+ :query faketime=TIMESTAMP: *Optional*. Timestamp in seconds to use when calculating the current OTP code of the device. Since protocol **v10**.
+ :query price=AMOUNT: *Optional*. Price to use when calculating the current OTP code of the device. Since protocol **v10**.
**Response:**
@@ -3235,11 +2757,49 @@ to validate that a customer made a payment.
device_description: string;
// Algorithm for computing the POS confirmation.
+ //
+ // Currently, the following numbers are defined:
+ // 0: None
+ // 1: TOTP without price
+ // 2: TOTP with price
otp_algorithm: Integer;
// Counter for counter-based OTP devices.
otp_ctr?: Integer;
+ // Current time for time-based OTP devices.
+ // Will match the ``faketime`` argument of the
+ // query if one was present, otherwise the current
+ // time at the backend.
+ //
+ // Available since protocol **v10**.
+ otp_timestamp: Integer;
+
+ // Current OTP confirmation string of the device.
+ // Matches exactly the string that would be returned
+ // as part of a payment confirmation for the given
+ // amount and time (so may contain multiple OTP codes).
+ //
+ // If the ``otp_algorithm`` is time-based, the code is
+ // returned for the current time, or for the ``faketime``
+ // if a TIMESTAMP query argument was provided by the client.
+ //
+ // When using OTP with counters, the counter is **NOT**
+ // increased merely because this endpoint created
+ // an OTP code (this is a GET request, after all!).
+ //
+ // If the ``otp_algorithm`` requires an amount, the
+ // ``amount`` argument must be specified in the
+ // query, otherwise the ``otp_code`` is not
+ // generated.
+ //
+ // This field is *optional* in the response, as it is
+ // only provided if we could compute it based on the
+ // ``otp_algorithm`` and matching client query arguments.
+ //
+ // Available since protocol **v10**.
+ otp_code?: string;
+
}
.. http:delete:: [/instances/$INSTANCE]/private/otp-devices/$DEVICE_ID
@@ -3335,9 +2895,27 @@ Adding templates
// This parameter is optional.
otp_id?: string;
- // Additional information in a separate template.
+ // Fixed contract information for orders created from
+ // this template.
template_contract: TemplateContractDetails;
- }
+
+ // Key-value pairs matching a subset of the
+ // fields from `template_contract` that are
+ // user-editable defaults for this template.
+ // Since protocol **v13**.
+ editable_defaults?: Object;
+
+ // Required currency for payments. Useful if no
+ // amount is specified in the `template_contract`
+ // but the user should be required to pay in a
+ // particular currency anyway. Merchant backends
+ // may reject requests if the `template_contract`
+ // or `editable_defaults` do
+ // specify an amount in a different currency.
+ // This parameter is optional.
+ // Since protocol **v13**.
+ required_currency?: string;
+ }
.. ts:def:: TemplateContractDetails
@@ -3497,6 +3075,30 @@ Removing template
Using template
----------------
+.. http:get:: [/instances/$INSTANCE]/templates/$TEMPLATE_ID
+
+ This is used to obtain information about a specific template by wallets
+ before they ask the user to fill in details.
+ This endpoint is available since protocol **v11**.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The backend has successfully returned the detailed information about a specific template.
+ Returns a `WalletTemplateDetails`.
+ :http:statuscode:`404 Not found`:
+ The instance or template(ID) is unknown to the backend.
+
+ .. ts:def:: WalletTemplateDetails
+
+ interface WalletTemplateDetails {
+
+ // Hard-coded information about the contrac terms
+ // for this template.
+ template_contract: TemplateContractDetails;
+ }
+
+
.. http:post:: [/instances/$INSTANCES]/templates/$TEMPLATE_ID
This using template can be modified by everyone and will be used to create order.
@@ -3552,7 +3154,7 @@ Adding webhooks
The creation of the webhook is successsful.
:http:statuscode:`404 Not found`:
- The merchant instance is unknowm or it not in our data.
+ The merchant instance is unknown or it not in our data.
.. ts:def:: WebhookAddDetails
@@ -3713,6 +3315,242 @@ Removing webhook
+----------------------------------------
+Token Families: Subscriptions, Discounts
+----------------------------------------
+
+This API provides functionalities for the issuance, management, and revocation
+of token families. Tokens facilitate the implementation of subscriptions and
+discounts, engaging solely the merchant and the user. Each token family
+encapsulates details pertaining to its respective tokens, guiding the merchant's
+backend on the appropriate processing and handling.
+
+
+Creating token families
+-----------------------
+
+.. http:post:: [/instances/$INSTANCES]/private/tokenfamilies
+
+ This is used to create a token family.
+
+ **Request:**
+
+ The request must be a `TokenFamilyCreateRequest`.
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The token family was created successfully.
+
+ :http:statuscode:`404 Not found`:
+ The merchant backend is unaware of the instance.
+
+ .. ts:def:: TokenFamilyCreateRequest
+
+ interface TokenFamilyCreateRequest {
+
+ // Identifier for the token family consisting of unreserved characters
+ // according to RFC 3986.
+ slug: string;
+
+ // Human-readable name for the token family.
+ name: string;
+
+ // Human-readable description for the token family.
+ description: string;
+
+ // Optional map from IETF BCP 47 language tags to localized descriptions.
+ description_i18n?: { [lang_tag: string]: string };
+
+ // Start time of the token family's validity period.
+ // If not specified, merchant backend will use the current time.
+ valid_after?: Timestamp;
+
+ // End time of the token family's validity period.
+ valid_before: Timestamp;
+
+ // Validity duration of an issued token.
+ duration: RelativeTime;
+
+ // Kind of the token family.
+ kind: TokenFamilyKind;
+
+ }
+
+ .. ts:def:: TokenFamilyKind
+
+ enum TokenFamilyKind {
+ Discount = "discount",
+ Subscription = "subscription",
+ }
+
+
+Updating token families
+-----------------------
+
+.. http:patch:: [/instances/$INSTANCES]/private/tokenfamilies/$TOKEN_FAMILY_SLUG
+
+ This is used to update a token family.
+
+ **Request:**
+
+ The request must be a `TokenFamilyUpdateRequest`.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The token family was successsful updated. Returns a `TokenFamilyDetails`.
+
+ :http:statuscode:`404 Not found`:
+ The merchant backend is unaware of the token family or instance.
+
+ .. ts:def:: TokenFamilyUpdateRequest
+
+ interface TokenFamilyUpdateRequest {
+
+ // Human-readable name for the token family.
+ name: string;
+
+ // Human-readable description for the token family.
+ description: string;
+
+ // Optional map from IETF BCP 47 language tags to localized descriptions.
+ description_i18n: { [lang_tag: string]: string };
+
+ // Start time of the token family's validity period.
+ valid_after: Timestamp;
+
+ // End time of the token family's validity period.
+ valid_before: Timestamp;
+
+ // Validity duration of an issued token.
+ duration: RelativeTime;
+
+ }
+
+
+
+Inspecting token families
+-------------------------
+
+.. http:get:: [/instances/$INSTANCES]/private/tokenfamilies
+
+ This is used to list all configured token families for an instance.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The merchant backend has successfully returned all token families.
+ Returns a `TokenFamiliesList`.
+
+ :http:statuscode:`404 Not found`:
+ The merchant backend is unaware of the instance.
+
+ .. ts:def:: TokenFamiliesList
+
+ // TODO: Add pagination
+
+ interface TokenFamiliesList {
+
+ // All configured token families of this instance.
+ token_families: TokenFamilySummary[];
+
+ }
+
+ .. ts:def:: TokenFamilySummary
+
+ interface TokenFamilySummary {
+ // Identifier for the token family consisting of unreserved characters
+ // according to RFC 3986.
+ slug: string;
+
+ // Human-readable name for the token family.
+ name: string;
+
+ // Start time of the token family's validity period.
+ valid_after: Timestamp;
+
+ // End time of the token family's validity period.
+ valid_before: Timestamp;
+
+ // Kind of the token family.
+ kind: TokenFamilyKind;
+ }
+
+
+.. http:get:: [/instances/$INSTANCES]/private/tokenfamilies/$TOKEN_FAMILY_SLUG
+
+ This is used to get detailed information about a specific token family.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The merchant backend has successfully returned the detailed information
+ about a specific token family. Returns a `TokenFamilyDetails`.
+
+ :http:statuscode:`404 Not found`:
+ The merchant backend is unaware of the token family or instance.
+
+
+ The `TokenFamilyDetails` object describes a configured token family.
+
+ .. ts:def:: TokenFamilyDetails
+
+ interface TokenFamilyDetails {
+
+ // Identifier for the token family consisting of unreserved characters
+ // according to RFC 3986.
+ slug: string;
+
+ // Human-readable name for the token family.
+ name: string;
+
+ // Human-readable description for the token family.
+ description: string;
+
+ // Optional map from IETF BCP 47 language tags to localized descriptions.
+ description_i18n?: { [lang_tag: string]: string };
+
+ // Start time of the token family's validity period.
+ valid_after: Timestamp;
+
+ // End time of the token family's validity period.
+ valid_before: Timestamp;
+
+ // Validity duration of an issued token.
+ duration: RelativeTime;
+
+ // Kind of the token family.
+ kind: TokenFamilyKind;
+
+ // How many tokens have been issued for this family.
+ issued: Integer;
+
+ // How many tokens have been redeemed for this family.
+ redeemed: Integer;
+
+ }
+
+
+
+Deleting token families
+-----------------------
+
+.. http:delete:: [/instances/$INSTANCES]/private/tokenfamilies/$TOKEN_FAMILY_SLUG
+
+ This is used to delete a token family. Issued tokens of this family will not
+ be spendable anymore.
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The backend has successfully deleted the token family.
+
+ :http:statuscode:`404 Not found`:
+ The merchant backend is unaware of the token family or instance.
+
+
+
------------------
The Contract Terms
------------------
@@ -3754,13 +3592,26 @@ The contract terms must have the following structure:
public_reorder_url?: string;
// URL that will show that the order was successful after
- // it has been paid for. Optional. When POSTing to the
- // merchant, the placeholder "${ORDER_ID}" will be
- // replaced with the actual order ID (useful if the
+ // it has been paid for. Optional, but either ``fulfillment_url``
+ // or ``fulfillment_message`` must be specified in every
+ // contract terms.
+ //
+ // If a non-unique fulfillment URL is used, a customer can only
+ // buy the order once and will be redirected to a previous purchase
+ // when trying to buy an order with the same fulfillment URL a second
+ // time. This is useful for digital goods that a customer only needs
+ // to buy once but should be able to repeatedly download.
+ //
+ // For orders where the customer is expected to be able to make
+ // repeated purchases (for equivalent goods), the fulfillment URL
+ // should be made unique for every order. The easiest way to do
+ // this is to include a unique order ID in the fulfillment URL.
+ //
+ // When POSTing to the merchant, the placeholder text "${ORDER_ID}"
+ // is be replaced with the actual order ID (useful if the
// order ID is generated server-side and needs to be
- // in the URL).
- // Note that this placeholder can only be used once.
- // Either fulfillment_url or fulfillment_message must be specified.
+ // in the URL). Note that this placeholder can only be used once.
+ // Front-ends may use other means to generate a unique fulfillment URL.
fulfillment_url?: string;
// Message shown to the customer after paying for the order.
diff --git a/core/api-nonce2ecash.rst b/core/api-nonce2ecash.rst
new file mode 100644
index 00000000..ad7c4997
--- /dev/null
+++ b/core/api-nonce2ecash.rst
@@ -0,0 +1,170 @@
+..
+ This file is part of GNU TALER.
+
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Joel Häberli
+
+===========================
+The nonce2ecash RESTful API
+===========================
+
+.. note::
+
+ **This API is experimental and not yet implemented**
+
+This chapter describe the APIs that third party providers need to integrate to allow
+withdrawals through indirect payment channels like credit cards or ATM.
+
+.. contents:: Table of Contents
+
+--------------
+Authentication
+--------------
+
+Terminals which authenticate against the nonce2ecash API must provide their respective
+access token. Therefore they provide a ``Authorization: Bearer $ACCESS_TOKEN`` header,
+where `$ACCESS_TOKEN`` is a secret authentication token configured by the exchange and
+must begin with the RFC 8959 prefix.
+
+----------------------------
+Configuration of nonce2ecash
+----------------------------
+
+.. http:get:: /config
+
+ Return the protocol version and configuration information about the nonce2ecash API.
+
+ **Response:**
+
+ :http:statuscode:`200 OK`:
+ The exchange responds with a `Nonce2ecashConfig` object. This request should
+ virtually always be successful.
+
+ **Details:**
+
+ .. ts:def:: Nonce2ecashConfig
+
+ interface Nonce2ecashConfig {
+ // Name of the API.
+ name: "taler-nonce2ecash";
+
+ // libtool-style representation of the nonce2ecash protocol version, see
+ // https://www.gnu.org/software/libtool/manual/html_node/Versioning.html#Versioning
+ // The format is "current:revision:age".
+ version: string;
+ }
+
+-----------------------------
+Withdrawing using nonce2ecash
+-----------------------------
+
+Withdrawals with a nonce2ecash are based on withdrawal operations which register a withdrawal identifier
+(nonce) at the nonce2ecash component. The provider must first create a unique identifier for the withdrawal
+operation (the ``WITHDRAWAL_ID``) to interact with the withdrawal operation and eventually withdraw using the wallet.
+
+.. http:post:: /withdrawal-operation
+
+ Initiate the withdrawal operation, identified by the ``WITHDRAWAL_ID``.
+
+ **Request:**
+
+ .. ts:def:: WithdrawRegistration
+
+ interface WithdrawRegistration {
+ // Maps a nonce generated by the provider to a reserve public key generated by the wallet.
+ withdrawal_id: ShortHashCode;
+
+ // Reserve public key generated by the wallet.
+ // According to TALER_ReservePublicKeyP (https://docs.taler.net/core/api-common.html#cryptographic-primitives)
+ reserve_pub_key: EddsaPublicKey;
+
+ // Optional amount for the withdrawal.
+ amount?: Amount;
+
+ // Id of the terminal of the provider requesting a withdrawal by nonce.
+ // Assigned by the exchange.
+ provider_terminal_id: SafeUint64;
+ }
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ The withdrawal was successfully registered.
+ :http:statuscode:`400 Bad request`:
+ The ``WithdrawRegistration`` request was malformed or contained invalid parameters.
+ :http:statuscode:`500 Internal Server error`:
+ The registration of the withdrawal failed due to server side issues.
+
+.. http:get:: /withdrawal-operation/$WITHDRAWAL_ID
+
+ Query information about a withdrawal operation, identified by the ``WITHDRAWAL_ID``.
+
+ **Response:**
+
+ :http:statuscode:`200 Ok`:
+ The withdrawal was found and is returned in the response body as ``Withdrawal``.
+ :http:statuscode:`404 Not found`:
+ nonce2ecash does not have a withdrawal registered with the specified ``WITHDRAWAL_ID``.
+
+ **Details**
+
+ .. ts:def:: Withdrawal
+
+ interface Withdrawal {
+
+ // Reserve public key generated by the wallet.
+ // According to TALER_ReservePublicKeyP (https://docs.taler.net/core/api-common.html#cryptographic-primitives)
+ reserve_pub_key: EddsaPublicKey;
+
+ // Status of the withdrawal
+ // pending : the operation is pending parameters selection (exchange and reserve public key)
+ // selected : the operations has been selected and is pending confirmation
+ // aborted : the operation has been aborted
+ // confirmed: the transfer has been confirmed and registered by the bank
+ withdrawal_status: EddsaPublicKey;
+ }
+
+.. http:post:: /withdrawal-operation/$WITHDRAWAL_ID
+
+ Notifies nonce2ecash about an executed payment for a specific withdrawal.
+
+ **Request:**
+
+ .. ts:def:: PaymentNotification
+
+ interface PaymentNotification {
+
+ // Unique identifier of the provider transaction.
+ provider_transaction_id: string;
+
+ // Specifies the amount which was payed to the provider (without fees).
+ // This amount shall be put into the reserve linked to by the withdrawal id.
+ amount: Amount;
+
+ // Fees associated with the payment.
+ fees: Amount;
+ }
+
+ **Response:**
+
+ :http:statuscode:`204 No content`:
+ nonce2ecash received the ``PaymentNotification`` successfully and will further process
+ the withdrawal.
+ :http:statuscode:`400 Bad request`:
+ The ``PaymentNotification`` request was malformed or contained invalid parameters.
+ :http:statuscode:`404 Not found`:
+ nonce2ecash does not have a withdrawal registered with the specified ``WITHDRAWAL_ID``.
+ :http:statuscode:`500 Internal Server error`:
+ The ``PaymentNotification`` could not be processed due to server side issues.
diff --git a/core/api-sync.rst b/core/api-sync.rst
index 69f59696..c2c86c23 100644
--- a/core/api-sync.rst
+++ b/core/api-sync.rst
@@ -103,6 +103,7 @@ user's location profiles by linking client IP addresses and client
keys.
.. contents:: Table of Contents
+ :local:
.. include:: tos.rst
@@ -114,6 +115,7 @@ Receiving Configuration
.. http:get:: /config
Obtain the key configuration settings of the storage service.
+ This specification corresponds to ``current`` protocol being version **2**.
**Response:**
@@ -139,6 +141,10 @@ Receiving Configuration
// The format is "current:revision:age".
version: string;
+ // URN of the implementation (needed to interpret 'revision' in version).
+ // @since v2, may become mandatory in the future.
+ implementation?: string;
+
}
.. _sync:
diff --git a/core/api-taldir.rst b/core/api-taldir.rst
index 1639e36d..4da9bb02 100644
--- a/core/api-taldir.rst
+++ b/core/api-taldir.rst
@@ -34,6 +34,8 @@ for all details not specified in the individual requests.
The `glossary <https://docs.taler.net/glossary.html#glossary>`_
defines all specific terms used in this section.
+.. contents:: Table of Contents
+ :local:
.. include:: tos.rst
diff --git a/core/index-bank-apis.rst b/core/index-bank-apis.rst
index ad3bae1c..f108df32 100644
--- a/core/index-bank-apis.rst
+++ b/core/index-bank-apis.rst
@@ -27,6 +27,7 @@ Bank RESTful APIs
.. toctree::
:maxdepth: 1
+ intro-bank-apis
api-corebank
api-bank-wire
api-bank-revenue
diff --git a/core/index.rst b/core/index.rst
index d6a20244..8a764c10 100644
--- a/core/index.rst
+++ b/core/index.rst
@@ -32,7 +32,7 @@ protocols using JSON.
.. toctree::
- :maxdepth: 2
+ :maxdepth: 1
api-overview
api-common
diff --git a/core/intro-bank-apis.rst b/core/intro-bank-apis.rst
new file mode 100644
index 00000000..f4307138
--- /dev/null
+++ b/core/intro-bank-apis.rst
@@ -0,0 +1,134 @@
+################################################
+Introduction to Taler (Core-)Banking Integration
+################################################
+
+This chapter provides an overview of the different ways that a bank or core
+banking system can provide integration with GNU Taler.
+
+
+Settlement Account Access
+#########################
+
+To make a GNU Taler deployment possible, the exchange service needs API access
+to a settlement bank account. The settlement account is used to fund digital
+cash withdrawals into users' Taler wallets, as well as to pay out merchants
+that deposited digital cash with the exchange.
+
+The following two operations need to be supported by the settlement account:
+
+1. Querying transactions on the settlement account.
+2. Initiating payments (simple credit transfer).
+
+Note that there is only **one** settlement account needed per Taler deployment.
+There is no per-user settlement account. Thus, creating or managing bank
+accounts is not a requirement.
+
+A core banking system could directly provide the HTTP/REST APIs
+consumed by the Taler exchange (:doc:`api-bank-integration`). Otherwise, an adapter (typically part
+of the libeufin component) needs to be written.
+
+
+Improved Withdrawal Process
+###########################
+
+In principle, any typical account-based (core-)banking system can be used as
+the underlying account-based financial layer for GNU Taler.
+
+However, without extra support from the bank, withdrawals can be difficult for
+unexperienced users. Thus to make sure that a Taler deployment can achieve
+mass adoption from non-technical users, extra integration by the bank / core
+banking system should be provided.
+
+Withdrawals without any extra support from the core banking system require the
+user to make a transaction to a particular bank account (i.e. the exchange's
+settlement account) with a rather long cryptographic identifier in the subject.
+This identifier is generated by the user's wallet when initiating a withdrawal
+from the wallet application. If the user misspells the identifier, the payment
+will be sent back automatically by the exchange.
+
+However, until the wire transfer is successfully completed, the wallet has no
+information about whether the transfer was already made by the user or if it
+was even made correctly. This makes it hard to show accurate information to
+the user about the status of withdrawing digital cash into their Taler wallet.
+
+
+Withdrawal Bank-Integration API
+===============================
+
+A core banking system can provide better support for GNU Taler withdrawals by
+allowing users to initiate *Taler withdrawal operations* from their bank
+account (e.g. in their banking app or online banking). A Taler withdrawal
+operation has a unique identifier (chosen/generated by the core banking
+system), called the WOPID (Withdrawal Operation Identifier).
+
+The core banking system can provide a (public) API to access withdrawal
+operations (:doc:`api-bank-integration`).
+
+The wallet learns the WOPID and API address via a ``taler://withdraw/...``
+QR-Code or link.
+
+The wallet generates the cryptographic identifiers required for the withdrawal,
+allows the user to choose an exchange (the bank may suggest a default one!),
+and then submits this information (chosen exchange, reserve public key) for the
+respective WOPID to the bank-integration API.
+
+The user can then confirm the withdrawal by completing the 2FA of
+their bank account for the operation. (Alternatively, the user can abort the operation
+in their banking client / 2FA app.)
+
+Upon completion of the 2FA / confirmation step, the core banking system
+initiates a credit transfer for the withdrawal operations (with the chosen
+exchange as the creditor and the cryptographic identifier / reserve pub in the
+subject). Afterwards, the withdrawal operation is marked as done.
+
+The wallet can continuously query the status of the withdrawal operation (via
+the API address and WOPID).
+In the Taler wallet app, the user can now always see the accurate status of
+their withdrawal operation (e.g. bank transfer done, aborted, confirmation/2FA
+pending).
+
+
+Payto-URI Integration
+=====================
+
+When initiating a withdrawal from the Taler wallet, the wallet can generate a
+payto:// link or QR code (see `RFC 8905 <https://www.rfc-editor.org/rfc/rfc8905.txt>`_)
+with the payment information necessary to make a
+credit transfer to the exchange's settlement account.
+
+Banking apps may provide integration here simply by handling payto:// URIs.
+
+Integration based on payto:// URIs prevents mistakes in typing the
+cryptographic identifier and bank account number during withdrawals. However,
+it still does not allow the wallet do accurately show the status of a
+withdrawal to the user.
+
+
+Future: Intent-Based Integration on Android
+===========================================
+
+(This type of integration is currently not specified, but planned for the future.)
+
+On the Android platform, applications can communicate via
+`Intents <https://developer.android.com/guide/components/intents-filters>`_.
+That would allow the Taler wallet to open a credit transfer dialog in a
+supported banking app to fund a withdrawal. The banking app can send the
+status of the credit transfer (confirmed/aborted by the user) back to the
+wallet, which can then show more accurate status information about the
+withdrawal to the user.
+
+
+Integration for Merchants
+#########################
+
+The Taler merchant backend has the option to connect to what
+we call the :doc:`Bank Revenue API <api-bank-revenue>`.
+
+A core banking system may provide this API to merchants that have a business
+account at the that bank. The API provides read-only access to incoming
+transactions on the merchant bank account.
+
+It allows merchants to easily and automatically reconcile incoming bank
+transfers from the Taler exchange's settlement account with the respective
+Taler payments. Usually multiple Taler payments are aggregated into one larger
+payment in the underlying banking layer.
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..01e3ec7f 100644
--- a/design-documents/023-taler-kyc.rst
+++ b/design-documents/023-taler-kyc.rst
@@ -19,7 +19,7 @@ Requirements
The solution should support fees to be paid by the user for the KYC process (#7365).
-Taler needs to run KYC checks in the following circumstances:
+Taler needs to take *measures* based on the following primary *triggers*:
* Customer withdraws money over a monthly threshold
@@ -40,24 +40,161 @@ 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)
+* Import of new sanctions lists and triggering of measures against matches of existing
+ customer records against the list
+
+
+For the different *measures*, there are various different possible KYC/AML *checks*
+that could happen:
+
+* In-person validation by AML staff
+* Various forms to be filled by AML staff
+* Validation involving local authorities and post-office
+* Online validation, sometimes with multiple options (like KYC for multiple people):
+
+ * Forms to be supplied by user (different types of ID)
+ * Interactive video
+ * Documents to be supplied (business register)
+ * Address validation (e-mail or phone or postal)
+
+Additionally, the process is dynamic and conditional upon various decisions:
+
+* Individual vs. business
+* PEP or non-PEP
+* Hit on sanctions list
+* Type of business (trust, foundation, listed on stock market, etc.)
+* Need for plausibilization (via documents by user or staff research)
+* Periodic updates (of customer data, of sanction lists) and re-assessment
+
+There are also various *outcomes*:
+
+* normal operation (with expiration date)
+* normal operation but with AML staff investigating (new measure)
+* held, requesting customer documentation (new measure)
+* held, AML staff reviewing evidence for plausibilization (new measure)
+* automatically frozen until certain day (due to sanctions)
+* institutionally frozen until certain day (due to order by state authority)
+
+The outcome of a *check* can trigger further *measures* (including
+expiration of the outcome state).
+
+
+Finally, we need to produce statistics:
+
+* number of incidents reported (voluntarily, required)
+* number of business relationships at any point in time
+* number of risky business relationships (PEP, etc.)
+* number of frozen transactions (authority vs. sanction) with start-date and end-date
+* start-data and end-date of relationships (data retained for X years after end of relationship)
+
+For this high-level monitoring, we need certain designated critical events to
+be tracked in the system statistics:
+
+ * account opened
+ * set to high risk
+ * set to low risk
+ * suspicious activity report filed with authority
+ * account frozen
+ * account unfrozen
+ * account closed
+
+As a result, we largely end up in a large state machine where the AML staff has
+serious flexibiltiy while the user needs guidance as to the possible next moves
+and/or to the current state of their account (where some information must not be
+disclosed).
Proposed Solution
=================
+We allow certain *conditions* to *trigger* a single specific *measures*.
+For the different *measures*, we define:
+
+* Who has to do something (AML staff, user, nobody)
+* Contextual input data to be provided (with templating, e.g. amount set dynamically based on the *trigger*)
+* A *check* to be performed
+* A *program* that uses data from the *check* as well as *context* data
+ to determine an *outcome* which is the specific operational state
+ (normal, held on staff, held on user, frozen, etc.) the account is to transition to
+* What information about the state to show to the user (normal, information required, pending, etc.)
+
+* For user-interactive checks:
+
+ * Web page template with instructions to render (with either a form to fill or links to external checks);
+ here the context could provide an array of choices!
+ * Possibly an external check to set up (if any); for cost-reasons, we should only do one at a time,
+ and probably should then always redirect the browser to that check.
+ * A *measure* to take on failure of the external check
+
+* For (AML) staff-interactive checks:
+
+ * UI to file forms and upload documentation (without state transition)
+ * UI to decide on next measure (providing context); here, the exchange needs
+ to expose the list of available *measures* and required *context* for each
+
+* Non-interactive measures (normal operation, account frozen) need:
+
+ * Expiration time (in context)
+ * Measure to trigger upon expiration, again with context
+ (renew documents, resume normal operation, etc.)
+
+
+We need some customer-driven interactivity in KYB/KYC process, for example the
+user may need to be given choices (address vs. phone, individual vs. business,
+order in which to provide KYC data of beneficiaries). As a result, the
+exchange needs to serve some "master" page for measures where the user is
+shown the next step(s) or choices (which person to collect KYC data on,
+whether to run challenger on phone number of physical address, etc.).
+That page should also potentially contain a form to allow the customer to
+directly upload documents to us (like business registration) instead of to
+some KYC provider. This is because KYC providers may not be flexible
+enough.
+
+Similarly, the AML staff will need to be able to trigger rather complex
+KYB/KYC processes, like "need KYC on X and Y and Z" or "phone number or
+mailing address" or "please upload form A/T/S". Here in particular it
+should be possible to request not only filled forms, but arbitrary
+documents.
+
+
+Documentation
+^^^^^^^^^^^^^
+
+* We must define risk-profile (902.4, 905.1)
+* We must document the specific setup, likely not just the INI file
+* We probably should have some key AMLA file attributes, such as:
+
+ * File opened, file closed (keep data for X years afterwards!)
+ * low-risk or high-risk business relationship
+ * PEP status
+ * business domain
+ * authority notification dates (possibly multiple) with
+ voluntary or mandatory notification classification
+
+* There must be a page with an overview of AMLA files with opening
+ and closing dates and an easy way to determine for any day the
+ number of open AMLA files
+
+* Technically, we also need a list of at-risk transactions and of
+ frozen transactions, but given that we can really only freeze
+ on an account-basis, I think there is nothing to do here
+
+
Terminology
^^^^^^^^^^^
-* **Check**: A check establishes a particular attribute of a user, such as their name based on an ID document and lifeness, mailing address, phone number, taxpayer identity, etc.
+* **Check**: A check establishes a particular attribute of a user, such as their name based on an ID document and lifeness, mailing address, phone number, taxpayer identity, etc. Checks may be given *context* (such as whether a customer is an individual or a business) to run correctly. Checks can also be AML staff inserting information for plausibilization. Checks result in an *outcome* being decided by an external AML *program*.
* **Condition**: A condition specifies when KYC is required. Conditions include the *type of operation*, a threshold amount (e.g. above EUR:1000) and possibly a time period (e.g. over the last month).
* **Configuration**: The configuration determines the *legitimization rules*, and specifies which providers offer which *checks* at what *cost*.
+* **Context**: Context is information provided as input into a *check* and *program* to customize their execution. The context is initially set by the *trigger*, but may evolve as the *account* undergoes *measures*. For each *check* and *program*, the required *context* data must be specified.
+
* **Cost**: Metric for the business expense for a KYC check at a certain *provider*. Not in any currency, costs are simply relative and non-negative values. Costs are considered when multiple choices are allowed by the *configuration*.
* **Expiration**: KYC legitimizations may be outdated. Expiration rules determine when *checks* have to be performed again.
@@ -66,8 +203,14 @@ Terminology
* **Logic**: Logic refers to a specific bit of code (realized as an exchange plugin) that enables the interaction with a specific *provider*. Logic typically requires *configuration* for access control (such as an authorization token) and possibly the endpoint of the specific *provider* implementing the respective API.
+* **Measure**: Describes the possible outgoing edges from one state in the state machine (including how to show the current state). Each edge is given some *context* and a *check* to be performed as well as a *program* to decide the *outcome* and the next *measure*.
+
+* **Outcome**: Describes the account state that an account ends up in due to the result of a *check*. Outcomes can be that an account is frozen (no transactions possible until freeze expires), held (no transactions possible until another *measure* has been taken), or operating normally.
+
* **Provider**: A provider performs a specific set of *checks* at a certain *cost*. Interaction with a provider is performed by provider-specific *logic*.
+* **Program**: An AML helper *program* is given *context* about the current state of an account and the data from a *check* to compute the *outcome*. For example, a *program* may look at the "PEP" field of a KYC check and decide if the outcome is to put the account into ``normal`` or ``held-for-manual-review`` state. A *program* operating on an AML form filed by AML staff will likely be trivial and directly apply the explicit decision taken by the staff member.
+
* **Type of operation**: The operation type determines which Taler-specific operation has triggered the KYC requirement. We support four types of operation: withdraw (by customer), deposit (by merchant), P2P receive (by wallet) and (high) wallet balance.
@@ -103,8 +246,9 @@ Access is ``authenticated`` by also passing the hash of the payto://-URI.
initiate a KYC process are not very sensitive.) Given this triplet, the
``/kyc-check/`` endpoint returns either the (positive) KYC status or redirects
the client (202) to the next required stage of the KYC process. The
-redirection must be for an HTTP(S) endpoint to be triggered via a simple HTTP GET. As this endpoint is involved in every KYC check at the beginning, this is also the place where we can
-integrate the payment process for the KYC fee.
+redirection must be for an HTTP(S) endpoint to be triggered via a simple HTTP
+GET. As this endpoint is involved in every KYC check at the beginning, this
+is also the place where we can integrate the payment process for the KYC fee.
The specific KYC provider to be executed depends on the configuration (see
below) which specifies a ``$PROVIDER_SECTION`` for each authentication procedure.
@@ -183,21 +327,14 @@ Configuration Options
The configuration specifies a set of providers, one per configuration section:
[kyc-provider-$PROVIDER_ID]
-# How expensive is it to use this provider?
-# Used to pick the cheapest provider possible.
-COST = NUMBER
# Which plugin is responsible for this provider?
LOGIC = PLUGIN_NAME
-# Which type of user does this provider handle?
-# Either INDIVIDUAL or BUSINESS.
-USER_TYPE = INDIVIDUAL
-# Which checks does this provider provide?
-# List of strings, no specific semantics.
-PROVIDED_CHECKS = SMS GOVID PHOTO
+# Which check does this provider provide?
+PROVIDED_CHECK = SMS
# Plus additional logic-specific options, e.g.:
AUTHORIZATION_TOKEN = superdupersecret
FORM_ID = business_legi_form
-# How long is the check considered valid?
+# How long is the data from this check considered valid?
EXPIRATION = DURATION
The configuration also specifies a set of legitimization
@@ -208,10 +345,8 @@ requirements, one per configuration section:
# Must be one of WITHDRAW, DEPOSIT, P2P-RECEIVE
# or WALLET-BALANCE.
OPERATION_TYPE = WITHDRAW
-# Required checks to be performed.
-# List of strings, must individually match the
-# strings in one or more provider's PROVIDED_CHECKS.
-REQUIRED_CHECKS = SMS GOVID
+# Required measure to be performed.
+REQUIRED_MEASURE = SWISSNESS
# Threshold amount above which the legitimization is
# triggered. The total must be exceeded in the given
# timeframe. Can be 'forever'.
@@ -222,6 +357,29 @@ THRESHOLD = AMOUNT
TIMEFRAME = DURATION
+Finally, the configuration specifies a set of measures,
+one per configuration section:
+
+[aml-measure-$MEASURE_NAME]
+# Program to run on the context and check data to
+# determine the outcome and next measure.
+PROGRAM = /bin/true
+# Check to run as part of this measure. Optional.
+CHECK = CHECK_NAME
+# Form to show to the user as part of this measure.
+FORM = FORM_NAME
+
+For each FORM_NAME, there then must be
+
+* A HTML template (Mustach) that is instantiated with the
+ JSON form context to produce a page to be shown to the user
+* A helper program (named after the form) that can:
+
+ * Generate a list of required context attributes
+ for the helper (!)
+ * Validate and convert an input JSON with context
+ attributes into the JSON form context
+
Exchange Database Schema
^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/design-documents/024-age-restriction.rst b/design-documents/024-age-restriction.rst
index 280a4f39..0445aa6d 100644
--- a/design-documents/024-age-restriction.rst
+++ b/design-documents/024-age-restriction.rst
@@ -247,7 +247,7 @@ changed since the given timestamp.
// Similar as for ``.denoms``, if the query parameter ``last_issue_date``
// was provided by the client, the exchange will only return the keys that
// have changed since the given timestamp.
- age_restricted_denoms: Denom[];
+ age_restricted_denoms: DenomCommon[];
//...
}
@@ -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/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/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/046-mumimo-contracts.rst b/design-documents/046-mumimo-contracts.rst
index 5bc3d25a..714b5822 100644
--- a/design-documents/046-mumimo-contracts.rst
+++ b/design-documents/046-mumimo-contracts.rst
@@ -62,8 +62,6 @@ We want Taler to support various interesting use-cases:
acquired (i.e., not brought from home or stolen from a stack of dirty items)
and incentivizes return after use.
-TODO: add more use-cases here!
-
Proposed Solution
=================
@@ -145,6 +143,33 @@ The contract terms v1 will have the following structure:
// More info about the merchant (same as in v0).
merchant: Merchant;
+ // Human-readable description of the contract.
+ summary: string;
+
+ // Map from IETF BCP 47 language tags to localized summaries.
+ summary_i18n?: { [lang_tag: string]: string };
+
+ // URL that will show that the order was successful after
+ // it has been paid for. Optional. When POSTing to the
+ // merchant, the placeholder "${ORDER_ID}" will be
+ // replaced with the actual order ID (useful if the
+ // order ID is generated server-side and needs to be
+ // in the URL).
+ // Note that this placeholder can only be used once.
+ // Either fulfillment_url or fulfillment_message must be specified.
+ fulfillment_url?: string;
+
+ // Message shown to the customer after paying for the order.
+ // Either fulfillment_url or fulfillment_message must be specified.
+ fulfillment_message?: string;
+
+ // Map from IETF BCP 47 language tags to localized fulfillment
+ // messages.
+ fulfillment_message_i18n?: { [lang_tag: string]: string };
+
+ // List of products that are part of the purchase (see `Product`).
+ products: Product[];
+
// After this deadline has passed, no refunds will be accepted.
refund_deadline: Timestamp;
@@ -184,83 +209,27 @@ The contract terms v1 will have the following structure:
// signing the deposit confirmation.
choices: ContractChoice[];
+ // Map from authority labels to meta data about the
+ // respective token authority.
+ token_types: { [authority_label: string]: TokenAuthority };
+
// Extra data that is only interpreted by the merchant frontend.
// Useful when the merchant needs to store extra information on a
// contract without storing it separately in their database.
extra?: any;
- // Fee limits and wire account details by currency.
- limits: { [currency:string] : CurrencyLimit };
- }
-
-.. ts:def:: CurrencyLimit
-
- interface CurrencyLimit {
-
- // The hash of the merchant instance's wire details.
- h_wire: HashCode;
-
- // Wire transfer method identifier for the wire method associated with ``h_wire``.
- // The wallet may only select exchanges via a matching auditor if the
- // exchange also supports this wire method.
- // The wire transfer fees must be added based on this wire transfer method.
- wire_method: string;
-
// Maximum total deposit fee accepted by the merchant for this contract.
max_fee: Amount;
- // Maximum wire fee accepted by the merchant (customer share to be
- // divided by the ``wire_fee_amortization`` factor, and further reduced
- // if deposit fees are below ``max_fee``). Default if missing is zero.
- max_wire_fee: Amount;
-
- // Over how many customer transactions does the merchant expect to
- // amortize wire fees on average? If the exchange's wire fee is
- // above ``max_wire_fee``, the difference is divided by this number
- // to compute the expected customer's contribution to the wire fee.
- // The customer's contribution may further be reduced by the difference
- // between the ``max_fee`` and the sum of the actual deposit fees.
- // Optional, default value if missing is 1. 0 and negative values are
- // invalid and also interpreted as 1.
- wire_fee_amortization: number;
-
// Exchanges that the merchant accepts for this currency.
exchanges: Exchange[];
}
-
.. ts:def:: ContractChoice
interface ContractChoice {
- // Human-readable description of the choice.
- summary: string;
-
- // Map from IETF BCP 47 language tags to localized summaries.
- summary_i18n?: { [lang_tag: string]: string };
-
- // URL that will show that the order was successful after
- // it has been paid for. Optional. When POSTing to the
- // merchant, the placeholder "${ORDER_ID}" will be
- // replaced with the actual order ID (useful if the
- // order ID is generated server-side and needs to be
- // in the URL).
- // Note that this placeholder can only be used once.
- // Either fulfillment_url or fulfillment_message must be specified.
- fulfillment_url?: string;
-
- // Message shown to the customer after paying for the order.
- // Either fulfillment_url or fulfillment_message must be specified.
- fulfillment_message?: string;
-
- // Map from IETF BCP 47 language tags to localized fulfillment
- // messages.
- fulfillment_message_i18n?: { [lang_tag: string]: string };
-
- // List of products that are part of the purchase (see `Product`).
- products: Product[];
-
// List of inputs the wallet must provision (all of them) to
// satisfy the conditions for the contract.
inputs: ContractInput[];
@@ -269,17 +238,13 @@ The contract terms v1 will have the following structure:
// once the contract is paid.
outputs: ContractOutput[];
- // Map from authority labels to meta data abou the
- // respective token authority.
- token_types: { [authority_label: TokenAuthority };
-
}
.. ts:def:: ContractInput
type ContractInput =
- | ContractInputRation
- | ContractInputToken;
+ ContractInputRation |
+ ContractInputToken;
.. ts:def:: ContractInputRation
@@ -305,9 +270,9 @@ The contract terms v1 will have the following structure:
type: "token";
- // Hash over the public key used to sign the
- // type of subscription token required.
- h_issuer: HashCode;
+ // Label of the token authority in the
+ // 'token_types' map on the top-level.
+ authority_label: string;
// Number of tokens of this type required.
// Defaults to one if the field is not provided.
@@ -318,17 +283,17 @@ The contract terms v1 will have the following structure:
.. ts:def:: ContractOutput
type ContractOutput =
- | ContractOutputCurrency
- | ContractOutputTaxReceipt
- | ContractOutputToken;
+ ContractOutputCoin |
+ ContractOutputTaxReceipt |
+ ContractOutputToken;
-.. ts:def:: ContractOutputCurrency
+.. ts:def:: ContractOutputCoin
- interface ContractOutputCurrency {
+ interface ContractOutputCoin {
- type: "currency";
+ type: "coins";
- // Amount of currency that will be yielded.
+ // Amount of coins that will be yielded.
// This excludes any applicable withdraw fees.
brutto_yield: Amount;
@@ -360,24 +325,21 @@ The contract terms v1 will have the following structure:
// 'token_types' map on the top-level.
authority_label: string;
- // Must a wallet understand this token type to
- // process contracts that consume or yield it?
- critical: boolean;
+ // Number of tokens to be yelded.
+ // Defaults to one if the field is not provided.
+ number?: Integer;
- // Information about the class of token that will
- // be yielded.
- details: OutputTokenClass;
}
-.. ts:def:: OutputTokenClass
+.. ts:def:: TokenClass
- type OutputTokenClass =
- | OutputTokenClassSubscription
- | OutputTokenClassDiscount
+ type TokenClass =
+ TokenClassSubscription
+ | TokenClassDiscount
-.. ts:def:: OutputTokenClassSubscription
+.. ts:def:: TokenClassSubscription
- interface OutputTokenClassSubscription {
+ interface TokenClassSubscription {
class: "subscription";
@@ -396,9 +358,9 @@ The contract terms v1 will have the following structure:
};
-.. ts:def:: OutputTokenClassDiscount
+.. ts:def:: TokenClassDiscount
- interface OutputTokenClassDiscount {
+ interface TokenClassDiscount {
class: "discount";
@@ -433,6 +395,13 @@ The contract terms v1 will have the following structure:
// When will tokens signed by this key expire?
token_expiration: Timestamp;
+ // Class-specific information of the token
+ details: TokenClass;
+
+ // Must a wallet understand this token type to
+ // process contracts that consume or yield it?
+ critical: boolean;
+
// Number of tokens issued according to ASS authority
// FIXME: this is still rather speculative in the design...
ass?: Integer;
@@ -452,8 +421,8 @@ The contract terms v1 will have the following structure:
.. ts:def:: TokenSignerPublicKey
type TokenSignerPublicKey =
- | DenomGroupRsa
- | DenomGroupCs;
+ DenomGroupRsa |
+ DenomGroupCs;
TODO: may want to do a deep copy and rename
DenomGroup* to TokenSignerPublicKey* here.
@@ -472,10 +441,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 +449,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 +459,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/053-wallet-ui.rst b/design-documents/053-wallet-ui.rst
index 5891eb37..99640ceb 100644
--- a/design-documents/053-wallet-ui.rst
+++ b/design-documents/053-wallet-ui.rst
@@ -4,7 +4,7 @@ DD 53: Wallet UI Design
Summary
=======
-This document proposes designs wallet UI. It defines what Android, iOS and
+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
@@ -12,8 +12,8 @@ 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
+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.
@@ -25,7 +25,7 @@ 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.
+ 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
@@ -40,25 +40,29 @@ 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
+* **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,
+* **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
+* **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
+
+* **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
+* **Screenshots**. Should be provided for all wallet implementations and kept
+ up to date, to ensure that they can be used to aid in UI/UX and QA
+ discussions.
+
+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
+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.
@@ -70,194 +74,589 @@ Common definition:
Proposed Solutions
==================
-List of dall screens with the defined properties
+List of all screens with the defined properties.
+
+.. _balance-list-ref:
+
+balance-list
+------------
+
+This screen shows a currency-scoped list of the balances stored in the wallet,
+and includes information about the total, incoming, and outgoing amounts, as
+well as the currency scope information for each item.
+
+Info
+^^^^
+
+* List of balances in the wallet, where each item contains:
+
+ * Total amount with currency (see :doc:`051-fractional-digits`).
+ * Incoming amount (money pending to arrive).
+ * Outgoing amount (money pending to leave).
+ * Currency scope information (see :doc:`035-regional-currencies`).
+
+Actions
+^^^^^^^
+
+* **View transactions**. Clicking on a balance item should take you to the
+ transaction list (:ref:`transaction-list-ref`) associated with that balance.
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+----------------------------------------------------------------+
+| Platform | Screenshot |
++===========+================================================================+
+| WebEx | .. image:: ../screenshots/balance-list-firefox-latest.png |
++-----------+----------------------------------------------------------------+
+| Android | .. image:: ../screenshots/balance-list-android-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/balance-list-1-ios-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/balance-list-2-ios-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------+
+
+
+.. _transaction-list-ref:
+
+transaction-list
+----------------
+
+This screen shows a list of all the transactions associated with a given
+currency scope.
+
+Info
+^^^^
+
+* Total amount and currency (see :doc:`051-fractional-digits`).
+* List of transactions associated with the currency scope, with pending
+ transactions on top, and where each item contains the following:
+
+ * **Title**. It depends on the transaction type. It can be the exchange URL
+ (e.g. exchange.demo.taler.net), a description of the type of transaction
+ (e.g. Deposit, Invoice, Payment, etc.), the name of the merchant paid
+ (e.g. Essay Shop), etc.
+ * **Summary**. It provides complementary information about the transaction
+ for the user, such as the status of the transaction (e.g. “Waiting for
+ confirmation,” “KYC required,” an error message, etc.). (The summary is
+ provided by wallet-core, along with internationalized versions.)
+ * **Timestamp**. The moment when the transaction was created. Ideally, it
+ should be shown with minimal precision, only showing the minutes, hours or
+ days that have elapsed.
+ * **Amount**. The positive or negative impact that the transaction has in
+ the total balance of the currency scope. It should be made clear whether
+ the amount of the transaction is positive or negative, ideally with a sign
+ (+/-) and a color (green/red).
+ * **Pending**. It should be indicated whether the transaction is pending or
+ finished. This can be done with a small badge and with different colors,
+ however, it should be always clear and communicate the message
+ effectively.
+
+Actions
+^^^^^^^
+
+* **Send**. The transaction list should include a button that allows the user
+ to initiate transactions that result in money being sent, such as deposits
+ and peer push payments.
+* **Receive**. The transaction list should also include a button that allows
+ the user to initiate transactions that result in money being received, such
+ as withdrawals and peer pull payments.
+* **View transaction details**. When clicking on a transaction, the user
+ should be taken to its corresponding transaction details depending on the
+ type of the transaction clicked.
+* **Select transaction(s)**. The user should be able to select one or more
+ transactions to perform specific bulk actions, such as deleting. The
+ interaction that triggers this action might differ across platforms. For
+ example, in Android this would be achieved by double pressing a transaction
+ (to activate selection mode) and then clicking other transactions to be
+ selected. On iOS, this could be achieved using an “Edit” button in the
+ toolbar that reveals checkboxes that allow the user to select the desired
+ transactions.
+* **Delete transaction(s)**. This could be achieved in bulk via selection
+ mode, or individually for each transaction via a menu or a button. Either
+ way, performing a deletion should always show a confirmation menu before
+ doing the actual deletion.
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+----------------------------------------------------------------+
+| Platform | Screenshot |
++===========+================================================================+
+| WebEx | .. image:: ../screenshots/transaction-list-firefox-latest.png |
++-----------+----------------------------------------------------------------+
+| Android | .. image:: ../screenshots/transaction-list-android-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/transaction-list-ios-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------+
+
+
+.. _cta-withdraw-ref:
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.
+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
+Info
+^^^^
-``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
+* exchange to be used showing the URL
+* table of details of the operation: use the :ref:`operation-table-details-ref` 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
-``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``
+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 :ref:`accept-tos-ref` screen
+* **cancel**: user will be redirected to ``balance``
.. attention::
User should be able to play with the amount, not possible in the current design
+Screenshots
+^^^^^^^^^^^
+
++-----------+----------------------------------------------------------------+
+| Platform | Screenshot |
++===========+================================================================+
+| WebEx | .. image:: ../screenshots/cta-withdraw-firefox-latest.png |
++-----------+----------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-withdraw-2-android-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-withdraw-ios-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------+
+
+
+.. _cta-wire-transfer-ref:
+
+cta-wire-transfer
+-----------------
+
+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
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-wire-transfer-firefox-latest.png |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-wire-transfer-1-android-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/cta-wire-transfer-2-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-wire-transfer-1-ios-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/cta-wire-transfer-2-ios-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/cta-wire-transfer-3-ios-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+
+
+.. _cta-withdraw-done-ref:
+
+cta-withdraw-done
+-----------------
+
+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
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-withdraw-done-firefox-latest.png |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-withdraw-done-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-withdraw-done-ios-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+
+
+.. _cta-url-entry-ref:
+
+cta-url-entry
+-------------
+
+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
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-url-entry-firefox-latest.png |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-url-entry-1-android-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/cta-url-entry-2-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+
+
+.. _cta-payment-ref:
+
cta-payment
-------------
+-----------
+
+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 :ref:`operation-table-details-ref` 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 :ref:`cta-withdraw-ref`
+* **cancel**: user will be redirected to ``balance``
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-payment-firefox-latest.png |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-payment-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-payment-ios-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
-``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``
+
+.. _cta-payment-paid-ref:
+
+cta-payment-paid
+----------------
+
+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 :ref:`operation-table-details-ref` 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``
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-payment-paid-firefox-latest.png |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-payment-paid-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-payment-paid-1-ios-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/cta-payment-paid-2-ios-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+
+
+.. _cta-deposit-ref:
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.
+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
+Info
+^^^^
-``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``
+* bank account where the money is going to
+* table of details of the operation: use the :ref:`operation-table-details-ref` 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
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-deposit-firefox-latest.png |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-deposit-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-deposit-1-ios-latest.png |
+| | :width: 30% |
+| | .. image:: ../screenshots/cta-deposit-2-ios-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+
+
+.. _cta-peer-pull-initiate-ref:
+
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.
+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
+Info
+^^^^
-``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
+* exchange to be used showing the URL
+* table of details of the operation: use the :ref:`operation-table-details-ref` 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``
+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 :ref:`accept-tos-ref` 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?
+Screenshots
+^^^^^^^^^^^
+
++-----------+----------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+======================================================================+
+| WebEx | .. image:: ../screenshots/cta-peer-pull-initiate-firefox-latest.png |
++-----------+----------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-peer-pull-initiate-android-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-peer-pull-initiate-ios-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------------+
+
+
+.. _cta-peer-pull-confirm-ref:
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.
+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 :ref:`operation-table-details-ref` screen
+* expiration: absolute time/date after which the invoice is not valid anymore
-``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
+^^^^^^^
-``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``
+* **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 :ref:`cta-withdraw-ref`
+* **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.
+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
+Info
+^^^^
-``Inputs``:
- * subject: short description of the transaction
- * expiration: absolute time/date after which the transfer 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
- * cancel: user will be redirected to ``balance``
+Inputs
+^^^^^^
-cta-peer-push-confirm
----------------------
+* **subject**: short description of the transaction
+* **expiration**: absolute time/date after which the transfer is not valid anymore
-``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.
+Actions
+^^^^^^^
-``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
+* **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``
-``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``
+Screenshots
+^^^^^^^^^^^
-cta-reward
------------
++-----------+----------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+======================================================================+
+| WebEx | .. image:: ../screenshots/cta-peer-push-initiate-firefox-latest.png |
++-----------+----------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-peer-push-initiate-android-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-peer-push-initiate-ios-latest.png |
+| | :width: 30% |
++-----------+----------------------------------------------------------------------+
+
+
+.. _cta-peer-push-confirm-ref:
+
+cta-peer-push-confirm
+---------------------
-``Description``: this screen is used for the confirmation of the acceptance of
-a reward from a merchant.
-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.
+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``:
- * amount: effective amount to receive
- * exchange: from where this money comes from
- * merchant: offering the reward
+Info
+^^^^
-``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``
+* 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 :ref:`accept-tos-ref` screen
+* **cancel**: user will be redirected to ``balance``
+
+.. _operation-table-details-ref:
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)
+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
+^^^^^^
-``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 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
+ * payment -> Price
* deposit -> Send
* peer-pull-credit -> Invoice
* peer-pull-debit -> Invoice
@@ -267,23 +666,45 @@ Initial amount label by operation:
* refund -> Refund
+.. _accept-tos-ref:
+
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)
+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
+^^^^^^
-``Inputs``:
- * format: allow the selection of a ToS format
- * languange: allow the selection of a languange different from system lang
+* **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
+
+Screenshots
+^^^^^^^^^^^
+
++-----------+------------------------------------------------------------------+
+| Platform | Screenshot |
++===========+==================================================================+
+| WebEx | .. image:: ../screenshots/cta-accept-tos-firefox-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| Android | .. image:: ../screenshots/cta-accept-tos-android-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
+| iOS | .. image:: ../screenshots/cta-accept-tos-ios-latest.png |
+| | :width: 30% |
++-----------+------------------------------------------------------------------+
-``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
Q / A
=====
-
diff --git a/design-documents/054-dynamic-form.rst b/design-documents/054-dynamic-form.rst
index 6ff84d41..d93b3684 100644
--- a/design-documents/054-dynamic-form.rst
+++ b/design-documents/054-dynamic-form.rst
@@ -51,7 +51,7 @@ 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
+.. code-block:: typescript
interface FormType<T extends object> {
value: Partial<T>;
@@ -82,7 +82,7 @@ The field type ``AmountJson`` and ``AbsoluteTime`` are opaque since field is use
The form can be instanciated using
-.. code-block:: javascript
+.. code-block:: typescript
import { FormProvider } from "@gnu-taler/web-util/browser";
@@ -90,7 +90,7 @@ The form can be instanciated using
Then the field component can access all the properties by the ``useField(name)`` hook,
which will return
-.. code-block:: javascript
+.. code-block:: typescript
interface InputFieldHandler<Type> {
value: Type;
@@ -116,10 +116,10 @@ A set of common form field exist in ``@gnu-taler/web-util``:
and should be used inside a ``Form`` context.
-.. code-block:: javascript
+.. code-block:: none
function MyFormComponent():VNode {
- return <FormProvider >
+ return <FormProvider>
<InputAmount name="amount" />
<InputText name="subject" />
<button type="submit"> Confirm </button>
@@ -132,7 +132,7 @@ Example
Consider a form shape represented by the TypeScript type:
-.. code-block:: javascript
+.. code-block:: typescript
type TheFormType = {
name: string,
@@ -148,7 +148,7 @@ Consider a form shape represented by the TypeScript type:
An example instance of this form could be:
-.. code-block:: javascript
+.. code-block:: typescript
const theFormValue: TheFormType = {
name: "Sebastian",
diff --git a/design-documents/055-wallet-problem-report.rst b/design-documents/055-wallet-problem-report.rst
new file mode 100644
index 00000000..2fd7a221
--- /dev/null
+++ b/design-documents/055-wallet-problem-report.rst
@@ -0,0 +1,114 @@
+DD 55: Wallet Problem Reports
+#############################
+
+.. note::
+
+ **Status**: Early work in progress / DD number reservation.
+
+.. warning::
+
+ We concluded that we don't need the problem reports feature right now,
+ as all cases we care about are already covered by something else.
+
+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
+----------------
+
+(Currently we don't have any good examples where this is actually needed.)
+
+Examples of what should NOT be a report
+---------------------------------------
+
+* money lost due to the exchange stopping to offer a denomination
+
+ * => Should be a transactions item
+
+* money locked behind a (long) pending refresh
+
+ * => Should be a pending transaction
+
+* money lost due to a permanently failing refresh
+
+ * => pending or final transaction item
+
+* money lost due to expired denominations (auto-refresh wasn't done fast enough)
+
+ * => transaction item
+
+* a denomination changed its info (expiration, fees)
+
+ * => exchange entry state
+
+* Important information about the exchange changed (master pub, accounts, keys)
+
+ => exchange entry state
+
+
+Definition of Done
+==================
+
+TBD.
+
+Alternatives
+============
+
+* Report problems with an API specific to each resource (exchange entry, transaction, ...)
+* Have an *alerts* API that returns alerts to the client that the client can show to to the user,
+ but that a user can't interact with.
+
+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 91bfce4c..454564d0 100644
--- a/design-documents/index.rst
+++ b/design-documents/index.rst
@@ -66,4 +66,5 @@ Design documents that start with "XX" are considered deprecated.
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
diff --git a/design-documents/wallet-screenshots/webex-wallet/READE b/design-documents/wallet-screenshots/webex-wallet/READE
new file mode 100644
index 00000000..597fa22e
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/READE
@@ -0,0 +1,22 @@
+Wallet Web Extension screenshots
+--------------------------------
+
+Screenshoots are organized by common use case using
+the happy path to ilustrate the user flow:
+
+ * withdrawal: starts from an empty wallet and performs
+ a manual withdrawal with demo exchange.
+ * payment: starts from demo shop and pay for an article.
+ also showing how a refund looks.
+ * transfer: performs a p2p push debit and credit.
+ * invoice: performs a p2p pull credit and debit.
+ * deposit: starts from a wallet with some balance
+ and deposit into a bank account new yet
+ known by the wallet.
+ * add-exchange: add the test exchange into the wallet.
+
+In this root folder there are some additionals screen for
+settings, dev tools and others.
+
+Screenshot starting with "store-*" are used in chrome webstore
+and firefox addon store.
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/1-balance.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/1-balance.png
new file mode 100644
index 00000000..1041e2ee
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/1-balance.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/10-testkudos-in-the-list.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/10-testkudos-in-the-list.png
new file mode 100644
index 00000000..12a53026
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/10-testkudos-in-the-list.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/11-select-test-kudos.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/11-select-test-kudos.png
new file mode 100644
index 00000000..43e18c89
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/11-select-test-kudos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/2-click-get-cash.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/2-click-get-cash.png
new file mode 100644
index 00000000..d7d247f0
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/2-click-get-cash.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/3-click-add-exchange.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/3-click-add-exchange.png
new file mode 100644
index 00000000..7a1a48e9
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/3-click-add-exchange.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/4-input-URL.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/4-input-URL.png
new file mode 100644
index 00000000..efdf852a
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/4-input-URL.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/5-click-next.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/5-click-next.png
new file mode 100644
index 00000000..9a2782f2
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/5-click-next.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/6-review-tos.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/6-review-tos.png
new file mode 100644
index 00000000..44a85d6f
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/6-review-tos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/7-accept-tos.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/7-accept-tos.png
new file mode 100644
index 00000000..c73c5256
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/7-accept-tos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/8-confirm.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/8-confirm.png
new file mode 100644
index 00000000..1041e2ee
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/8-confirm.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/add-exchange/9-click-get-cash.png b/design-documents/wallet-screenshots/webex-wallet/add-exchange/9-click-get-cash.png
new file mode 100644
index 00000000..d7d247f0
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/add-exchange/9-click-get-cash.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/1-balance.png b/design-documents/wallet-screenshots/webex-wallet/deposit/1-balance.png
new file mode 100644
index 00000000..7c571c48
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/1-balance.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/10-balance.png b/design-documents/wallet-screenshots/webex-wallet/deposit/10-balance.png
new file mode 100644
index 00000000..4e3a787b
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/10-balance.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/2-click-send.png b/design-documents/wallet-screenshots/webex-wallet/deposit/2-click-send.png
new file mode 100644
index 00000000..2cdb5fe0
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/2-click-send.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/3-click-deposit.png b/design-documents/wallet-screenshots/webex-wallet/deposit/3-click-deposit.png
new file mode 100644
index 00000000..afc4a431
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/3-click-deposit.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/4-click-add-account.png b/design-documents/wallet-screenshots/webex-wallet/deposit/4-click-add-account.png
new file mode 100644
index 00000000..c91bc8d9
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/4-click-add-account.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/5-complete-form.png b/design-documents/wallet-screenshots/webex-wallet/deposit/5-complete-form.png
new file mode 100644
index 00000000..77514161
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/5-complete-form.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/6-click-add.png b/design-documents/wallet-screenshots/webex-wallet/deposit/6-click-add.png
new file mode 100644
index 00000000..e78538c7
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/6-click-add.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/7-confirm-deposit.png b/design-documents/wallet-screenshots/webex-wallet/deposit/7-confirm-deposit.png
new file mode 100644
index 00000000..bf2c61bc
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/7-confirm-deposit.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/8-show-transaction.png b/design-documents/wallet-screenshots/webex-wallet/deposit/8-show-transaction.png
new file mode 100644
index 00000000..381ae09e
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/8-show-transaction.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/deposit/9-after-deposit-confirmed.png b/design-documents/wallet-screenshots/webex-wallet/deposit/9-after-deposit-confirmed.png
new file mode 100644
index 00000000..74c2026d
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/deposit/9-after-deposit-confirmed.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/dev-tools.png b/design-documents/wallet-screenshots/webex-wallet/dev-tools.png
new file mode 100644
index 00000000..a817d055
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/dev-tools.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/1-balance.png b/design-documents/wallet-screenshots/webex-wallet/invoice/1-balance.png
new file mode 100644
index 00000000..a6692c4f
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/1-balance.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/10-confirm-transfer.png b/design-documents/wallet-screenshots/webex-wallet/invoice/10-confirm-transfer.png
new file mode 100644
index 00000000..2611c9f3
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/10-confirm-transfer.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/11-show-history.png b/design-documents/wallet-screenshots/webex-wallet/invoice/11-show-history.png
new file mode 100644
index 00000000..52907939
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/11-show-history.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/2-click-add.png b/design-documents/wallet-screenshots/webex-wallet/invoice/2-click-add.png
new file mode 100644
index 00000000..7834436d
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/2-click-add.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/3-input-six.png b/design-documents/wallet-screenshots/webex-wallet/invoice/3-input-six.png
new file mode 100644
index 00000000..0f910210
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/3-input-six.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/4-click-invoice.png b/design-documents/wallet-screenshots/webex-wallet/invoice/4-click-invoice.png
new file mode 100644
index 00000000..0d7c1b31
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/4-click-invoice.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/5-complete-form.png b/design-documents/wallet-screenshots/webex-wallet/invoice/5-complete-form.png
new file mode 100644
index 00000000..625afb3c
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/5-complete-form.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/6-create-invoice.png b/design-documents/wallet-screenshots/webex-wallet/invoice/6-create-invoice.png
new file mode 100644
index 00000000..def698a8
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/6-create-invoice.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/7-copy-qr-open-qr-page.png b/design-documents/wallet-screenshots/webex-wallet/invoice/7-copy-qr-open-qr-page.png
new file mode 100644
index 00000000..fe221eac
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/7-copy-qr-open-qr-page.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/8-paste-URI.png b/design-documents/wallet-screenshots/webex-wallet/invoice/8-paste-URI.png
new file mode 100644
index 00000000..26351cb9
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/8-paste-URI.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/invoice/9-click-open.png b/design-documents/wallet-screenshots/webex-wallet/invoice/9-click-open.png
new file mode 100644
index 00000000..90393d3b
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/invoice/9-click-open.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/1-load-shop.png b/design-documents/wallet-screenshots/webex-wallet/payment/1-load-shop.png
new file mode 100644
index 00000000..4aacc47b
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/1-load-shop.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/10-click-article-URL.png b/design-documents/wallet-screenshots/webex-wallet/payment/10-click-article-URL.png
new file mode 100644
index 00000000..74488cb6
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/10-click-article-URL.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/2-click-first-article.png b/design-documents/wallet-screenshots/webex-wallet/payment/2-click-first-article.png
new file mode 100644
index 00000000..31635b8a
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/2-click-first-article.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/3-confirm-payment.png b/design-documents/wallet-screenshots/webex-wallet/payment/3-confirm-payment.png
new file mode 100644
index 00000000..016f5514
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/3-confirm-payment.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/4-click-refund.png b/design-documents/wallet-screenshots/webex-wallet/payment/4-click-refund.png
new file mode 100644
index 00000000..4a3ddd39
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/4-click-refund.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/5-click-request-refund.png b/design-documents/wallet-screenshots/webex-wallet/payment/5-click-request-refund.png
new file mode 100644
index 00000000..9b27cd5b
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/5-click-request-refund.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/6-accept-refund.png b/design-documents/wallet-screenshots/webex-wallet/payment/6-accept-refund.png
new file mode 100644
index 00000000..a4b1c137
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/6-accept-refund.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/7-click-refund-detail.png b/design-documents/wallet-screenshots/webex-wallet/payment/7-click-refund-detail.png
new file mode 100644
index 00000000..14291836
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/7-click-refund-detail.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/8-show-history.png b/design-documents/wallet-screenshots/webex-wallet/payment/8-show-history.png
new file mode 100644
index 00000000..2758f7f3
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/8-show-history.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/payment/9-click-receipt.png b/design-documents/wallet-screenshots/webex-wallet/payment/9-click-receipt.png
new file mode 100644
index 00000000..a4b1c137
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/payment/9-click-receipt.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/scan-qr-code.png b/design-documents/wallet-screenshots/webex-wallet/scan-qr-code.png
new file mode 100644
index 00000000..ae28e3db
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/scan-qr-code.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/settings-developer-mode.png b/design-documents/wallet-screenshots/webex-wallet/settings-developer-mode.png
new file mode 100644
index 00000000..c93883dc
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/settings-developer-mode.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/settings-normal-mode.png b/design-documents/wallet-screenshots/webex-wallet/settings-normal-mode.png
new file mode 100644
index 00000000..50f70cab
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/settings-normal-mode.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/store-installed.png b/design-documents/wallet-screenshots/webex-wallet/store-installed.png
new file mode 100644
index 00000000..67c481fc
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/store-installed.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/store-payment.png b/design-documents/wallet-screenshots/webex-wallet/store-payment.png
new file mode 100644
index 00000000..3f776696
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/store-payment.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/store-withdraw.png b/design-documents/wallet-screenshots/webex-wallet/store-withdraw.png
new file mode 100644
index 00000000..8409a0b9
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/store-withdraw.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/1-initial-balance.png b/design-documents/wallet-screenshots/webex-wallet/transfer/1-initial-balance.png
new file mode 100644
index 00000000..20e74cf3
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/1-initial-balance.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/10-open-URI.png b/design-documents/wallet-screenshots/webex-wallet/transfer/10-open-URI.png
new file mode 100644
index 00000000..22f21f89
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/10-open-URI.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/11-accept-transfer.png b/design-documents/wallet-screenshots/webex-wallet/transfer/11-accept-transfer.png
new file mode 100644
index 00000000..9ee2083a
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/11-accept-transfer.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/12-show-history.png b/design-documents/wallet-screenshots/webex-wallet/transfer/12-show-history.png
new file mode 100644
index 00000000..d2d12ca8
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/12-show-history.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/2-click-send.png b/design-documents/wallet-screenshots/webex-wallet/transfer/2-click-send.png
new file mode 100644
index 00000000..0e705860
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/2-click-send.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/3-amount-five.png b/design-documents/wallet-screenshots/webex-wallet/transfer/3-amount-five.png
new file mode 100644
index 00000000..ffe4bee7
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/3-amount-five.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/4-send-wallet.png b/design-documents/wallet-screenshots/webex-wallet/transfer/4-send-wallet.png
new file mode 100644
index 00000000..f566b0cb
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/4-send-wallet.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/5-complete-form.png b/design-documents/wallet-screenshots/webex-wallet/transfer/5-complete-form.png
new file mode 100644
index 00000000..836755ca
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/5-complete-form.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/6-confirm-transfer.png b/design-documents/wallet-screenshots/webex-wallet/transfer/6-confirm-transfer.png
new file mode 100644
index 00000000..55de4bb0
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/6-confirm-transfer.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/7-show-history.png b/design-documents/wallet-screenshots/webex-wallet/transfer/7-show-history.png
new file mode 100644
index 00000000..39de7b66
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/7-show-history.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/8-scan-qr.png b/design-documents/wallet-screenshots/webex-wallet/transfer/8-scan-qr.png
new file mode 100644
index 00000000..cacdce06
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/8-scan-qr.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/transfer/9-paste-URI.png b/design-documents/wallet-screenshots/webex-wallet/transfer/9-paste-URI.png
new file mode 100644
index 00000000..32ac0ff4
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/transfer/9-paste-URI.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/10-transaction-completed.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/10-transaction-completed.png
new file mode 100644
index 00000000..2a774334
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/10-transaction-completed.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/11-history-after-withdraw.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/11-history-after-withdraw.png
new file mode 100644
index 00000000..54b05212
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/11-history-after-withdraw.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/2-empty-wallet.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/2-empty-wallet.png
new file mode 100644
index 00000000..79fc787b
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/2-empty-wallet.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/3-get-digital-cash.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/3-get-digital-cash.png
new file mode 100644
index 00000000..273d5f5f
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/3-get-digital-cash.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/4-select-kudos.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/4-select-kudos.png
new file mode 100644
index 00000000..741ac32a
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/4-select-kudos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/5-set-amount-five.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/5-set-amount-five.png
new file mode 100644
index 00000000..8454928b
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/5-set-amount-five.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/6-withdraw-from-bank.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/6-withdraw-from-bank.png
new file mode 100644
index 00000000..e0942a0c
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/6-withdraw-from-bank.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/7-review-tos.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/7-review-tos.png
new file mode 100644
index 00000000..505e06d3
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/7-review-tos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/8-accept-tos.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/8-accept-tos.png
new file mode 100644
index 00000000..61d3c0a4
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/8-accept-tos.png
Binary files differ
diff --git a/design-documents/wallet-screenshots/webex-wallet/withdrawal/9-confirm-withdraw.png b/design-documents/wallet-screenshots/webex-wallet/withdrawal/9-confirm-withdraw.png
new file mode 100644
index 00000000..579803cc
--- /dev/null
+++ b/design-documents/wallet-screenshots/webex-wallet/withdrawal/9-confirm-withdraw.png
Binary files differ
diff --git a/frags/apt-install-libeufin-bank.rst b/frags/apt-install-libeufin-bank.rst
new file mode 100644
index 00000000..97b1bd71
--- /dev/null
+++ b/frags/apt-install-libeufin-bank.rst
@@ -0,0 +1,6 @@
+
+To install libeufin-nexus, you can now simply run:
+
+.. code-block:: console
+
+ # apt install libeufin-bank
diff --git a/frags/apt-install-libeufin-nexus.rst b/frags/apt-install-libeufin-nexus.rst
new file mode 100644
index 00000000..25ff8070
--- /dev/null
+++ b/frags/apt-install-libeufin-nexus.rst
@@ -0,0 +1,6 @@
+
+To install libeufin-nexus, you can now simply run:
+
+.. code-block:: console
+
+ # apt install libeufin-nexus
diff --git a/frags/deploying-tos.rst b/frags/deploying-tos.rst
new file mode 100644
index 00000000..5b389f44
--- /dev/null
+++ b/frags/deploying-tos.rst
@@ -0,0 +1,45 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+
+Configuring exchange terms
+==========================
+
+You can use your own terms of service and privacy policy. You can use the default templates in ``/usr/share/taler/terms`` as a guide.
+Assuming you have custom terms of service and privacy policy ``rst`` teamplte files at ``TOS_PATH`` and ``PRIVACY_PATH``, the following commands generate the terms files:
+
+.. code-block:: console
+
+ # taler-terms-generator -i "$TOS_PATH"
+ # taler-terms-generator -i "$PRIVACY_PATH"
+
+You now have to specify the terms file names in the exchange config:
+
+.. code-block:: console
+
+ # TERMS_ETAG="$(basename "$TOS_PATH" .rst)"
+ # PRIVACY_ETAG="$(basename "$PRIVACY_PATH" .rst)"
+
+.. code-block:: ini
+
+ [exchange]
+ TERMS_ETAG=${TERMS_ETAG}
+ PRIVACY_ETAG=${PRIVACY_ETAG}
+
+Make sure to restart taler-exchange after changing these configuration options:
+
+.. code-block:: console
+
+ # systemctl restart taler-exchange.target
diff --git a/frags/ebics-setup.rst b/frags/ebics-setup.rst
index c6ff5143..e69de29b 100644
--- a/frags/ebics-setup.rst
+++ b/frags/ebics-setup.rst
@@ -1,63 +0,0 @@
-
-When you sign up for an EBICS-enabled bank account, the bank will provide you
-with various credentials. Those must be provided in the
-``/etc/libeufin/libeufin-nexus.conf`` configuration file together with the
-name of the *fiat* currency.
-
-The following snippet shows the mandatory configuration values:
-
-.. _core-config:
-
-.. code-block:: console
-
- [nexus-ebics]
- CURRENCY = CHF
-
- # Bank
- HOST_BASE_URL = http://bank.example.com/
- BANK_DIALECT = postfinance
-
- # EBICS IDs
- HOST_ID = mybank
- USER_ID = myuser
- PARTNER_ID = myorg
-
- # Key files
- BANK_PUBLIC_KEYS_FILE = ${LIBEUFIN_HOME}/bank-keys.json
- CLIENT_PRIVATE_KEYS_FILE = ${LIBEUFIN_HOME}/subscriber-keys.json
-
- # Account information
- IBAN = myiban
- BIC = mybic
- NAME = myname
-
-.. note::
- Refer to the manpage ``libeufin-nexus.conf(5)``
- for the full array of configuration values.
-
-Assuming that the configuration file exists at ``$config_file``, the following
-command would start the EBICS setup process. The files CLIENT_PRIVATE_KEYS_FILE
-and BANK_PUBLIC_KEYS_FILE would be created at the CWD. Adjust their path to your
-setup ('$HOME' is currently not supported along paths).
-
-.. code-block:: console
-
- libeufin-nexus ebics-setup -c $config_file
-
-If the previous command succeeded, the subscriber keys reached the bank, but the setup
-**should** fail with an ``EBICS_INVALID_USER_STATE`` error code. That happens because
-the client tries to download the bank keys *before* having confirmed the subscriber keys
-via the traditional post service.
-
-To that purpose, the previous run should have left a PDF document that the subscriber can
-print, sign, and send to the bank to confirm their subscriber keys. Look for the message
-looking like ``PDF file with keys hex encoding created at: /tmp/libeufin-nexus-keys-$timestamp.pdf``.
-
-Once the bank received and approved such printed document, run the same command again, in
-order to download the bank keys and let the user accept them.
-
-.. code-block:: console
-
- libeufin-nexus ebics-setup -c $config_file
-
-The setup is considered finished once the user accepts the bank keys. \ No newline at end of file
diff --git a/frags/libeufin-config-cli.rst b/frags/libeufin-config-cli.rst
index 0852c2aa..5475324e 100644
--- a/frags/libeufin-config-cli.rst
+++ b/frags/libeufin-config-cli.rst
@@ -19,6 +19,8 @@ It takes two arguments, the section name and the option name
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
**-f** \| **--filename**
Interpret value as path with dollar-expansion.
@@ -31,15 +33,19 @@ This command dump the configuration.
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
config pathsub
--------------
This command substitute variables in a path.
-It takes one argument, a path expresion.
+It takes one argument, a path expression.
**-h** \| **--help**
Print short help on options.
**-c** \| **--config** *FILENAME*
- Specifies the configuration file. \ No newline at end of file
+ Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
diff --git a/frags/nexus-ebics-setup.rst b/frags/nexus-ebics-setup.rst
new file mode 100644
index 00000000..76f51bfe
--- /dev/null
+++ b/frags/nexus-ebics-setup.rst
@@ -0,0 +1,87 @@
+
+When you sign up for an EBICS-enabled bank account, the bank will provide you
+with various credentials. Those must be provided in the
+``/etc/libeufin/libeufin-nexus.conf`` configuration file together with the
+name of the *fiat* currency.
+
+.. note::
+ As legacy transactions in that bank account would likely confuse the system, it is advisable to use a fresh bank account with an empty transaction history.
+
+The following snippet shows the mandatory configuration values:
+
+.. _core-config:
+
+.. code-block:: ini
+
+ [nexus-ebics]
+ CURRENCY = CHF
+
+ # Bank
+ HOST_BASE_URL = https://ebics.postfinance.ch/ebics/ebics.aspx
+ BANK_DIALECT = postfinance
+
+ # EBICS IDs
+ HOST_ID = PFEBICS
+ USER_ID = PFC00563
+ PARTNER_ID = PFC00563
+
+ # Account information
+ IBAN = CH7789144474425692816
+ BIC = POFICHBEXXX
+ NAME = John Smith S.A.
+
+.. note::
+ Refer to the manpage ``libeufin-nexus.conf(5)``
+ for the full array of configuration values.
+
+.. warning::
+ This combination of HOST_ID, USER_ID and PARTNER_ID must never be used by another instance of libeufin-nexus or by other EBICS clients, otherwise data will be lost.
+
+Reuse existing client keys
+--------------------------
+
+If you have client keys from a previous EBICS setup you can copy the JSON file to the configured path ``CLIENT_PRIVATE_KEYS_FILE`` (``/var/lib/libeufin-nexus/client-ebics-keys.json`` with the default config).
+
+Make sure this file is accessible to the user running ``libeufin-nexus``, for the default services you should run:
+
+.. code-block:: console
+
+ $ chown libeufin-nexus:libeufin-nexus /var/lib/libeufin-nexus/client-ebics-keys.json
+
+Create new client keys
+----------------------
+
+Assuming that the configuration file exists at ``$CONFIG_FILE``, the following
+command should start the EBICS setup process:
+
+.. code-block:: console
+
+ $ libeufin-nexus ebics-setup -c "$CONFIG_FILE"
+
+If the previous command failed when running EBICS INI with an error code of
+``EBICS_INVALID_USER_OR_USER_STATE``, you need to confirm your keys to your bank to
+activate your account.
+
+To that end, the previous run should have left a PDF document that you can
+print, sign and send to the bank. Look for the message that looks like ``PDF
+file with keys created at '/tmp/libeufin-nexus-keys-$TIMESTAMP.pdf'``.
+
+Once the bank has received and processed this document you can continue.
+
+Get bank keys
+-------------
+
+Assuming that the configuration file exists at ``$CONFIG_FILE``, the following
+command will finish the EBICS setup process:
+
+.. code-block:: console
+
+ $ libeufin-nexus ebics-setup -c "$CONFIG_FILE"
+
+The EBICS setup is finished once the bank keys have been accepted.
+
+Make sure this bank keys are accessible to the user running ``libeufin-nexus``, for the default services you should run:
+
+.. code-block:: console
+
+ $ chown libeufin-nexus:libeufin-nexus /var/lib/libeufin-nexus/bank-ebics-keys.json
diff --git a/frags/regional-manual-architecture.rst b/frags/regional-manual-architecture.rst
new file mode 100644
index 00000000..cfb8aacd
--- /dev/null
+++ b/frags/regional-manual-architecture.rst
@@ -0,0 +1,48 @@
+Architecture
+============
+
+There are several key components needed to operate a regional currency based
+on GNU Taler and LibEuFin technology:
+
+- LibEuFin Nexus: is responsible to drive the master (fiat) bank account both to learn
+ about incoming payments and to send fiat cash-out payments
+- LibEuFin Bank: offers basic banking operations, e.g. wire transfers, Taler withdrawals,
+ account management, cash-out's
+- Taler exchange: server side of Taler operations.
+- Taler wallet: client side of Taler operations.
+- Taler merchant backend: abstracts Taler details to the shops.
+
+.. image:: ../images/regional-arch.png
+
+In this model, the regional currency is backed by the fiat currency and users
+are offered two operations: *cash-in* to create regional currency starting
+from fiat money, and *cash-out* to convert regional currency into fiat
+currency.
+
+The design assumes that one single unit of regional currency is always backed
+by one single unit of fiat currency.
+
+
+Cash-in
++++++++
+
+One fundamental entity to create the regional currency is the *master bank account*.
+The master bank account is hosted at one fiat bank and whenever it receives a *valid*
+fiat payment of N units, it triggers the creation of N units of regional currency.
+Such trigger causes the *admin bank account* at the regional bank to wire the N units of
+regional currency to the Taler exchange (regional) bank account. At this point, the
+Taler exchange is ready to issue the regional coins to the Taler wallet that proves
+to own them.
+
+.. note::
+
+ *Valid* fiat payments are those with a Taler-relevant subject that should be generated by a Taler wallet.
+
+
+Cash-out
+++++++++
+
+Once a regional bank user confirms a cash-out operation of N units, the system sends
+a regional payment of N units to the *admin bank account*. This latter triggers then
+a fiat payment of N units to the fiat bank account owned by the user who initiated the
+cash-out. \ No newline at end of file
diff --git a/frags/regional-manual-use.rst b/frags/regional-manual-use.rst
new file mode 100644
index 00000000..f33d9010
--- /dev/null
+++ b/frags/regional-manual-use.rst
@@ -0,0 +1,99 @@
+Using the Regional Currency
+===========================
+
+The very first step you should check afte the installation process has been
+completed successfully, is to make sure all three URLs (bank,backend and exchange),
+are available (this means to see a Website, and not any NGINX error).
+
+
+Bank backend walkthrough
++++++++++++++++++++++++++
+
+- As stated above, please visit before "https://bank.yourdomain.ltd", to make sure it is available.
+
+- Now login with the username "admin" and the password you have choosen during the installation process, or use the one which might
+ have been generated automatically (and shown on your terminal screen), during the installation process.
+ Once inside the Bank Administrator area, please create the "very first" customer account.
+
+- Transfer some funds from the "admin" bank account to this new customer account.
+
+- Now logout from the "admin" account, and login again using the recently "customer" account you have created, and make sure the funds you have transfered from admin, have arrived correctly.
+
+- Now, please choose the option "Send Money to a Taler Wallet", and try to send for example 100 units of your regional currency to the
+ wallet installed on your browser or mobile phone.
+
+- Now try to spend some of these funds from your wallet, and try to buy something somewhere, with the same digital currency you have choosen, during your installation process, let's say Netzbon.
+
+- Lastly, you can also try to transfer funds to another "bank account",for that you will need to know the recipient's username or the bank account ID.
+
+If you have successfully accomplished all the previous steps, for the bank administrator
+backend and your installed Wallet, you can move now to test other components such
+as the Merchant backend (https://backend.yourdomain.ltd).
+
+Wallet Setup
+++++++++++++
+
+This section describes the interaction between the Taler graphical wallet (Android,
+iOS, WebExtensions) and the regional currency system.
+
+You need to add your regional currency exchange to the wallet. This can
+be done by scanning a QR code with a ``taler://withdraw-exchange/exchange.$DOMAIN/$MASTER_PUB``
+URL or by manually entering the URL into the respective ``Add exchange``
+dialogue.
+
+
+Cash-In
++++++++
+
+Next, start the withdraw process in the Taler wallet for the respective
+currency and specify the desired amount. The wallet will then show you the
+details of the fiat wire transfer that must be made for the cash-in to be
+completed. Once the money has arrived at the fiat bank account, Nexus will
+obtain the transaction data and the regional currency bank will create the
+corresponding amount in regional currency, crediting the GNU Taler exchange
+account. In turn, the exchange will issue the respective amount to your
+wallet.
+
+.. note::
+
+ Cash-in operations may be subject to conversion rates, conversion fees and
+ minimum amounts to be transferred.
+
+
+Making payments
++++++++++++++++
+
+For testing, you should be able to *deposit* regional currency directly into
+your regional currency libeufin-bank account directly from the Taler wallet.
+For this, you primarily need to know your bank account details (which should
+be accessible by clicking on your name in the bank Web site after logging in).
+
+.. note::
+
+ There may be a short delay between the wallet making the deposit and
+ the exchange crediting your bank account. This is because the wallet
+ uses a small wire transfer delay by default when initiating a deposit
+ into a bank account.
+
+For production, it is more common for a shop to configure a :ref:`Taler
+merchant backend <taler-merchant-backend-operator-manual>` or at least use an
+instance within such a setup. To configure an instance, you primarily need
+again the bank account details to :ref:`setup instance bank accounts
+<instance-bank-account>`.
+
+
+Cash-Out
+++++++++
+
+Regional currency accounts that have a positive balance could be eligible for
+cash-out. Cash-out operations may again be restricted by the regional
+currency operator and will *only* be made to the respective pre-configured
+fiat currency bank account. To cash-out, simply log into your regional
+currency account, select cash-out, specify the desired amount and pass the
+second-factor authorization challenge by entering the TAN you receive at the
+registered e-mail address or mobile phone number.
+
+.. note::
+
+ Cash-out operations may be subject to conversion rates, conversion fees and
+ minimum amounts to be transferred.
diff --git a/frags/regional-system-on.rst b/frags/regional-system-on.rst
new file mode 100644
index 00000000..7a150cbf
--- /dev/null
+++ b/frags/regional-system-on.rst
@@ -0,0 +1,28 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+
+System ON!
+==========
+
+The last step is to enable libeufin-nexus to :ref:`import incoming bank
+transactions <receive-transaction-data>` (cash in) and to :ref:`trigger
+outgoing bank transactions <sending-payments>` (cash out).
+
+.. code-block:: console
+
+ # systemctl enable --now libeufin-nexus.target
+
+.. FIXME: explain how to test if libeufin is working!
diff --git a/images/Makefile b/images/Makefile
index 56f9fbac..ad7a695d 100644
--- a/images/Makefile
+++ b/images/Makefile
@@ -1,7 +1,9 @@
-diagrams: arch-api.png coin.png deposit.png reserve.png transaction-common-states.png transaction-withdrawal-states.png transaction-payment-states.png transaction-refund-states.png transaction-refresh-states.png transaction-reward-states.png transaction-deposit-states.png transaction-push-debit-states.png transaction-push-credit-states.png transaction-pull-credit-states.png transaction-pull-debit-states.png challenger.png
+diagrams: regional-arch.png arch-api.png coin.png deposit.png reserve.png transaction-common-states.png transaction-withdrawal-states.png transaction-payment-states.png transaction-refund-states.png transaction-refresh-states.png transaction-deposit-states.png transaction-push-debit-states.png transaction-push-credit-states.png transaction-pull-credit-states.png transaction-pull-debit-states.png challenger.png
arch-api.png: arch-api.dot
dot -Tpng arch-api.dot > arch-api.png
+regional-arch.png: regional-arch.dot
+ dot -Tpng regional-arch.dot > regional-arch.png
challenger.png: challenger.dot
dot -Tpng challenger.dot > challenger.png
transaction-common-states.png: transaction-common-states.dot
@@ -14,8 +16,6 @@ transaction-refund-states.png: transaction-refund-states.dot
dot -Tpng transaction-refund-states.dot > transaction-refund-states.png
transaction-refresh-states.png: transaction-refresh-states.dot
dot -Tpng transaction-refresh-states.dot > transaction-refresh-states.png
-transaction-reward-states.png: transaction-reward-states.dot
- dot -Tpng transaction-reward-states.dot > transaction-reward-states.png
transaction-deposit-states.png: transaction-deposit-states.dot
dot -Tpng transaction-deposit-states.dot > transaction-deposit-states.png
transaction-push-debit-states.png: transaction-push-debit-states.dot
@@ -32,4 +32,3 @@ deposit.png: deposit.dot
dot -Tpng deposit.dot > deposit.png
reserve.png: reserve.dot
dot -Tpng reserve.dot > reserve.png
-
diff --git a/images/grafana-postgres-exporter.png b/images/grafana-postgres-exporter.png
new file mode 100644
index 00000000..a51c28f0
--- /dev/null
+++ b/images/grafana-postgres-exporter.png
Binary files differ
diff --git a/images/kuma.png b/images/kuma.png
new file mode 100644
index 00000000..d98772a1
--- /dev/null
+++ b/images/kuma.png
Binary files differ
diff --git a/kyc-process.pdf b/images/kyc-process.pdf
index 8b178c02..8b178c02 100644
--- a/kyc-process.pdf
+++ b/images/kyc-process.pdf
Binary files differ
diff --git a/kyc-process.png b/images/kyc-process.png
index 563418b1..563418b1 100644
--- a/kyc-process.png
+++ b/images/kyc-process.png
Binary files differ
diff --git a/kyc-process.tex b/images/kyc-process.tex
index c10dd8d9..c10dd8d9 100644
--- a/kyc-process.tex
+++ b/images/kyc-process.tex
diff --git a/images/regional-arch.dot b/images/regional-arch.dot
new file mode 100644
index 00000000..8a61ed5e
--- /dev/null
+++ b/images/regional-arch.dot
@@ -0,0 +1,36 @@
+digraph G {
+ subgraph cluster_2 {
+ ubank;
+ nexus;
+ rank="same"; ebank; mbank;
+ label="Fiat currency";
+ };
+ subgraph cluster_1 {
+ user;
+ exchange;
+ shop;
+ rbank;
+ label="Regional currency";
+ };
+ subgraph cluster_2b {
+ }
+ user[label="Customer (Wallet)"];
+ shop[label="Merchant (Backend)"];
+ exchange[label="Exchange"];
+ ubank[label="Customer Fiat Bank"];
+ ebank[label="Exchange Fiat Bank"];
+ mbank[label="Merchant Fiat Bank"];
+ rbank[label="Regional Currency Bank"];
+ user->ubank [label="1. Initiate withdraw"];
+ ubank->ebank [label="2. Wire transfer"];
+ ebank->nexus [label="3. EBICS (CAMT)"];
+ nexus->rbank [label="4. Conversion (Cash-in)"];
+ rbank->exchange [label="5. Wirewatch"];
+ exchange->user [label="6. Withdraw E-Cash"];
+ user->shop [label="7. Spend E-Cash"];
+ shop->exchange [label="8. Deposit E-Cash"];
+ exchange->rbank [label="9. Credit Shop"];
+ rbank->nexus [xlabel="10. Conversion (Cash-out)"];
+ nexus->ebank [label="11. EBICS (PAIN)"];
+ ebank->mbank [label="12. Wire-transfer"];
+}
diff --git a/images/regional-arch.png b/images/regional-arch.png
new file mode 100644
index 00000000..a3691aea
--- /dev/null
+++ b/images/regional-arch.png
Binary files differ
diff --git a/images/taler-monitoring-infrastructure.png b/images/taler-monitoring-infrastructure.png
new file mode 100644
index 00000000..05f29704
--- /dev/null
+++ b/images/taler-monitoring-infrastructure.png
Binary files differ
diff --git a/images/transaction-reward-states.dot b/images/transaction-reward-states.dot
deleted file mode 100644
index 476c8c74..00000000
--- a/images/transaction-reward-states.dot
+++ /dev/null
@@ -1,11 +0,0 @@
-digraph G {
- initial[label="", shape="circle"];
- dialog_user[label="dialog(user)"];
- pending_pickup[label="pickup"];
- done[label="done", shape="box"];
-
- initial -> dialog_user;
-
- dialog_user -> pending_pickup [color=blue, label="OK"];
- pending_pickup -> done [color=green];
-}
diff --git a/images/uptime-kuma-edit.png b/images/uptime-kuma-edit.png
new file mode 100644
index 00000000..23b85dad
--- /dev/null
+++ b/images/uptime-kuma-edit.png
Binary files differ
diff --git a/images/uptime-kuma-from-grafana.png b/images/uptime-kuma-from-grafana.png
new file mode 100644
index 00000000..c42b8660
--- /dev/null
+++ b/images/uptime-kuma-from-grafana.png
Binary files differ
diff --git a/index.rst b/index.rst
index f562b2e8..bd3b30d6 100644
--- a/index.rst
+++ b/index.rst
@@ -37,23 +37,20 @@ practice a fraudulent Exchange might go bankrupt instead of paying the
Merchants and thus the Exchange will need to be audited regularly like
any other banking institution.
-The system will be based on free software and open protocols.
+The system is based on free software and open protocols.
+
+In this documentation, we describe the REST-based APIs between the various
+components, how to use the system, the internal architecture of key
+components, and how to get them installed and configured.
-In this document, we describe the REST-based APIs between the various
-components, internal architecture of key components, and how to get them
-installed. In addition to this documentation, we have source-level
-documentation which you can find converted to HTML at these pages:
-* `Exchange <https://docs.taler.net/doxygen/exchange/>`_
-* `Merchant <https://docs.taler.net/doxygen/merchant/>`_
-* `Wallet-core <https://docs.taler.net/doxygen/wallet-core/>`_
Documentation Overview
----------------------
.. toctree::
:numbered:
- :maxdepth: 2
+ :maxdepth: 1
core/index
taler-user-guide
diff --git a/libeufin/bank-manual.rst b/libeufin/bank-manual.rst
index af977492..ab793b2b 100644
--- a/libeufin/bank-manual.rst
+++ b/libeufin/bank-manual.rst
@@ -1,21 +1,60 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Florian Dold
+ @author Marcello Stanisci
+ @author Christian Grothoff
+
.. target audience: operator, developer
+.. _libeufin-bank:
+
Bank Setup Manual
#################
-.. contents:: Table of Contents
-
-LibEuFin Bank implements a simple core banking system with
+libeufin-bank implements a simple core banking system with
account and REST APIs, including REST APIs for a Web interface
and REST APIs to interact with GNU Taler components.
In this manual, we explain how to setup a bank.
+.. contents:: Table of Contents
+ :local:
+
+
Installing LibEuFin Bank
========================
The following section was tested on an *OpenJDK 17* environment.
+Installing the libeufin-bank binary packages on Debian
+------------------------------------------------------
+
+.. include:: ../frags/installing-debian.rst
+
+.. include:: ../frags/apt-install-libeufin-bank.rst
+
+
+Installing the libeufin-bank binary packages on Ubuntu
+------------------------------------------------------
+
+.. include:: ../frags/installing-ubuntu.rst
+
+.. include:: ../frags/apt-install-libeufin-bank.rst
+
+
Building from source
--------------------
@@ -38,8 +77,9 @@ Navigate into the *libeufin* local repository, and from top-level run:
If the previous steps succeeded, the ``libeufin-bank`` command should
be found in the $PATH.
-Setting up the LibEuFin Bank
-============================
+
+Minimal Configuration for LibEuFin Bank
+=======================================
The following snippet shows the mandatory configuration values:
@@ -47,79 +87,119 @@ The following snippet shows the mandatory configuration values:
[libeufin-bank]
CURRENCY = KUDOS
-
- # Server
- SERVE = tcp
- PORT = 8080
-
- [libeufin-bankdb-postgres]
- CONFIG = postgresql:///libeufinbank
+
+ # Supported payment target type
+ WIRE_TYPE = iban or x-taler-bank
+ # If WIRE_TYPE = iban
+ IBAN_PAYTO_BIC = SANDBOXX
+ # If WIRE_TYPE = x-taler-bank
+ X_TALER_BANK_PAYTO_HOSTNAME = https://bank.taler.net
.. note::
Refer to the manpage ``libeufin-man.conf(5)``
for the full array of configuration values.
-Assuming that the configuration file exists at ``$config_file``, the following
-command would define the database schema and create an admin account.
+.. _libeufin-mfa:
-.. code-block:: console
+Configuring multi-factor authentication
+---------------------------------------
+
+libeufin-bank supports two-factor authentication. libeufin-bank uses helper scripts to send challenge codes to addresses for multi-factor authentication. We provide two default helper scripts: ``libeufin-tan-email.sh`` to send e-mails and ``libeufin-tan-sms.sh`` to send SMS. To enable two-factor authentication you need to configure at least one TAN channel.
- $ libeufin-bank dbinit -c $config_file
+SMS TAN channel
++++++++++++++++
-If you wish to authenticate as admin, you must change the account password with the following command.
+The default ``libeufin-tan-sms.sh`` script is based on the `Telesign <https://www.telesign.com>`_ SMS provider. It requires an additional ``AUTH_TOKEN`` environment variable for `Telesign Basic authentication <https://developer.telesign.com/enterprise/docs/authentication#basic-authentication>`_.
+
+To test your setup run:
.. code-block:: console
- $ libeufin-bank passwd -c $config_file admin $PASSWORD
+ $ AUTH_TOKEN=$TELESIGN_TOKEN
+ $ echo "Test 1234" | libeufin-tan-sms.sh $PHONE
-Then you can start the HTTP server.
+If you received an SMS containing "Test 1234" you can enable this channel in the config:
-.. code-block:: console
+.. code-block:: ini
- $ libeufin-bank serve -c $config_file
+ [libeufin-bank]
+ TAN_SMS = libeufin-tan-sms.sh
+ TAN_SMS_ENV = "AUTH_TOKEN=$TELESIGN_TOKEN"
+Mail TAN channel
+++++++++++++++++
-Using custom e-mail / SMS TAN scripts
--------------------------------------
+The default ``libeufin-tan-email.sh`` script is based on the ``mail`` Linux command. It requires a working local mail transfer agent.
-The guided setup installs the TAN scripts found in ``libeufin/contrib/``:
-``libeufin-tan-email.sh`` and ``libeufin-tan-sms.sh``, but should you want to
-use custom scripts to send the e-mail or SMS TAN, set the configuration like
-follows:
+To test your setup run:
-.. note::
+.. code-block:: console
- The default SMS TAN script is based on the `Telesign <https://www.telesign.com>`_ provider.
+ $ echo "Test 1234" | libeufin-tan-email.sh $EMAIL
+
+If you received an email containing "Test 1234" you can enable this channel in the config:
.. code-block:: ini
[libeufin-bank]
+ TAN_EMAIL = libeufin-tan-email.sh
+
+Custom TAN channel scripts
+++++++++++++++++++++++++++
+
+It is possible to replace these scripts with use custom scripts to send
+the e-mail or SMS TAN. Such alternative scripts must accept the phone number / e-mail address as the ``$1`` parameter and the message content to be transmitted in their standard input. They should return 0 to indicate successful transmission of the challenge and non-zero on failure.
+
+To change the scripts used for multi-factor authentication, change the following
+options in the configuration file:
+.. code-block:: ini
+
+ [libeufin-bank]
TAN_SMS = custom-tan-sms.sh
+ TAN_SMS_ENV =
TAN_EMAIL = custom-tan-email.sh
+ TAN_EMAIL_ENV =
+
+Launching libeufin-bank
+=======================
+
+Assuming that the configuration file exists at ``$CONFIG_FILE``, the following
+command initializes (or upgrades) the database schema:
+
+.. code-block:: console
+
+ $ libeufin-bank-dbinit -c "$CONFIG_FILE"
+
+Once this is done, you can start the libeufin-bank HTTP server:
+
+.. code-block:: console
+
+ $ libeufin-bank serve -c "$CONFIG_FILE"
-The scripts TAN_SMS/EMAIL must accept the phone number / e-mail address as the
-``$1`` parameter and the message content to be transmitted in their standard
-input.
-Using the Bank Web Interface
+Using the bank Web interface
============================
-Before you can use the Web interface, you must set
-a password for the "admin" account. You can do this
-using:
+To be able to use the Web interface, you must set a password for the "admin"
+account. You can set (or reset) the account password to ``$PASSWORD`` using
+the following command:
.. code-block:: console
- $ libeufin-bank passwd -c $config_file admin "$PASSWORD"
+ $ libeufin-bank passwd -c "$CONFIG_FILE admin "$PASSWORD"
+
+You can also use the same command to reset the passwords of other accounts by
+replacing "admin" with the respective login.
+
-Setting up Accounts
+Setting up accounts
-------------------
-Using the above "$PASSWORD", log into the Web interface as "admin". Then
-search for the button "Create account" near the list of all existing bank
-accounts in the Web interface of libeufin-bank.
+Using the above "$PASSWORD", log into the Web interface as "admin". To setup
+regular accounts, search for the button "Create account" near the list of all
+existing bank accounts in the Web interface of libeufin-bank.
You will be asked to specify:
@@ -147,27 +227,24 @@ XXX Cashout channel
Is this account public?
Public accounts can be viewed without access control, their balance and transaction history becomes public.
-After submitting the form, a randomly created password
-for the new account will be shown in a notification.
-The administrator can also change passwords for any
-account in the system using the "change password" link
-in the account list. To change other details about an
-account, select the "Username" in the account list.
+After submitting the form, a randomly created password for the new account
+will be shown in a notification. The administrator can also change passwords
+for any account in the system using the "change password" link in the account
+list. To change other details about an account, select the "Username" in the
+account list.
-Account Introspection
+Account introspection
---------------------
-Users can see (and possibly change) the settings of
-their bank account and also their IBAN by clicking
-on the "Welcome, $USERNAME" text after logging into
-their bank account using their username and password.
+Users can see (and possibly change) the settings of their bank account and
+also their IBAN by clicking on the "Welcome, $USERNAME" text after logging
+into their bank account using their username and password.
-The IBAN field has a convenient "copy to clipboard"
-button next to it.
+The IBAN field has a convenient "copy to clipboard" button next to it.
-Making Transfers between Accounts
+Making transfers between accounts
---------------------------------
First, you need to know the IBAN of the account to credit, and log in as the
@@ -179,12 +256,52 @@ be wired. After pressing "Send", you may have to pass a 2-FA check.
Integration with the Taler Exchange
===================================
-Exchange Configuration
-----------------------
+.. note::
+
+ This step is fully automated if you use the :doc:`automated setup manual<regional-automated-manual>`.
+
+You must have an exchange account with username ``exchange`` for conversion to work.
+Assuming that the configuration file exists at ``$CONFIG_FILE``, the following
+command would create one:
+
+.. code-block:: console
+
+ $ libeufin-bank create-account '{"username":"exchange","password":"$EXCHANGE_PASSWORD","name":"Cashout Exchange","is_taler_exchange":true}' -c "$CONFIG_FILE"
+
+.. note::
+
+ You can also set up the exchange account as "admin" using the Web interface of libeufin-bank.
+
+Having done so, take note of two key pieces of information, namely the ``$EXCHANGE_PASSWORD`` and the "payto://"-URI of the exchange bank account. This information must then be used to configure the exchange as described in
+:ref:`exchange bank account configuration <exchange-account-signing>`. When using the libeufin-bank in the context
+of a regional currency with conversion, you must
+additionally specify a "conversion-url" when setting
+up the exchange account. See the section on :ref:`conversion setup <regional-conversion-setup>` in the regional currency setup chapter for details.
-TODO.
Withdrawing e-cash to a Taler wallet
-------------------------------------
+====================================
+
+.. note::
+
+ This step is fully automated if you use the :doc:`automated setup manual<regional-automated-manual>`.
+
+Users can withdraw digital cash from their bank account starting from their
+online banking as implemented by the libeufin-bank. However, in this scenario,
+the Taler wallet may not already know about an exchange that works with the
+respective currency. Thus, the protocol includes the possibility of the bank
+*recommending* an exchange service to the wallet, thus providing a sane
+default for the wallet to suggest to the user. To do so, the base URL of the
+exchange API must be specified in the libeufin-bank configuration:
+
+.. code-block:: ini
+
+ [libeufin-bank]
+ DEFAULT_EXCHANGE=${PROTO}://exchange.${DOMAIN_NAME}
+
+After changing this value, the libeufin-bank service needs to be restarted
+to make the change effective.
+
+.. note::
-TODO.
+ The user may change the default exchange from within the wallet, assuming they know of an alternative exchanges for the currency.
diff --git a/libeufin/index.rst b/libeufin/index.rst
index 042388dc..c77255b0 100644
--- a/libeufin/index.rst
+++ b/libeufin/index.rst
@@ -1,3 +1,23 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2023 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Florian Dold
+ @author Marcello Stanisci
+ @author Christian Grothoff
+
+
LibEuFin
########
@@ -9,5 +29,6 @@ LibEuFin is a project providing free software tooling for European FinTech.
nexus-manual
bank-manual
- regional-manual
+ regional-automated-manual
+ regional-custom-manual
setup-ebics-at-postfinance
diff --git a/libeufin/nexus-manual.rst b/libeufin/nexus-manual.rst
index bc4ca471..de2f4bae 100644
--- a/libeufin/nexus-manual.rst
+++ b/libeufin/nexus-manual.rst
@@ -1,23 +1,68 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Florian Dold
+ @author Marcello Stanisci
+ @author Christian Grothoff
+
.. target audience: operator, developer
+.. _libeufin-nexus:
+
Nexus Manual
############
-.. contents:: Table of Contents
+LibEuFin Nexus is an EBICS facilitator. It offers a command line interface to
+setup EBICS access, download banking records, and submit payments. Today, the
+LibEuFin implementation supports EBICS 2.5 and 3.0 and has been tested with
+the Postfinance (CHF). Please note that banks tend to have their own dialects
+of finance messages and thus other retail banks may or may not work. Contact
+us if you need support for another bank or core banking protocol.
-LibEuFin Nexus is an EBICS facilitator. It offers a command line
-interface to setup EBICS access, download banking records, and submit payments.
-Future versions will offer a Web API to allow Taler Exchanges to talk to their
+Future versions will offer a Web API to allow Taler exchanges to talk to their
banks.
In this manual, we explain how to setup an EBICS subscriber. We assume that
-the bank had already granted EBICS access to the subscriber.
+the bank has already granted EBICS access to the subscriber.
+
+.. contents:: Table of Contents
+ :local:
+
Installing Nexus
================
The following section was tested on an *OpenJDK 17* environment.
+
+Installing the libeufin-nexus binary packages on Debian
+-------------------------------------------------------
+
+.. include:: ../frags/installing-debian.rst
+
+.. include:: ../frags/apt-install-libeufin-nexus.rst
+
+
+Installing the libeufin-nexus binary packages on Ubuntu
+-------------------------------------------------------
+
+.. include:: ../frags/installing-ubuntu.rst
+
+.. include:: ../frags/apt-install-libeufin-nexus.rst
+
+
Building from source
--------------------
@@ -45,71 +90,79 @@ be found in the $PATH.
Setting up the EBICS subscriber
===============================
-.. include:: ../frags/ebics-setup.rst
-
-Sending payments
-================
+.. include:: ../frags/nexus-ebics-setup.rst
-Sending payments must follow a successful `EBICS subscriber setup <ebics-setup>`_,
-where the bank obtained the subscriber keys, and the subscriber accepted the
-bank keys. The responsible subcommand for sending payments is ``ebics-submit``,
-and its configuration is a **superset** of core-config_. On top of that, it
-expects the database connection string, and *optionally* a frequency to check
-for submittable payments in the database.
+Database setup
+==============
-The connection string is specified as
+The configuration file must include a connection string that
+tells Nexus how it should connect to the database. The default
+is:
.. code-block:: ini
[nexus-postgres]
-
config = postgres:///nexus
+You must make sure that this database exists and is accessible to the user
+running Nexus before continuing. Then, the Nexus database schema must be
+created (or updated) to the current Nexus version using the following command:
+
+.. code-block:: console
+
+ $ libeufin-nexus-dbinit -c "$CONFIG_FILE"
+
+where ``$CONFIG_FILE`` is again the path to a configuration that contains at
+least the above ``[nexus-postgres]`` section.
+
+.. _sending-payments:
+
+Sending payments
+================
+
+Sending payments must follow a successful `EBICS subscriber setup
+<ebics-setup>`_, where the bank obtained the subscriber keys, and the
+subscriber accepted the bank keys. Furthermore, the database has to
+be set up. Right now, some other process must queue payments to be
+submitted to the database, so this section only discusses how such
+queued payments will be executed.
+
+The responsible subcommand for sending payments is ``ebics-submit``, and its
+configuration is a **superset** of core-config_. On top of that, it expects
+the database connection string and *optionally* a frequency at which it will
+check for submittable payments in the database.
+
The frequency **may** be specified as
.. code-block:: ini
[nexus-submit]
- frequency = 5m
- # Optional, but useful to check what Nexus sends to the bank
- submissions_log_directory = $LIBEUFIN_DATA_HOME/uploads
+ FREQUENCY = 5m
The supported time units are ``s`` (seconds), ``m`` (minutes), ``h`` (hours).
-Before delving into the following sections, the database schema must be
-created, therefore run the following command:
-
-.. code-block:: console
-
- $ libeufin-nexus dbinit -c $config_file
-
-Where ``$config_file`` is the path to a configuration path that contains at
-least the ``[nexus-postgres]`` section.
For testing
-----------
The ``ebics-submit`` subcommand is **not** suitable to send arbitrary
-payments, but rather to submit initiated payments that may be found
-in the database.
-
-Such initiated payments may be refunds of incoming payments with a subject
-that would be invalid for a Taler withdrawal, or from a Taler exchange in
-the attempt to pay a merchant.
+payments, but rather to submit initiated payments that are already queued for
+submission in the Nexus database.
-For testing purposes, however, it is possible to artificially initiate
-a payment into the database with the ``contrib/payment_initiation_debug.sh``
-script, found in the libeufin repository. The script pays always one Swiss
-Franc to an IBAN and subject pair of choice.
+Such queued payments may originate from bounces of incoming payments with a
+subject that would be invalid for a Taler withdrawal, or from a Taler exchange
+that needs to send a payment to a merchant.
+For testing purposes it is possible to manually initiate a payment using the
+``initiate-payment`` subcommand.
The following invocation pays 1 CHF to the CH987654321 with an "Hello, Nexus!"
-subject.
+subject:
.. code-block:: console
- $ ./payment_initiation_debug.sh $config_file CH987654321 "Hello, Nexus!"
+ $ libeufin-nexus initiate-payment -c "$CONFIG_FILE" --subject "Hello, Nexus!" "payto://iban/CH987654321?receiver-name=Name&amount=CHF:1"
-``$config_file`` is the path to Nexus' configuration file and it does not need
+``$CONFIG_FILE`` is the path to Nexus' configuration file and it does not need
the FREQUENCY value. If the previous command worked, now the database should
contain a new row in the ``initiated_outgoing_transactions`` table, with an
``unsubmitted`` submission state.
@@ -120,13 +173,14 @@ send it to the bank.
.. code-block:: console
- $ libeufin-nexus ebics-submit -c $config_file --transient
+ $ libeufin-nexus ebics-submit -c "$CONFIG_FILE" --transient
The ``--transient`` flag instructs the software to perform only one pass on
the database, submit what is submittable, and return.
-Alternatively, the ``--debug`` flag makes ebics-submit accept data from STDIN,
-and submit it to the bank.
+The ``--debug-ebics $SAVEDIR`` flag will cause the files to be stored in
+``$SAVEDIR/$YYYY-MM-DD/submit`` where ``$YYYY-MM-DD`` represents the
+date when the upload took place. This is mostly useful for debugging.
For production
--------------
@@ -136,87 +190,88 @@ The ``ebics-submit`` subcommand can run in fixed frequency, or transient mode.
The fixed frequency mode causes the command to check the database every time the
frequency period expires. To activate this mode, and -- for example -- set a frequency
of five minutes, set the configuration value ``FREQUENCY`` to ``5m``. Assuming that
-``$config_fixed_frequency`` is set as described above, the following invocation would
+``FREQUENCY`` is set as described above, the following invocation would
make ``ebics-submit`` check the database every five minutes, and submit any initiated
payment according to their submission state.
.. code-block:: console
- $ libeufin-nexus ebics-submit -c $config_fixed_frequency
-
+ $ libeufin-nexus ebics-submit -c "$CONFIG_FILE"
Transient mode causes ``ebics-submit`` to check the database only once, submit any
initiated payment according to their submission state, and return.
.. code-block:: console
- $ libeufin-nexus ebics-submit -c $config
+ $ libeufin-nexus ebics-submit -c "$CONFIG_FILE"
+
+
+.. _receive-transaction-data:
-Downloading records
-===================
+Downloading payment records
+===========================
-Downloading records must follow a successful `EBICS subscriber setup <ebics-setup>`_,
-where the bank obtained the subscriber keys, and the subscriber accepted the bank keys.
+Downloading payments must follow a successful `EBICS subscriber setup
+<ebics-setup>`_, where the bank obtained the subscriber keys, and the
+subscriber accepted the bank keys. Furthermore, the database has to
+be set up.
-The configuration file must contain all the ``[ebics-setup]`` sections, plus the following
-values to set the database connection and a log directory where any downloaded record would
-be stored.
+The responsible subcommand for sending payments is ``ebics-fetch``, and its
+configuration is a **superset** of core-config_. On top of that, it expects
+the database connection string and *optionally* a frequency at which it will
+downloads any new EBICS files and ingest them in the database.
+
+The frequency **may** be specified as
.. code-block:: ini
- [nexus-postgres]
- config = postgres:///nexus
[nexus-fetch]
- # Optional, but usefull against data loss.
- statement_log_directory = $LIBEUFIN_DATA_HOME/downloads
+ FREQUENCY = 5m
-Assuming that ``$config_file`` contains any required option, the following command
-would download any unseen notifications (as camt.054 files).
+The supported time units are ``s`` (seconds), ``m`` (minutes), ``h`` (hours).
-.. code-block:: console
+Assuming that ``$CONFIG_FILE`` contains all required options, the following
+command would download any unseen EBICS files:
- $ libeufin-nexus ebics-fetch -c $config_file --transient
+.. code-block:: console
-The ``--transient`` flag makes the command to download only once and return. If the
-bank returned any records, look in ``$LIBEUFIN_DATA_HOME/camt/YYYY-MM-DD`` to find them.
-YYYY-MM-DD is the date when the download took place.
+ $ libeufin-nexus ebics-fetch -c "$CONFIG_FILE" --transient
-To activate periodic downloads, add the following setting to the ``nexus-fetch``
-configuration section in ``$config_file``:
+The ``ebics-fetch`` subcommand will always cause libeufin-nexus to download
+then parse EBICS files and ingest their content statements into its local
+database.
-.. code-block:: ini
+The files type can be given as an argument to select what will be fetched. If no argument is given, all supported files are fetched. The following files are supported:
- [nexus-fetch]
- frequency = 5m
+* ``acknowledgement``: EBICS acknowledgement, retrieves the status of EBICS orders.
+* ``status``: Payment status, retrieves status of pending debits.
+* ``notification``: Debit & credit notifications, retrieves the history of confirmed debits and credits.
-The following invocation would then download records every five minutes, asking the bank
-to only return documents that are timestamped *from* (inclusive) the last incoming transaction.
+The ``--transient`` flag makes the command download and import EBICS files only
+once and return immediately afterwards. Without the flag, Nexus
+will download at the frequency specified in the configuration.
-.. code-block:: console
+The ``--debug-ebics $SAVEDIR`` flag will cause the files to be stored in
+``$SAVEDIR/$YYYY-MM-DD/fetch`` where ``$YYYY-MM-DD`` represents the
+date when the download took place. This is mostly useful for debugging.
- $ libeufin-nexus ebics-fetch -c $config_file
-Testing
--------
+For Testing
+-----------
If the bank account history has transactions that are useful for testing, it is
-possible to redownload them via the ``--pinned-start`` argument. Note: if the Nexus
-database contains already the bank account history, you might need to **reset** it,
-in order to have the redownloaded transactions ingested.
+possible to re-download them via the ``--pinned-start`` argument.
-.. note::
-
- Double-check the configuration: resetting the wrong database might cause DATA LOSS!
-
-For example, say that three back on the 2023-06-01 an handful of incoming transactions
-got booked at the bank account watched by Nexus. After such day, the following command
-would redownload them (and ingest them, if the database doesn't have them):
+The following command redownloads transactions *from* the pinned start until
+the present:
.. code-block:: console
- $ libeufin-nexus ebics-fetch -c $config_file --pinned-start 2023-06-01
-
+ $ libeufin-nexus ebics-fetch -c "$CONFIG_FILE" --pinned-start 2023-11-01
.. note::
- The command redownloads transactions *from* the pinned start until the present.
+ If the Nexus database already contains the bank account history, you might need
+ to **reset** the database in order to have the re-downloaded transactions be
+ properly ingested. Be careful when resetting the database: resetting the wrong
+ database might cause DATA LOSS!
diff --git a/libeufin/regional-automated-manual.rst b/libeufin/regional-automated-manual.rst
new file mode 100644
index 00000000..645e000f
--- /dev/null
+++ b/libeufin/regional-automated-manual.rst
@@ -0,0 +1,259 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Florian Dold
+ @author Marcello Stanisci
+ @author Christian Grothoff
+
+
+.. target audience: operator
+
+Regional Currency Automated Setup Manual
+########################################
+
+This manual describes how to setup a regional currency using a script that largely automates the process. If you want to do a custom setup you can follow the :doc:`custom setup manual<regional-custom-manual>`.
+
+
+.. contents:: Table of Contents
+ :local:
+
+.. include:: ../frags/regional-manual-architecture.rst
+
+Guided Automated Setup
+======================
+
+Prerequisites
++++++++++++++
+
+For this manual, we assume that the system is deployed on a contemporary
+Debian GNU/Linux Bookworm or Ubuntu Mantic system using the binary packages provided.
+Furthermore, you should run the process on a system with one or more globally
+reachable IP address(es) *and* with various DNS names already pointing to
+these IPs.
+
+Preparing the required subdomain names
+++++++++++++++++++++++++++++++++++++++
+
+The GNU Taler program needs to have three subdomains pointing to your server IP address, in order to let NGINX to accommodate each component.
+These are "bank", "exchange" and "backend", this said, you need to have a registered top level domain name,
+where you can create type (A) entries, as subdomains pointing to your own server public IP address.
+A very good advice when creating these subdomains, and if your domain panel lets you specify the TTL (time to live) figure, is
+to specify a very low value (such as 300), so in case of future changes, its value (the IP address), will be propagated quickly.
+
+Once you have added the three required subdomains in your domain control panel, you have to make sure as well, these subdomains have
+propagated over the Internet correctly, and they are currently publicly available.
+
+You can check this from your terminal very easily with the "ping" command, as this:
+
+.. code-block:: console
+
+ $ ping -c1 bank.domainname.ltd
+ $ ping -c1 exchange.domainname.ltd
+ $ ping -c1 backend.domainname.ltd
+
+You can also use `this tool <https://toolbox.googleapps.com/apps/dig/>`_ for the same purpose, and to check the propagation status.
+
+.. warning::
+ Take into account some hosting providers providing virtualized servers (VPS or VDS) can enable by default the firewall program "UFW", blocking by default the port number 443. So you have to either disable this firewall program, or open to this 443 port number to allow https.
+
+Now you are ready to go with the next step.
+
+Obtaining the Scripts
++++++++++++++++++++++
+
+First, download the deployment scripts via Git:
+
+.. code-block:: console
+
+ # apt update && apt install git
+ $ git clone git://git.taler.net/deployment
+
+Running the Guided Configuration
+++++++++++++++++++++++++++++++++
+
+Navigate into the *regional-currency/* directory and run *main.sh* as **root**:
+
+.. code-block:: console
+
+ $ cd deployment/regional-currency/
+ # ./main.sh
+
+The script will start by installing the required packages and then asking you fundamental questions about the desired setup, in particular:
+
+#. The name of the regional currency. It must have 3 to 11 letters.
+#. Whether to setup the regional currency to be backed by a fiat currency. You'll need a bank account at a fiat currency bank offering an online banking protocol supported by LibEuFin Nexus. If you answer ``y``, you will also need to provide the following information:
+
+ #. The ISO code of the fiat currency. Use 'CHF' or 'EUR'.
+ #. The IBAN of the fiat bank account.
+ #. The BIC of the fiat bank account.
+ #. The legal name of the fiat bank account.
+
+#. The name of the regional currency bank. It will be shown to business users when they interact with the system.
+#. The DNS domain name of your setup (i.e: domain.tld). The installer will create by itself all the needed subdomains for your domain name, as (``bank.$DOMAIN_NAME``, ``exchange.$DOMAIN_NAME`` and ``backend.$DOMAIN_NAME``). But, these subdomain names as explained before, must have been added beforehand to your DNS domain control panel, and they must be pointing to the IP address of the server on which you are running the installation (before you execute the installer).
+#. Whether to use TLS or not. You should answer ``y`` in most cases.
+#. Whether to setup SMS two-factor authentication using `Telesign <https://www.telesign.com>`_, multi-factor authentication is strongly recommended, especially when regional currency can be converted to fiat currency. This requires `a Customer ID and an API Key <https://developer.telesign.com/enterprise/docs/authentication#basic-authentication>`_. You should answer ``y`` in most cases.
+#. The admin password for the bank. Be absolutely sure to enter a very, very long and high-entropy password, preferably using the autogenerated one.
+#. Whether to generate terms of service (ToS) for the exchange from default templates.
+#. Whether to generate a privacy policy for the exchange from default templates.
+
+The information you entered as well as the generated bank admin password will
+be stored in a file called ``config/user.conf``. If you run the script in
+the future again (for example, to upgrade the installation), you will not be asked
+these questions a second time.
+
+After answering all of the questions, the actual installation will start. The
+scripts will download and configure various packages, which may take some time.
+Grab a coffee.
+
+.. note::
+
+ At this point, the setup is NOT connected to any fiat bank account! The next
+ steps must always be done manually!
+
+Running the script again from scratch
++++++++++++++++++++++++++++++++++++++
+
+If for some reason your installation doesn't work because you have answered erroneously
+some of the interactive questions, or you just want to reset the current installation and to re-deploy
+the script again for having its latest changes, you will have to proceed as follows:
+
+In brief, you need to wipe completely the "content" of the file config/user.conf, this doesn't mean
+to remove the file itself, but only its content. Even though you can do this manually by editing the file manually
+with your preferred text editor, you can also do this in one single command.
+
+.. code-block:: console
+
+ # rm config/user.conf
+
+.. note::
+
+ In future versions of the program when executed for the second time, the program itself will
+ show an option to offer wiping the content of this config/user.conf file, automatically.
+
+Multi-factor authentication
++++++++++++++++++++++++++++
+
+The script allows you to configure multi-factor authentication via SMS using Telesign as a provider. You can also configure multi-factor authentication via email or use providers other than Telesign for SMS. You will need to configure these channels manually as described in :ref:`multi-factor authentication <libeufin-mfa>`.
+
+If you choose not to back your regional currency with a fiat currency, you can stop here.
+
+Web-based Configuration
++++++++++++++++++++++++
+
+By default, the regional currency conversion rates are 1:1. You can change the conversion rates and the ``admin`` debt limit via the bank's web interface as the ``admin`` user.
+
+Connecting to a Fiat Bank: the EBICS setup
+++++++++++++++++++++++++++++++++++++++++++
+
+To complete the conversion setup, you have to set up an EBICS subscriber using the fiat bank account you specified during the automated setup.
+
+When you sign up for an EBICS-enabled bank account, the bank will provide you
+with various credentials. Those must be provided in the
+``/etc/libeufin/libeufin-nexus.conf`` configuration file.
+
+.. note::
+ As legacy transactions in that bank account would likely confuse the system, it is advisable to use a fresh bank account with an empty transaction history.
+
+The following snippet shows the mandatory configuration values:
+
+.. _core-config:
+
+.. code-block:: ini
+
+ [nexus-ebics]
+ # Bank
+ HOST_BASE_URL = https://ebics.postfinance.ch/ebics/ebics.aspx
+ BANK_DIALECT = postfinance
+
+ # EBICS IDs
+ HOST_ID = PFEBICS
+ USER_ID = PFC00563
+ PARTNER_ID = PFC00563
+
+.. warning::
+ This combination of HOST_ID, USER_ID and PARTNER_ID must never be used by another instance of libeufin-nexus or by other EBICS clients, otherwise data will be lost.
+
+Reuse existing client keys
+^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+If you have client keys from a previous EBICS setup you can copy the JSON file to ``/var/lib/libeufin-nexus/client-ebics-keys.json``.
+
+Make sure this file is accessible to the user running ``libeufin-nexus``, you should run:
+
+.. code-block:: console
+
+ $ chown libeufin-nexus:libeufin-nexus /var/lib/libeufin-nexus/client-ebics-keys.json
+
+Create new client keys
+^^^^^^^^^^^^^^^^^^^^^^
+
+Run the following command to start the EBICS setup process:
+
+.. code-block:: console
+
+ $ sudo -u libeufin-nexus libeufin-nexus ebics-setup
+
+If the previous command failed when running EBICS INI with an error code of
+``EBICS_INVALID_USER_OR_USER_STATE``, you need to confirm your keys to your bank to
+activate your account.
+
+To that end, the previous run should have left a PDF document that you can
+print, sign and send to the bank. Look for the message that looks like ``PDF
+file with keys created at '/tmp/libeufin-nexus-keys-$TIMESTAMP.pdf'``.
+
+Once the bank has received and processed this document you can continue.
+
+Get bank keys
+^^^^^^^^^^^^^
+
+Run the following command to finish the EBICS setup process:
+
+.. code-block:: console
+
+ $ sudo -u libeufin-nexus libeufin-nexus ebics-setup
+
+The EBICS setup is finished once the bank keys have been accepted.
+
+
+Configuring the Exchange for Conversion
++++++++++++++++++++++++++++++++++++++++
+
+In our automated setup the second account is automatically set up correctly
+without fees or special restrictions. However, various additional
+*restrictions* and *options* could be configured. Details are explained in
+the :ref:`regional conversion setup <regional-conversion-setup>` section for the
+manual setup and in the the manpage of ``taler-exchange-offline``.
+
+
+.. include:: ../frags/regional-system-on.rst
+.. include:: ../frags/deploying-tos.rst
+.. include:: ../frags/regional-manual-use.rst
+
+
+Installing Updates
+++++++++++++++++++
+
+The standard procedure for installing updates is to:
+
+ * First, make a backup (!)
+ * Stop Taler services
+ * Install new version
+ * Upgrade databases
+ * Start Taler services
+
+The "upgrade.sh" script in the "regional-currency/" folder of "deployment.git"
+shows how to do the above steps *except* for the backup. For the backup, all
+critical bits of data will be in the Postgresql databases. Thus, we recommend
+following the database manual on making backups.
diff --git a/libeufin/regional-custom-manual.rst b/libeufin/regional-custom-manual.rst
new file mode 100644
index 00000000..580168f3
--- /dev/null
+++ b/libeufin/regional-custom-manual.rst
@@ -0,0 +1,181 @@
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Florian Dold
+ @author Marcello Stanisci
+ @author Christian Grothoff
+
+
+.. target audience: operator
+
+Regional Currency Custom Setup Manual
+#####################################
+
+This manual describes how to setup a regional currency manually. If you want a guided setup you can follow the :doc:`automated setup manual<regional-automated-manual>`.
+
+.. contents:: Table of Contents
+ :local:
+
+.. include:: ../frags/regional-manual-architecture.rst
+
+Custom Manual Setup
+===================
+
+You first need to setup the :ref:`libeufin-bank<libeufin-bank>` and integrate it with a Taler exchange.
+
+If you don't want your regional currency to be backed by a fiat currency, you can stop here.
+
+Enabling Currency Conversion
+++++++++++++++++++++++++++++
+
+You need to setup the :ref:`libeufin-nexus<libeufin-nexus>` using a bank account at a bank dealing in fiat currency that
+offers an online banking protocol supported by LibEuFin Nexus.
+
+Next, you have to enable conversion and should ensure that at least one TAN
+channel for :ref:`multi-factor authentication <libeufin-mfa>` is configured.
+
+The following snippet shows how to enable conversion in ``libeufin-bank`` configuration:
+
+.. code-block:: ini
+
+ [libeufin-bank]
+ ALLOW_CONVERSION = YES
+ FIAT_CURRENCY = EUR
+
+Make sure to (re)start the libeufin-bank after changing
+these configuration options:
+
+.. code-block:: console
+
+ # systemctl restart libeufin-bank
+
+
+Web-based Configuration
++++++++++++++++++++++++
+
+Now you have to set the conversion rates and the ``admin`` debt limit via the bank's web interface as the ``admin`` user.
+
+.. _regional-conversion-setup:
+
+Configuring the Exchange for Conversion
++++++++++++++++++++++++++++++++++++++++
+
+An exchange that supports currency conversion needs to advertise two bank
+accounts, one in the regional currency and a second in the fiat currency. The
+conversion logic ensures that wire transfers in either account are
+immediately reflected in the other account.
+
+This section explains how to enable currency conversion at the exchange,
+which is critical for wallets to know how to wire fiat currency to an
+exchange to obtain regional currency.
+
+You will need to use the ``taler-exchange-offline`` tool to inform the
+exchange about the **fiat** bank account that can be used for cash in
+operations and also specify the URL for currency conversion. Additionally,
+you may also configure restrictions on the bank accounts that may originate
+the funds, for example, to prevent international wire transfers that may expose
+you to additional compliance risks.
+
+Given the ``$IBAN`` of the fiat currency bank account and ``$NAME`` as
+the (URL-encoded) name of the exchange-account owner, the following
+``taler-exchange-offline`` invocation can be used to notify wallets about
+the possibility of currency conversion (cash in):
+
+.. code-block:: console
+
+ # source config/user.conf
+ # sudo -u taler-exchange-offline \
+ taler-exchange-offline \
+ wire-fee now iban "${CURRENCY}":0 "${CURRENCY}":0 \
+ enable-account \
+ "${CONVERSION_PAYTO}" \
+ conversion-url "${PROTO}://bank.$DOMAIN_NAME/conversion-info/" \
+ display-hint 10 "CHF" \
+ debit-restriction deny \
+ credit-restriction \
+ regex \
+ 'payto://iban/.*/CH.*?receiver-name=.*' \
+ 'Swiss only' \
+ '{"de":"nur Schweiz","fr":"Suisse uniquement"}' \
+ upload
+
+Here, the ``$CONVERSION_URL`` must be set to the base URL of the conversion
+endpoint of the bank, which should be
+``https://bank.$DOMAIN/conversion-info/`` in our setup.
+
+The above commands set up the exchange to perform conversion with a
+restriction to only accept credit transfers from Swiss bank accounts. You may
+want to configure such restrictions on the bank accounts that may originate
+funds to prevent international wire transfers that may expose you to
+additional compliance risks.
+
+You can leave out the "credit-restriction" if you want to allow international
+inbound wire transfers.
+
+The "debit-restriction" is largely mandatory as in this setup the
+``taler-exchange-transfer`` is only configured to deal with the regional
+currency bank. Crediting fiat bank accounts must thus be done via the
+cash-out functionality of the regional currency bank account.
+
+The "display-hint" gives priority (10) for the fiat cash-in account over the
+regional currency account in the withdraw dialog of the wallets and labels the
+account with "CHF".
+
+.. note::
+
+ The above command adds a **second** bank account to the exchange.
+ You (or the guided setup script) should have already enabled the
+ regional currency bank account (without any "conversion-url").
+
+.. include:: ../frags/regional-system-on.rst
+.. include:: ../frags/deploying-tos.rst
+.. include:: ../frags/regional-manual-use.rst
+
+
+Maintenance
++++++++++++
+
+The ``taler-exchange-offline`` commands given above set fees only for the
+current year (``now``). Thus, before January 1st of each year, you must to set
+up new fees for the new calendar year. In a regional currency setup, this
+typically requires up to three annual settings:
+
+.. code-block:: console
+
+ # YEAR=2025 # edit if necessary
+ # FIAT_CURRENCY=CHF # edit if necessary
+ # REGIO_CURRENCY=NETZBON # edit if necessary
+ # sudo -u taler-exchange-offline \
+ taler-exchange-offline \
+ wire-fee "$YEAR" \
+ iban "${FIAT_CURRENCY}":0 "${FIAT_CURRENCY}":0 \
+ wire-fee "$YEAR" \
+ x-taler-bank "${REGIO_CURRENCY}":0 "${REGIO_CURRENCY}":0 \
+ global-fee $YEAR \
+ "${REGIO_CURRENCY}:0" \
+ "${REGIO_CURRENCY}:0" \
+ "${REGIO_CURRENCY}:0"
+ 4w 6y 4 \
+ upload
+
+If the fees are not all zero, simply change the respective place to specify
+a non-zero fee.
+
+.. note::
+
+ Additionally, the denomination signing keys will only have been
+ pre-generated for some time, depending on your ``LOOKAHEAD_SIGN``
+ configuration option. Thus, you may need to periodically run
+ the "taler-exchange-offline download sign upload" sequence as well!
diff --git a/libeufin/regional-manual.rst b/libeufin/regional-manual.rst
deleted file mode 100644
index e497e8c9..00000000
--- a/libeufin/regional-manual.rst
+++ /dev/null
@@ -1,482 +0,0 @@
-.. target audience: operator
-
-Regional Currency Setup Manual
-##############################
-
-In this manual, we explain how we model a regional currency and
-how to set up one using GNU Taler and LibEuFin technology.
-
-.. contents:: Table of Contents
-
-
-How to create/destroy regional currency
-=======================================
-
-In this model, the regional currency is backed by the fiat currency and users are
-offered two operations: *cash-in* to create regional currency starting from the fiat,
-and *cash-out* to destroy regional currency and obtain fiat currency back.
-
-The example below assumes that one single unit of regional currency is always backed
-by one single unit of fiat currency.
-
-Cash-in
-+++++++
-
-One fundamental entity to create the regional currency is the *master bank account*.
-The master bank account is hosted at one fiat bank and whenever it receives a *valid*
-fiat payment of N units, it triggers the creation of N units of regional currency.
-Such trigger causes the *admin bank account* at the regional bank to wire the N units of
-regional currency to the Taler exchange (regional) bank account. At this point, the
-Taler exchange is ready to issue the regional coins to the Taler wallet that proves
-to own them. Note: *valid* fiat payments are those with a Taler-relevant subject that
-should be generated by a Taler wallet.
-
-Cash-out
-++++++++
-
-Once a regional bank user confirms a cash-out operation of N units, the system sends
-a regional payment of N units to the *admin bank account*. This latter triggers then
-a fiat payment of N units to the fiat bank account owned by the user who initiated the
-cash-out.
-
-How are GNU Taler & LibEuFin used to create the regional currency?
-==================================================================
-
-Following are the main components to operate a regional currency based
-on GNU Taler and LibEuFin technology.
-
-- LibEuFin Nexus: is responsible to drive the master (fiat) bank account both to learn
- about incoming payments and to send fiat cash-out payments
-- LibEuFin Bank: offers basic banking operations, e.g. wire transfers, Taler withdrawals,
- account management, cash-out's
-- Taler exchange: server side of Taler operations.
-- Taler wallet: client side of Taler operations.
-- Taler merchant backend: abstracts Taler details to the shops.
-
-
-Guided basic setup
-==================
-
-Prerequisites
-+++++++++++++
-
-For this manual, we assume that the system is deployed on a contemporary
-Debian GNU/Linux or Ubuntu LTS system using the binary packages provided.
-Furthermore, you should run the process on a system with one or more globally
-reachable IP address(es) *and* with various DNS names already pointing to
-these IPs.
-
-To further simplify the process, we suggest to use (or at least study) the
-automatic deployment scripts provided in the ``deployment.git`` Git repository
-in the ``regional-currency/`` folder.
-
-
-Obtaining the scripts
-+++++++++++++++++++++
-
-First, download the deployment scripts via Git:
-
-.. code-block:: console
-
- $ git clone git://git.taler.net/deployment
-
-Guided Configuration
-++++++++++++++++++++
-
-This approach sets up a regional currency with cash-in/-out rates of 1:1.
-
-Navigate into the *regional-currency/* directory, and as **root** run:
-
-.. code-block:: console
-
- # ./main.sh
-
-The script will start by asking you fundamental questions about the
-desired setup, in particular:
-
- * The name of the regional currency. It must have 3 to 11 letters.
- Currently only 'NETZBON' is supported.
- * The ISO code of the fiat currency. Currently only 'CHF' is supported.
- * The name of the regional currency bank. It will be shown to business
- users when they interact with the system.
- * Whether to use TLS or not. You should answer ``y`` in most cases.
- * Whether to run taler-exchange-offline. Unless you need a high-security
- setup and expect to run an offline key management process, say ``y``.
- If you say ``n``, you will need to run ``taler-exchange-offline setup``
- on your offline system and provide the master public key. Furthermore,
- you should then study the exchange manual on offline key management to
- finish the exchange setup process later.
- * The admin password for the bank. Be absolutely sure to enter a very,
- very long and high-entropy password, preferably use the autogenerated one.
- * The DNS domain name of your setup (i.e: domain.tld). The installer will
- create by itself all the needed subdomains for your domain name,
- as (``bank.$DOMAIN``, ``exchange.$DOMAIN`` and ``backend.$DOMAIN``).
- But, these subdomain names, must have been added beforehand to your
- DNS domain control panel, and they must be pointing to the
- IP address of the system on which you are running the
- installation (before you execute the installer)).
-
-The information you entered as well as the generated bank admin password will be stored in a file called ``config/user.conf``.
-Should you run the script in the future (for example, to upgrade the installation),
-you will not be asked these questions a second time.
-
-After answering all of the questions, the actual installation will start. The
-scripts will download and configure various packages, which may take some time.
-Grab a coffee.
-
-.. note::
-
- At this point, the setup is NOT connected to any fiat bank account!
-
-Connecting to a Fiat Bank
-=========================
-
-Some regional currencies are backed by assets in a fiat currency and allow users
-to convert fiat currency into the regional currency (``cash in``) and to convert
-regional currency into fiat currency (``cash out``). Restrictions, exchange rates
-and fees may apply to these conversions. This section explains how to setup LibEuFin
-Nexus to communicate with the fiat bank account that backs the regional currency.
-
-Prerequisites
-+++++++++++++
-
-You must have a bank account at a bank dealing in fiat currency that offers an
-online banking protocol supported by LibEuFin Nexus. As legacy transactions
-in that bank account would likely confuse the system, it is highly advised to
-use a fresh bank account, with an empty transaction history.
-
-Today, the LibEuFin implementation supports EBICS 2.5 and 3.0 and has been
-tested with the Postfinance (CHF). Please note that banks tend to have their
-own dialects of finance messages and thus other retail banks may or may not work.
-Contact us if you need support for another bank or core banking protocol.
-
-EBICS setup
-+++++++++++
-
-.. include:: ../frags/ebics-setup.rst
-
-.. note::
-
- For debug setups where the cash-ins are simulated :ref:`this way <withdraw-simulation>`,
- this step can be entirely skipped.
-
-
-Enable regional currency conversion
-===================================
-
-Prerequisites
--------------
-
-This step assumes that you already have a working regional currency bank
-and have successfully connected to a backing fiat bank account.
-Follow the instructions from :ref:`EBICS subscriber setup <ebics-setup>`.
-
-Configuration
--------------
-
-Then you have to enable conversion and at least one TAN channel for cashout in the configuration file.
-
-.. code-block:: ini
-
- [libeufin-bank]
- ALLOW_CONVERSION = YES
- FIAT_CURRENCY = EUR
-
- TAN_SMS = libeufin-tan-sms.sh
- # And/Or
- TAN_EMAIL = libeufin-tan-email.sh
-
-
-You must have an exchange account with username ``exchange`` for conversion to work.
-Assuming that the configuration file exists at ``$config_file``, the following
-command would create one:
-
-.. code-block:: console
-
- libeufin-bank create-account '{"username":"exchange","password":"password","name":"Cashout Exchange","is_taler_exchange":true}' -c $config_file
-
-Then the following command would start the server with conversion API enabled :
-
-.. code-block:: console
-
- libeufin-bank serve -c $config_file
-
-Web-based Configuration
------------------------
-
-Now you should be able to setup conversion rates and ``admin`` debt limit though the Web
-interface of the bank as the ``admin`` user.
-
-Conversion ON!
---------------
-
-The last step is to run Nexus to import incoming bank
-transactions (cash in) and to trigger outgoing bank transactions (cash out).
-Refers to ``nexus-manual.conf`` for more details.
-
-
-
-Configuring the merchant
-========================
-
-In order to setup a shop, you need a merchant backend to run. The guided setup
-installs and sets one backend up, but the user is required to complete the shop
-configuration via the Web browser.
-
-One fundamental piece of information are the banking details, to allow merchant
-receive payments from the exchange. If you don't have a bank account at the regional
-bank, contact the administrator and get one. After being able to login to the new
-bank account, you can see your IBAN by clicking on the ``Welcome, $USERNAME`` message
-in the profile page. The IBAN is shown under the ``Internal IBAN`` box.
-
-Next, point your browser to ``$proto://backend.$domain_name/``. You should
-be welcomed by the following merchant backoffice page:
-
-.. image:: merchant_first_login.png
-
-Such page offers to create a merchant profile: fill any required field (including
-your access token) and click to ``confirm``. It should now be possible to associate
-the banking details to the profile just created: click to ``Bank account`` at the
-left of the page. The following page should be shown:
-
-.. image:: no_default_account_yet.png
-
-Click on the blue "+" sign on the top right of the page, and expect the following
-page to appear:
-
-.. image:: enter_instance_details.png
-
-This tutorial is focused on IBAN, so choose ``iban`` as the account type, and
-expect the following page to appear:
-
-.. image:: instance_iban_config.png
-
-After providing the details and confirming, the shop is ready to generate orders
-and accept payments.
-
-Make an order
-+++++++++++++
-
-Click on ``Orders`` at the top left corner of the merchant backoffice page; the
-following page should appear
-
-.. image:: create_orders.png
-
-After having filled the required fields, the interface should show the following
-page with the related links to check the status of the order and let wallets pay
-for it. Take note of the link beside ``Payment URI`` (we'll call it ``$payUri``).
-
-.. image:: payment_links.png
-
-In order to test the setup, it should be now possible to use the command line wallet
-to withdraw Taler coins and spend them to buy the order we just created.
-
-.. _withdraw-simulation:
-
-Pay for the order
-+++++++++++++++++
-
-This section explains how to pay for the order in a scenario where the fiat bank
-is simulated. The simulation takes place by crafting ad-hoc XML files as if the
-bank would have issued them. Such XML files carry information about incoming payments
-to the regional currency master bank account. Finally, the XML files are passed
-to LibEuFin nexus via a convenient CLI method. The responsible script for such
-simulation is ``withdraw.sh``.
-
-Run ``./withdraw.sh`` without any arguments. Assuming that you ran the command
-as the ``test-user``, after the execution, 5 units of the regional currency should
-be found in the CLI wallet owned by ``test-user``.
-
-
-Check it with:
-
-.. code-block:: console
-
- $ taler-wallet-cli balance
-
-If so, call the wallet in the following way to finally pay for the order just created:
-
-.. code-block:: console
-
- $ taler-wallet-cli handle-uri $payUri
-
-.. note::
-
- Reset the state before going to production, as it impacts the way nexus
- asks records to the bank. In particular, delete: any database and the
- files ``config/user.conf`` and ``config/internal.conf``, and finally run
- ``./main.sh`` again.
-
-
-Exchange-wallet integration
-===========================
-
-Although not strictly needed to start withdrawing regional money, this
-section explain how to enable the tight integration between Taler exchange
-and wallet, to let wallets learn about the possibility of withdrawing
-regional funds via a particular exchange.
-
-First, you need to use the ``taler-exchange-offline`` tool to inform the
-exchange about the fiat bank account that can be used for cash in operations
-and also specify the URL for currency conversion. Additionally, you may also
-configure restrictions on the bank accounts that may originate the funds, for
-example to prevent international wire transfers that may expose you to
-additional compliance risks.
-
-Given the ``$IBAN`` of the fiat currency bank account and ``$NAME`` as
-the (URL-encoded) name of the exchange-account owner, the following
-``taler-exchange-offline`` invocation can be used to notify wallets about
-the possibility of currency conversion (cash in):
-
-.. code-block:: console
-
- # taler-exchange-offline \
- enable-account \
- payto://iban/$IBAN?receiver-name=$NAME \
- conversion-url "$CONVERSION_URL" \
- upload
-
-Here, the ``$CONVERSION_URL`` must be set to the base URL of the conversion
-endpoint of the bank, which should be ``https://bank.$DOMAIN/conversion-info/``
-in our setup.
-
-Wallet setup
-============
-
-This section describes the interaction between the Taler graphical wallet (Android,
-iOS, WebExtensions) and the regional currency system.
-
-You need to add your regional currency exchange to the wallet. This can
-be done by scanning a QR code with a ``taler://withdraw-exchange/exchange.$DOMAIN``
-URL or by manually entering the URL into the respective ``Add exchange``
-dialogue.
-
-After starting the withdraw process and specifying the desired amount, the wallet
-should show you the details of the fiat wire transfer that must be made for the cash
-in to be completed. Once the money has arrived at the fiat bank account, Nexus will
-obtain the transaction data and the regional currency bank will create the
-corresponding amount in regional currency, crediting the GNU Taler exchange account.
-In turn, the exchange will issue the respective amount to your wallet.
-
-For testing, you should be able to *deposit* regional currency directly
-into your LibEuFin Bank account from the Taler wallet. Note: the wallet relies on the
-exchange to perform such deposit. So once the exchange has credited the regional
-currency account to your account and assuming the cash out rules are satisfied, you
-should then be able to start a cash out operation.
-
-..
- FIXME: uncomment once tested.
-
- Enable regional currency conversion
- ===================================
-
- Prerequisites
- +++++++++++++
-
- This step assumes that you already have a working regional currency bank
- and have successfully connected to a backing fiat bank account.
-
- Additionally, for each account that is allowed to convert regional currency
- into fiat, you must configure the (fiat) bank account number of the fiat
- currency with the respective account profile. Only the bank ``admin`` is
- allowed to set fiat bank account numbers.
-
- Furthermore, to achieve a reasonable security level, you must enable two
- factor authentication for "cash out" transactions. This requires you to
- configure an e-mail address or phone number for every account that supports
- "cash out" transactions --- and to setup your system for sending e-mails or
- SMS. This manual does not cover setting up e-mail. For SMS delivery, you will
- need to obtain credentials from an SMS provider and provide a script to send
- messages via such a provider.
-
- Configuration
- +++++++++++++
-
- You have to enable conversion and at least one TAN channel for cashout in the
- ``/etc/libeufin/libeufin-bank.conf`` configuration file:
-
- .. code-block:: console
-
- [libeufin-bank]
- ALLOW_CONVERSION = yes
- FIAT_CURRENCY = EUR
-
- TAN_SMS = libeufin-tan-sms.sh
- # And/Or
- TAN_EMAIL = libeufin-tan-email.sh
-
- Afterwards, restart the bank:
-
- .. code-block:: console
-
- # systemctl restart libeufin-bank
-
-
- The scripts TAN_SMS/EMAIL must accept the phone number / e-mail address
- as the ``$1`` parameter and the content in their standard input. The LibEuFin
- repository offers them in ``contrib/``: adjust to your setup!
-
- .. note::
-
- the TAN_SMS script relies on a Telesign account. For this reason,
- it needs a telesign-secret file found in the PATH, that defines the
- environment variables API_KEY and CUSTOMER_ID
-
- Web-based Configuration
- +++++++++++++++++++++++
-
- Now you should be able to setup conversion rates and ``admin`` debt limit though the Web
- interface of the bank as the ``admin`` user.
-
-
- Conversion ON!
- ++++++++++++++
-
- The last step is to enable the Nexus services to import incoming bank
- transactions (cash in) and to trigger outgoing bank transactions (cash out):
-
- .. code-block:: console
-
- # systemd enable --now libeufin-nexus-ebics-fetch
- # systemd enable --now libeufin-nexus-ebics-submit
-
- Going live!
- ===========
-
- Exchange setup
- ++++++++++++++
-
- First, you need to use the ``taler-exchange-offline`` tool to inform the
- exchange about the fiat bank account that can be used for cash in operations
- and also specify the URL for currency conversion. Additionally, you may also
- configure restrictions on the bank accounts that may originate the funds, for
- example to prevent international wire transfers that may expose you to
- additional compliance risks.
-
- Given the ``$IBAN`` of the fiat currency bank account and ``$NAME`` as
- the (URL-encoded) name of the exchange-account owner, the following
- ``taler-exchange-offline`` invocation can be used to inform wallets about
- the possibility of currency conversion (cash in) when wallets download
- ``/keys`` with bank account data from the exchange:
-
- .. code-block:: console
-
- # taler-exchange-offline \
- enable-account \
- payto://iban/$IBAN?receiver-name=$NAME \
- conversion-url "$CONVERSION_URL" \
- upload
-
- Here, the ``$CONVERSION_URL`` must be set to the base URL of the conversion
- endpoint of the bank, which should be ``https://bank.$DOMAIN/conversion-info/``
- in our setup.
-
-Podman deployment
-=================
-
-The Podman-based deployment installs, configures, and launches any Taler and
-LibEuFin service with the aim of serving a regional currency.
-
-Please clone ``git://git.taler.net/deployment`` and checkout the ``regio``
-branch. Navigate to the ``sandcastle-ng`` directory and read the README file:
-it should guide you through all the steps to running the regional currency.
diff --git a/manpages/challenger.conf.5.rst b/manpages/challenger.conf.5.rst
index a46b8461..626d11f7 100644
--- a/manpages/challenger.conf.5.rst
+++ b/manpages/challenger.conf.5.rst
@@ -71,6 +71,8 @@ AUTH_COMMAND
ADDRESS_TYPE
Type of the address that is being collected, returned as part of the ``address_type`` in the ``/info`` endpoint. Examples include ``email`` or ``phone``.
+ADDRESS_RESTRICTIONS
+ JSON object with a map of keys (names of the fields of the address to be entered by the user) to objects with a "regex" (string) containing an extended Posix regular expression for allowed address field values, and a "hint"/"hint_i18n" giving a human-readable explanation to display if the value entered by the user does not match the regex. Keys that are not mapped to such an object have no restriction on the value provided by the user. Examples would be '{"email":{"hint":"valid e-mail address required","regex":"^[a-zA-Z0-9\_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$"}' or '{"zip":{"hint":"numeric zip code required","regex":"^[0-9]+$"}'.
SEE ALSO
diff --git a/manpages/libeufin-bank.1.rst b/manpages/libeufin-bank.1.rst
index 60176ef0..5b8c3721 100644
--- a/manpages/libeufin-bank.1.rst
+++ b/manpages/libeufin-bank.1.rst
@@ -57,6 +57,8 @@ Its options are as follows:
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
**-r** \| **--reset**
If present, deletes any database table (WARNING: potential data loss)
@@ -72,6 +74,8 @@ Its options are as follows:
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
create-account
--------------
@@ -84,6 +88,8 @@ Its options are as follows:
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
**-u** \| **--username** *USERNAME*
Account unique username.
**-p** \| **--password** *PASSWORD*
@@ -119,6 +125,8 @@ Its options are as follows:
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
**--name** *NAME*
Legal name of the account owner.
**--public** *true|false*
@@ -145,6 +153,8 @@ Its options are as follows:
Print short help on options.
**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
.. include:: ../frags/libeufin-config-cli.rst
diff --git a/manpages/libeufin-bank.conf.5.rst b/manpages/libeufin-bank.conf.5.rst
index 0b27319f..35103760 100644
--- a/manpages/libeufin-bank.conf.5.rst
+++ b/manpages/libeufin-bank.conf.5.rst
@@ -35,6 +35,15 @@ The following options are from the “[libeufin-bank]” section.
CURRENCY
Internal currency of the libeufin-bank, e.g. “EUR” for Euro.
+WIRE_TYPE
+ Supported payment target type, this can either be ``iban`` or ``x-taler-bank``
+
+IBAN_PAYTO_BIC
+ Bank BIC used in generated iban payto URI. Required if WIRE_TYPE = iban
+
+X_TALER_BANK_PAYTO_HOSTNAME
+ Bank hostname used in generated x-taler-bank payto URI. Required if WIRE_TYPE = x-taler-bank
+
DEFAULT_DEBT_LIMIT
Default debt limit for newly created accounts. Defaults to CURRENCY:0 if not specified.
@@ -62,6 +71,14 @@ TAN_EMAIL
Path to TAN challenge transmission script via email. If not specified, this TAN channel will not be supported.
Only used if ``ALLOW_CONVERSION`` is ``YES``.
+TAN_SMS_ENV
+ Environment variables for the sms TAN script.
+ Only used if ``TAN_SMS`` is set.
+
+TAN_EMAIL_ENV
+ Environment variables for the email TAN script.
+ Only used if ``TAN_EMAIL`` is set.
+
SERVE
This can either be ``tcp`` or ``unix``.
@@ -69,6 +86,10 @@ PORT
Port on which the HTTP server listens, e.g. 9967.
Only used if ``SERVE`` is ``tcp``.
+BIND_TO
+ Which IP address should we bind to? E.g. ``127.0.0.1`` or ``::1``for loopback. Can also be given as a hostname.
+ Only used if ``SERVE`` is ``tcp``.
+
UNIXPATH
Which unix domain path should we bind to?
Only used if ``SERVE`` is ``unix``.
@@ -86,6 +107,9 @@ following value.
CONFIG
PostgreSQL connection string.
+SQL_DIR
+ Where are the SQL files to setup our tables?
+
SEE ALSO
========
diff --git a/manpages/libeufin-nexus.1.rst b/manpages/libeufin-nexus.1.rst
index 17ddd1ec..a0ed99ff 100644
--- a/manpages/libeufin-nexus.1.rst
+++ b/manpages/libeufin-nexus.1.rst
@@ -48,9 +48,11 @@ This command creates the client keys, if they aren't found already on the disk,
Its options are as follows:
**-h** \| **--help**
- Prints short help on options.
-**-c** \| **--config** \ ‌\ *FILENAME*
+ Print short help on options.
+**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
**--force-keys-resubmission**
Resubmits the client keys. If no keys were found, it creates and submits them.
**--auto-accept-keys**
@@ -68,8 +70,10 @@ Its options are as follows:
**-h** \| **--help**
Print short help on options.
-**-c** \| **--config** \ ‌\ *FILENAME*
+**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
**-r** \| **--reset**
If present, deletes any database table (WARNING: potential data loss)
@@ -83,8 +87,11 @@ Its options are as follows:
**-h** \| **--help**
Print short help on options.
-**-c** \| **--config** \ ‌\ *FILENAME*
+**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
+ Uploaded documents will be stored *before* being submitted to the bank. This directory would contain several directories, each named after the ``YYYY-MM-DD/submit`` format. The pain.001 file would then be named in the following schema: ``$microseconds_pain.001.xml``.
**--transient**
This flag, enabled by default, causes the command to check the database and submit only once, and then return.
@@ -92,17 +99,48 @@ Its options are as follows:
ebics-fetch
-----------
-This subcommand downloads banking records via EBICS and stores them into the database. Along the download, ebics-fetch would bounce incoming payments that do not have a valid Taler subject, or as well those with an already existing valid subject. Valid incoming payments are then stored in the database so that they can trigger Taler withdrawals. Along this process, ebics-submit would as well reconcile initiated outgoing payments with any outgoing transactions that shows up in the downloaded records.
+This subcommand downloads and parse EBICS files and ingest them into the database. Along the download, ebics-fetch would bounce incoming payments that do not have a valid Taler subject, or as well those with an already existing valid subject. Valid incoming payments are then stored in the database so that they can trigger Taler withdrawals. Along this process, ebics-submit would as well reconcile initiated outgoing payments with any outgoing transactions that show up in the downloaded records.
+
+The files type can be given as an argument to select what will be fetched. If no argument is given, all supported files are fetched. The following files are supported:
+
+* ``acknowledgement``: EBICS acknowledgement, retrieves the status of EBICS orders.
+* ``status``: Payment status, retrieves status of pending debits.
+* ``notification``: Debit & credit notifications, retrieves the history of confirmed debits and credits.
**-h** \| **--help**
Print short help on options.
-**-c** \| **--config** \ ‌\ *FILENAME*
+**-c** \| **--config** *FILENAME*
Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
+**--debug-ebics** *SAVEDIR*
+ Log EBICS content at SAVEDIR.
+ Downloaded documents will be stored *before* being ingested in the database. This directory would contain several directories, each named after the ``YYYY-MM-DD/fetch`` format. The stored files would then be named after the following schema: ``$microseconds_$filename``. Exception to this naming scheme are the HAC responses, since they do not get any filename assigned by the ZIP archive (they are sent unzipped). Their naming scheme is: ``$microseconds_HAC_response.pain.002.xml``.
**--transient**
This flag, enabled by default, causes the command to perform one download and return.
**--pinned-start**
Only supported in --transient mode, this option lets specify the earliest timestamp of the downloaded documents. The latest timestamp is always the current time.
+initiate-payment
+----------------
+
+This subcommand initiates an outgoing payment. The pending payment is stored in the database and will be performed the next time ``ebics-submit`` run.
+
+It takes one argument, the creditor IBAN payto URI, which must contain a 'receiver-name' and may contain an 'amount' and a 'message' if they have not been defined using CLI options.
+
+**-h** \| **--help**
+ Print short help on options.
+**-c** \| **--config** *FILENAME*
+ Specifies the configuration file.
+**-L** \| **--log** *LOGLEVEL*
+ Configure logging to use LOGLEVEL.
+**--amount** *AMOUNT*
+ The amount to transfer, payto 'amount' parameter takes the precedence
+**--subject** *TEXT*
+ The payment subject, payto 'message' parameter takes the precedence
+**--request-uid** *TEXT*
+ The payment request UID, will be randomly generated if missing.
+
.. include:: ../frags/libeufin-config-cli.rst
SEE ALSO
diff --git a/manpages/libeufin-nexus.conf.5.rst b/manpages/libeufin-nexus.conf.5.rst
index 5bb9df2a..e70ff7b3 100644
--- a/manpages/libeufin-nexus.conf.5.rst
+++ b/manpages/libeufin-nexus.conf.5.rst
@@ -111,7 +111,7 @@ the ``libeufin-nexus ebics-setup`` command.
CURRENCY
Name of the currency, e.g. “EUR” for Euro.
-HOST_BASE_URL = http://bank.example.com/
+HOST_BASE_URL
URL of the EBICS server
BANK_DIALECT
@@ -130,7 +130,6 @@ PARTNER_ID
EBICS specific: partner ID of the EBICS subscriber. This value must be assigned
by the bank after having activated a new EBICS subscriber.
-
BANK_PUBLIC_KEYS_FILE
Filesystem location where Nexus should store the bank public keys.
@@ -156,16 +155,6 @@ FREQUENCY
Duration value to instruct the ``ebics-submit`` subcommand how much to wait
before checking the database again to find new unsubmitted payments.
-SUBMISSIONS_LOG_DIRECTORY
- Optional value to define the path where the pain.001 documents gets stored *before*
- being submitted to the bank. This directory would contain several directories,
- each named after the YYYY-MM-DD format. The pain.001 file would then be named in
- the following schema: ``$submissionTimestampMicroseconds_requestUid_$requestUid_pain.001.xml``.
- ``$requestUid`` is the same value that constitutes the pain.001 ``MsgIg`` element.
- In the event that one log file would be overridden, ``ebics-submit`` fails without
- overriding it.
-
-
EBICS FETCH OPTIONS
-------------------
@@ -175,16 +164,16 @@ FREQUENCY
Duration value to instruct the ``ebics-fetch`` subcommand how often it should
download from the bank.
-STATEMENT_LOG_DIRECTORY
- Optional value to define the path where the downloaded documents would be stored
- *before* being ingested in the database. This directory would contain several
- directories, each named after the YYYY-MM-DD format. The stored files would then
- be named after the following schema:
- ``$downloadTimestampMicroseconds_$filenameAsGivenByTheBank``. In case one log file
- would be overridden, ``ebics-fetch`` fails without overriding it.
- Exception to this naming scheme are the HAC responses, since they do not get any
- filename assigned by the ZIP archive (they are sent unzipped). Their naming scheme
- is: ``$downloadTimestampMicroseconds_HAC_response.pain.002.xml``
+DATABASE OPTIONS
+----------------
+
+Setting the database belongs to the “[libeufin-nexusdb-postgres]” section and the following value.
+
+CONFIG
+ PostgreSQL connection string.
+
+SQL_DIR
+ Where are the SQL files to setup our tables?
SEE ALSO
========
diff --git a/manpages/libeufin-sandbox.1.rst b/manpages/libeufin-sandbox.1.rst
index e073500e..6f0948d0 100644
--- a/manpages/libeufin-sandbox.1.rst
+++ b/manpages/libeufin-sandbox.1.rst
@@ -70,16 +70,16 @@ config
This command takes argument ``NAME`` and creates a demobank with that name.
-Option ``--currency CUR`` (default: ``EUR``) specifes another currency.
+Option ``--currency CUR`` (default: ``EUR``) specifies another currency.
Option ``--captcha-url $URL`` specifies where the wallet user is going
-to be redirected to confirm the withdrawal operation. This $URL should
+to be redirected to confirm the withdrawal operation. This $URL should
point to the bank frontend. More precisely to the UI that let the user
finish a withdrawal operation that needs to be confirmed. Example of
-this value may be "https://bank.domain/#/operation/{wopid}" where
+this value may be "https://bank.domain/#/operation/{wopid}" where
"https://bank.domain" returns the demobank SPA and the demobank view under
the route "/operation/{wopid}" will show the status of the operation id {wopid}.
Note that "{wopid}" is literally in the --captcha-url config and replaced at
-runtime by the sandbox server.
+runtime by the sandbox server.
Option ``--bank-debt-limit N`` (default: 1000000) specifies that
the bank debt limit should be N (units of currency).
Similarly, option ``--users-debt-limit N`` (default: 1000) specifies
diff --git a/manpages/taler-exchange-dbinit.1.rst b/manpages/taler-exchange-dbinit.1.rst
index 0ee83543..cbbc494c 100644
--- a/manpages/taler-exchange-dbinit.1.rst
+++ b/manpages/taler-exchange-dbinit.1.rst
@@ -13,6 +13,7 @@ Synopsis
========
**taler-exchange-dbinit**
+[**-a** | **--inject-auditor**]
[**-c** *FILENAME* | **--config=**\ ‌\ *FILENAME*]
[**-g** | **--gc**]
[**-h** | **--help**]
@@ -31,6 +32,9 @@ Taler exchange to operate.
Its options are as follows:
+**-a** \| **--inject-auditor**
+ Installs triggers to notify real-time auditors of relevant changes to the database state.
+
**-c** *FILENAME* \| **--config=**\ ‌\ *FILENAME*
Use the configuration and other resources for the exchange to operate
from *FILENAME*.
diff --git a/manpages/taler-exchange-offline.1.rst b/manpages/taler-exchange-offline.1.rst
index 378c6312..bd8cd793 100644
--- a/manpages/taler-exchange-offline.1.rst
+++ b/manpages/taler-exchange-offline.1.rst
@@ -277,6 +277,14 @@ Afterwards, optional arguments can be given:
REST API that allows merchants and wallets to determine the current
conversion rate.
+ * ``display-hint`` $PRIORITY $LABEL: specifies that this bank account should
+ be shown to the user with the given numeric $PRIORITY (higher is earlier)
+ and with the given $LABEL. This is useful to ensure that if an exchange
+ has multiple bank accounts, we can show the user those that are most likely
+ useful first, and give them appropriately labeled hints for selecting other
+ accounts as well. A display hint is optional, if missing the priority is 0
+ and the wallet must pick some appropriate label itself somehow.
+
* ``credit-restriction`` $TYPE [$ARGS]: Specifies that there are
restrictions in place when crediting this bank account. Details depend on
the restriction $TYPE. This argument may be given multiple times, in which
diff --git a/manpages/taler-merchant-depositcheck.1.rst b/manpages/taler-merchant-depositcheck.1.rst
index d0af4cda..e243f0d2 100644
--- a/manpages/taler-merchant-depositcheck.1.rst
+++ b/manpages/taler-merchant-depositcheck.1.rst
@@ -18,6 +18,7 @@ Synopsis
[**-h** | **--help**]
[**-L** *LOGLEVEL* | **--loglevel=**\ ‌\ *LOGLEVEL*]
[**-l** *FILENAME* | **--logfile=**\ ‌\ *FILENAME*]
+[**-T** *USEC* | **--timetravel**\ \ *USEC*]
[**-t** | **--test**]
[**-v** | **--version**]
@@ -53,6 +54,11 @@ Its options are as follows:
if different processes are used to watch multiple bank accounts (for the
same instance or different instances).
+**-T** *USEC* \| **--timetravel=**\ \ *USEC*
+ Modify the system time by *USEC* microseconds.
+ *USEC* may be prefixed with ``+`` or ``-`` (e.g. ``-T +300``).
+ This option is intended for debugging/testing only.
+
**-t** \| **--test**
Run in test mode. Only runs until the current list of bank
transactions are all imported.
diff --git a/manpages/taler-merchant-exchange.1.rst b/manpages/taler-merchant-exchange.1.rst
index 6e18028e..de2b571f 100644
--- a/manpages/taler-merchant-exchange.1.rst
+++ b/manpages/taler-merchant-exchange.1.rst
@@ -17,6 +17,7 @@ Synopsis
[**-h** | **--help**]
[**-L** *LOGLEVEL* | **--loglevel=**\ ‌\ *LOGLEVEL*]
[**-l** *FILENAME* | **--logfile=**\ ‌\ *FILENAME*]
+[**-T** *USEC* | **--timetravel**\ \ *USEC*]
[**-t** | **--test**]
[**-v** | **--version**]
@@ -48,6 +49,11 @@ Its options are as follows:
**-l** *FILENAME* \| **--logfile=**\ ‌\ *FILENAME*
Send logging output to *FILENAME*.
+**-T** *USEC* \| **--timetravel=**\ \ *USEC*
+ Modify the system time by *USEC* microseconds.
+ *USEC* may be prefixed with ``+`` or ``-`` (e.g. ``-T +300``).
+ This option is intended for debugging/testing only.
+
**-t** \| **--test**
Run in test mode. Only runs until the current list of bank
transactions have all been checked.
diff --git a/manpages/taler-merchant-setup-reserve.1.rst b/manpages/taler-merchant-setup-reserve.1.rst
deleted file mode 100644
index 73fa2a0c..00000000
--- a/manpages/taler-merchant-setup-reserve.1.rst
+++ /dev/null
@@ -1,119 +0,0 @@
-taler-merchant-setup-reserve(1)
-###############################
-
-
-.. only:: html
-
- Name
- ====
-
- **taler-merchant-setup-reserve** - setup reserve for rewards
-
-
-Synopsis
-========
-
-**taler-merchant-setup-reserve**
-[**-A** *USERNAME:PASSWORD* | **--auth=**\ \ *USERNAME:PASSWORD*]
-[**-a** *VALUE* | **--amount=**\ \ *VALUE*]
-[**-C** *CERTFILE* | **--cert=**\ \ *CERTFILE*]
-[**-c** *FILENAME* | **--config=**\ \ *FILENAME*]
-[**-e** *URL* | **--exchange-url=**\ \ *URL*]
-[**-h** | **--help**]
-[**-k** *KEYFILE* | **--key=**\ \ *KEYFILE*]
-[**-L** *LOGLEVEL* | **--loglevel=**\ ‌\ *LOGLEVEL*]
-[**-l** *FILENAME* | **--logfile=**\ ‌\ *FILENAME*]
-[**-m** *URL* | **--merchant-url=**\ \ *URL*]
-[**-p** *KEYFILEPASSPHRASE* | **--pass=**\ \ *KEYFILEPASSPHRASE*]
-[**-t** *CERTTYPE* | **--type=**\ \ *CERTTYPE*]
-[**-w** *METHOD* | **--wire-method=**\ \ *METHOD*]
-[**-v** | **--version**]
-
-
-Description
-===========
-
-**taler-merchant-setup-reserve** is a command-line tool to setup a reserve
-(creating the private reserve key) and obtaining the wire transfer information
-from the exchange needed to fill the reserve.
-
-
-Options
-=======
-
-**-A** *USERNAME:PASSWORD* \| **--auth=**\ \ *USERNAME:PASSWORD*
- Use ``USERNAME`` and ``PASSWORD`` for HTTP client authentication.
- The ":" must be present as a separator.
- Note that this form of authentication has nothing to do with the TLS client
- certificate authentication supported with the ``-C``, ``-k`` and ``-p`` options.
- The ``PASSWORD`` given to this option is given to the server!
-
-**-a** *VALUE* \| **--amount=**\ \ *VALUE*
- Mandatory.
- Amount to be transferred to the reserve.
-
-**-C** *CERTFILE* \| **--cert=**\ \ *CERTFILE*
- The specified ``CERTFILE`` contains a TLS client certificate to be used to
- authenticate the client. See also ``-t``.
-
-**-c** *FILENAME* \| **--config=**\ \ *FILENAME*
- Use the configuration and other resources for the merchant to
- operate from ``FILENAME``.
-
-**-e** *URL* \| **--exchange-url=**\ \ *URL*
- Mandatory.
- Use ``URL`` for the exchange base URL.
- This is the exchange where the reserve will be created.
- The currency used in the amount specification must be offered by this exchange.
-
-**-h** \| **--help**
- Print short help on options.
-
-**-k** *KEYFILE* \| **--key=**\ \ *KEYFILE*
- The specified ``KEYFILE`` contains a TLS client private key to be used to
- authenticate the client. See also ``-p`` and ``-C``.
-
-**-L** *LOGLEVEL* \| **--loglevel=**\ ‌\ *LOGLEVEL*
- Specifies the log level to use. Accepted values are: ``DEBUG``, ``INFO``,
- ``WARNING``, ``ERROR``.
-
-**-l** *FILENAME* \| **--logfile=**\ ‌\ *FILENAME*
- Send logging output to *FILENAME*.
-
-**-m** *URL* \| **--merchant-url=**\ \ *URL*
- Mandatory.
- Use ``URL`` as the merchant base URL.
- Should include the path to the instance if the reserve is to be
- created for a non-default instance.
-
-**-p** *KEYFILEPASSPHRASE* \| **--pass=**\ \ *KEYFILEPASSPHRASE*
- The specified ``KEYFILEPASSPHRASE`` is to be used to decrypt the KEYFILE.
- See also ``-k``. Not to be confused with ``-A``.
- The ``KEYFILEPASSPHRASE`` given here is only used locally to decrypt the KEYFILE.
-
-**-t** *CERTTYPE* \| **--type=**\ \ *CERTTYPE*
- The specified CERTFILE contains a TLS client certificate of ``CERTTYPE``.
- Default is ``PEM``. See also ``-C``.
-
-**-w** *METHOD* \| **--wire-method=**\ \ *METHOD*
- Mandatory.
- Which wire method should be used.
- Needed to select the wire transfer method of the exchange.
- The method must be supported by the exchange.
- Typical values would be ``iban`` or ``x-taler-bank``.
-
-**-v** \| **--version**
- Print version information.
-
-
-See Also
-========
-
-taler-merchant-dbinit(1), taler.conf(5)
-
-
-Bugs
-====
-
-Report bugs by using https://bugs.taler.net/ or by sending electronic
-mail to <taler@gnu.org>.
diff --git a/manpages/taler-merchant-webhook.1.rst b/manpages/taler-merchant-webhook.1.rst
index 314c574a..c3a71509 100644
--- a/manpages/taler-merchant-webhook.1.rst
+++ b/manpages/taler-merchant-webhook.1.rst
@@ -17,6 +17,7 @@ Synopsis
[**-h** | **--help**]
[**-L** *LOGLEVEL* | **--loglevel=**\ ‌\ *LOGLEVEL*]
[**-l** *FILENAME* | **--logfile=**\ ‌\ *FILENAME*]
+[**-T** *USEC* | **--timetravel**\ \ *USEC*]
[**-t** | **--test**]
[**-v** | **--version**]
@@ -43,6 +44,11 @@ Its options are as follows:
**-l** *FILENAME* \| **--logfile=**\ ‌\ *FILENAME*
Send logging output to *FILENAME*.
+**-T** *USEC* \| **--timetravel=**\ \ *USEC*
+ Modify the system time by *USEC* microseconds.
+ *USEC* may be prefixed with ``+`` or ``-`` (e.g. ``-T +300``).
+ This option is intended for debugging/testing only.
+
**-t** \| **--test**
Run in test mode. Only runs until there are no more webhooks
to be executed.
diff --git a/manpages/taler-merchant-wirewatch.1.rst b/manpages/taler-merchant-wirewatch.1.rst
index 54daa767..e2f9d1df 100644
--- a/manpages/taler-merchant-wirewatch.1.rst
+++ b/manpages/taler-merchant-wirewatch.1.rst
@@ -17,6 +17,8 @@ Synopsis
[**-h** | **--help**]
[**-L** *LOGLEVEL* | **--loglevel=**\ ‌\ *LOGLEVEL*]
[**-l** *FILENAME* | **--logfile=**\ ‌\ *FILENAME*]
+[**-p** | **--persist**]
+[**-T** *USEC* | **--timetravel**\ \ *USEC*]
[**-t** | **--test**]
[**-v** | **--version**]
@@ -44,11 +46,19 @@ Its options are as follows:
**-l** *FILENAME* \| **--logfile=**\ ‌\ *FILENAME*
Send logging output to *FILENAME*.
+**-p** \| **--persist**
+ Run in persist mode. Does not exit when the account configuration changes. Useful when not running under systemd.
+
**-s** *SECTION* \| **--section=**\ \ *SECTION*
Configuration section to use. Default is taler-merchant-wirewatch. Needed
if different processes are used to watch multiple bank accounts (for the
same instance or different instances).
+**-T** *USEC* \| **--timetravel=**\ \ *USEC*
+ Modify the system time by *USEC* microseconds.
+ *USEC* may be prefixed with ``+`` or ``-`` (e.g. ``-T +300``).
+ This option is intended for debugging/testing only.
+
**-t** \| **--test**
Run in test mode. Only runs until the current list of bank
transactions are all imported.
diff --git a/manpages/taler-wallet-cli.1.rst b/manpages/taler-wallet-cli.1.rst
index 2d35bb87..dad790f5 100644
--- a/manpages/taler-wallet-cli.1.rst
+++ b/manpages/taler-wallet-cli.1.rst
@@ -46,8 +46,6 @@ for testing.
**withdraw-uri** URI
-**reward-uri** URI
-
**refund-uri** URI
**pay-uri** [**-y** | **--yes**] URI
diff --git a/manpages/taler.conf.5.rst b/manpages/taler.conf.5.rst
index 09b993e0..3074f68b 100644
--- a/manpages/taler.conf.5.rst
+++ b/manpages/taler.conf.5.rst
@@ -151,7 +151,9 @@ BIND_TO
MASTER_PUBLIC_KEY
Crockford Base32-encoded master public key, public version of the
- exchange's long-time offline signing key.
+ exchange's long-time offline signing key. This configuration option
+ is also used by the **auditor** to determine the public key of the
+ exchange which it is auditing.
AML_THRESHOLD
Largest amount in this currency that can be transferred per month without
@@ -160,15 +162,8 @@ AML_THRESHOLD
KYC_AML_TRIGGER
Program to run on KYC attribute data to decide whether we should immediately flag an account for AML review. Program must return 0 if a manual AML review is not needed, and non-zero to trigger an AML review. The KYC attribute data of the new user will be passed on standard-input.
-ENABLE_REWARDS
- This option can be used to announce that an exchange does not allow
- the use of the reserves for rewards. The default is YES which means
- that rewards are allowed. The option merely announces that
- rewards is enabled or disabled, and protocol-compliant merchant
- backends will then enable or disable the feature accordingly.
-
STEFAN_ABS
- Absolte amount to add as an offset in the STEFAN fee approximation
+ Absolute amount to add as an offset in the STEFAN fee approximation
curve (see DD47). Defaults to CURRENCY:0 if not specified.
STEFAN_LOG
@@ -187,6 +182,12 @@ BASE_URL
Added to wire transfers to enable tracking by merchants.
Used by the KYC logic when interacting with OAuth 2.0.
+TOPLEVEL_REDIRECT_URL
+ Where to redirect visitors that access the top-level
+ "/" endpoint of the exchange. Should point users to
+ information about the exchange operator.
+ Optional setting, defaults to "/terms".
+
AGGREGATOR_IDLE_SLEEP_INTERVAL
For how long should the taler-exchange-aggregator sleep when it is idle
before trying to look for more work? Default is 60 seconds.
@@ -298,6 +299,12 @@ KYC_OAUTH2_POST_URL
KYC_OAUTH2_CONVERTER_HELPER
Helper to convert JSON with KYC data returned by the OAuth2.0 info endpoint into GNU Taler internal format. Specific to the OAuth 2.0 provider.
+KYC_OAUTH2_DEBUG_MODE
+ Set to YES to allow error responses to include potentially
+ sensitive private information (such as full responses
+ from the OAuth 2.0 server) that might aid in debugging
+ problems. Should be set to "NO" in production.
+
EXCHANGE KYC KYCAID OPTIONS
^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/orphaned/taler-nfc-guide.rst b/orphaned/taler-nfc-guide.rst
index aa961d31..d025d347 100644
--- a/orphaned/taler-nfc-guide.rst
+++ b/orphaned/taler-nfc-guide.rst
@@ -231,8 +231,8 @@ to dereference the ``taler://pay`` URI from the example above:
# success response with no data
m<-w 9000
-(Note that this process works analogously for communication between a bank/ATM
-terminal or "reward provider".)
+(Note that this process works analogously for communication with a bank/ATM
+terminal.)
Request tunneling
diff --git a/screenshots/balance-list-1-ios-0.png b/screenshots/balance-list-1-ios-0.png
new file mode 100644
index 00000000..bead680a
--- /dev/null
+++ b/screenshots/balance-list-1-ios-0.png
Binary files differ
diff --git a/screenshots/balance-list-1-ios-latest.png b/screenshots/balance-list-1-ios-latest.png
new file mode 120000
index 00000000..d876cbcc
--- /dev/null
+++ b/screenshots/balance-list-1-ios-latest.png
@@ -0,0 +1 @@
+balance-list-1-ios-0.png \ No newline at end of file
diff --git a/screenshots/balance-list-2-ios-0.png b/screenshots/balance-list-2-ios-0.png
new file mode 100644
index 00000000..23efbbd5
--- /dev/null
+++ b/screenshots/balance-list-2-ios-0.png
Binary files differ
diff --git a/screenshots/balance-list-2-ios-latest.png b/screenshots/balance-list-2-ios-latest.png
new file mode 120000
index 00000000..4b7f977e
--- /dev/null
+++ b/screenshots/balance-list-2-ios-latest.png
@@ -0,0 +1 @@
+balance-list-2-ios-0.png \ No newline at end of file
diff --git a/screenshots/balance-list-android-0.png b/screenshots/balance-list-android-0.png
new file mode 100644
index 00000000..f87919f8
--- /dev/null
+++ b/screenshots/balance-list-android-0.png
Binary files differ
diff --git a/screenshots/balance-list-android-latest.png b/screenshots/balance-list-android-latest.png
new file mode 120000
index 00000000..0af04e4b
--- /dev/null
+++ b/screenshots/balance-list-android-latest.png
@@ -0,0 +1 @@
+balance-list-android-0.png \ No newline at end of file
diff --git a/screenshots/balance-list-firefox-0.png b/screenshots/balance-list-firefox-0.png
new file mode 100644
index 00000000..6a4fcb12
--- /dev/null
+++ b/screenshots/balance-list-firefox-0.png
Binary files differ
diff --git a/screenshots/balance-list-firefox-latest.png b/screenshots/balance-list-firefox-latest.png
new file mode 120000
index 00000000..390d4b60
--- /dev/null
+++ b/screenshots/balance-list-firefox-latest.png
@@ -0,0 +1 @@
+balance-list-firefox-0.png \ No newline at end of file
diff --git a/libeufin/create_orders.png b/screenshots/create_orders.png
index 74814c72..74814c72 100644
--- a/libeufin/create_orders.png
+++ b/screenshots/create_orders.png
Binary files differ
diff --git a/screenshots/cta-accept-tos-android-0.png b/screenshots/cta-accept-tos-android-0.png
new file mode 100644
index 00000000..c9537071
--- /dev/null
+++ b/screenshots/cta-accept-tos-android-0.png
Binary files differ
diff --git a/screenshots/cta-accept-tos-android-latest.png b/screenshots/cta-accept-tos-android-latest.png
new file mode 120000
index 00000000..89544b02
--- /dev/null
+++ b/screenshots/cta-accept-tos-android-latest.png
@@ -0,0 +1 @@
+cta-accept-tos-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-accept-tos-firefox-0.png b/screenshots/cta-accept-tos-firefox-0.png
new file mode 100644
index 00000000..6809d775
--- /dev/null
+++ b/screenshots/cta-accept-tos-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-accept-tos-firefox-latest.png b/screenshots/cta-accept-tos-firefox-latest.png
new file mode 120000
index 00000000..f1b6f069
--- /dev/null
+++ b/screenshots/cta-accept-tos-firefox-latest.png
@@ -0,0 +1 @@
+cta-accept-tos-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-accept-tos-ios-0.png b/screenshots/cta-accept-tos-ios-0.png
new file mode 100644
index 00000000..7d8d5ff8
--- /dev/null
+++ b/screenshots/cta-accept-tos-ios-0.png
Binary files differ
diff --git a/screenshots/cta-accept-tos-ios-latest.png b/screenshots/cta-accept-tos-ios-latest.png
new file mode 120000
index 00000000..091a79a1
--- /dev/null
+++ b/screenshots/cta-accept-tos-ios-latest.png
@@ -0,0 +1 @@
+cta-accept-tos-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-deposit-1-ios-0.png b/screenshots/cta-deposit-1-ios-0.png
new file mode 100644
index 00000000..6cf30dde
--- /dev/null
+++ b/screenshots/cta-deposit-1-ios-0.png
Binary files differ
diff --git a/screenshots/cta-deposit-1-ios-latest.png b/screenshots/cta-deposit-1-ios-latest.png
new file mode 120000
index 00000000..a3a21c74
--- /dev/null
+++ b/screenshots/cta-deposit-1-ios-latest.png
@@ -0,0 +1 @@
+cta-deposit-1-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-deposit-2-ios-0.png b/screenshots/cta-deposit-2-ios-0.png
new file mode 100644
index 00000000..49007f6c
--- /dev/null
+++ b/screenshots/cta-deposit-2-ios-0.png
Binary files differ
diff --git a/screenshots/cta-deposit-2-ios-latest.png b/screenshots/cta-deposit-2-ios-latest.png
new file mode 120000
index 00000000..5dd80393
--- /dev/null
+++ b/screenshots/cta-deposit-2-ios-latest.png
@@ -0,0 +1 @@
+cta-deposit-2-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-deposit-android-0.png b/screenshots/cta-deposit-android-0.png
new file mode 100644
index 00000000..74435360
--- /dev/null
+++ b/screenshots/cta-deposit-android-0.png
Binary files differ
diff --git a/screenshots/cta-deposit-android-latest.png b/screenshots/cta-deposit-android-latest.png
new file mode 120000
index 00000000..53a323c3
--- /dev/null
+++ b/screenshots/cta-deposit-android-latest.png
@@ -0,0 +1 @@
+cta-deposit-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-deposit-firefox-0.png b/screenshots/cta-deposit-firefox-0.png
new file mode 100644
index 00000000..e78538c7
--- /dev/null
+++ b/screenshots/cta-deposit-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-deposit-firefox-latest.png b/screenshots/cta-deposit-firefox-latest.png
new file mode 120000
index 00000000..93e5beca
--- /dev/null
+++ b/screenshots/cta-deposit-firefox-latest.png
@@ -0,0 +1 @@
+cta-deposit-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-android-0.png b/screenshots/cta-payment-android-0.png
new file mode 100644
index 00000000..d518c922
--- /dev/null
+++ b/screenshots/cta-payment-android-0.png
Binary files differ
diff --git a/screenshots/cta-payment-android-latest.png b/screenshots/cta-payment-android-latest.png
new file mode 120000
index 00000000..b858e45f
--- /dev/null
+++ b/screenshots/cta-payment-android-latest.png
@@ -0,0 +1 @@
+cta-payment-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-firefox-0.png b/screenshots/cta-payment-firefox-0.png
new file mode 100644
index 00000000..c9d01380
--- /dev/null
+++ b/screenshots/cta-payment-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-payment-firefox-latest.png b/screenshots/cta-payment-firefox-latest.png
new file mode 120000
index 00000000..26b0f16e
--- /dev/null
+++ b/screenshots/cta-payment-firefox-latest.png
@@ -0,0 +1 @@
+cta-payment-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-ios-0.png b/screenshots/cta-payment-ios-0.png
new file mode 100644
index 00000000..ad7cb8f0
--- /dev/null
+++ b/screenshots/cta-payment-ios-0.png
Binary files differ
diff --git a/screenshots/cta-payment-ios-latest.png b/screenshots/cta-payment-ios-latest.png
new file mode 120000
index 00000000..130b47c8
--- /dev/null
+++ b/screenshots/cta-payment-ios-latest.png
@@ -0,0 +1 @@
+cta-payment-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-paid-1-ios-0.png b/screenshots/cta-payment-paid-1-ios-0.png
new file mode 100644
index 00000000..09364982
--- /dev/null
+++ b/screenshots/cta-payment-paid-1-ios-0.png
Binary files differ
diff --git a/screenshots/cta-payment-paid-1-ios-latest.png b/screenshots/cta-payment-paid-1-ios-latest.png
new file mode 120000
index 00000000..c721af49
--- /dev/null
+++ b/screenshots/cta-payment-paid-1-ios-latest.png
@@ -0,0 +1 @@
+cta-payment-paid-1-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-paid-2-ios-0.png b/screenshots/cta-payment-paid-2-ios-0.png
new file mode 100644
index 00000000..b340000f
--- /dev/null
+++ b/screenshots/cta-payment-paid-2-ios-0.png
Binary files differ
diff --git a/screenshots/cta-payment-paid-2-ios-latest.png b/screenshots/cta-payment-paid-2-ios-latest.png
new file mode 120000
index 00000000..7b13031e
--- /dev/null
+++ b/screenshots/cta-payment-paid-2-ios-latest.png
@@ -0,0 +1 @@
+cta-payment-paid-2-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-paid-android-0.png b/screenshots/cta-payment-paid-android-0.png
new file mode 100644
index 00000000..51a412c7
--- /dev/null
+++ b/screenshots/cta-payment-paid-android-0.png
Binary files differ
diff --git a/screenshots/cta-payment-paid-android-latest.png b/screenshots/cta-payment-paid-android-latest.png
new file mode 120000
index 00000000..8aabd17e
--- /dev/null
+++ b/screenshots/cta-payment-paid-android-latest.png
@@ -0,0 +1 @@
+cta-payment-paid-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-payment-paid-firefox-0.png b/screenshots/cta-payment-paid-firefox-0.png
new file mode 100644
index 00000000..f67e2af3
--- /dev/null
+++ b/screenshots/cta-payment-paid-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-payment-paid-firefox-latest.png b/screenshots/cta-payment-paid-firefox-latest.png
new file mode 120000
index 00000000..22dd4530
--- /dev/null
+++ b/screenshots/cta-payment-paid-firefox-latest.png
@@ -0,0 +1 @@
+cta-payment-paid-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-peer-pull-initiate-android-0.png b/screenshots/cta-peer-pull-initiate-android-0.png
new file mode 100644
index 00000000..9be8abdf
--- /dev/null
+++ b/screenshots/cta-peer-pull-initiate-android-0.png
Binary files differ
diff --git a/screenshots/cta-peer-pull-initiate-android-latest.png b/screenshots/cta-peer-pull-initiate-android-latest.png
new file mode 120000
index 00000000..eeb4d8c9
--- /dev/null
+++ b/screenshots/cta-peer-pull-initiate-android-latest.png
@@ -0,0 +1 @@
+cta-peer-pull-initiate-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-peer-pull-initiate-firefox-0.png b/screenshots/cta-peer-pull-initiate-firefox-0.png
new file mode 100644
index 00000000..0d7c1b31
--- /dev/null
+++ b/screenshots/cta-peer-pull-initiate-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-peer-pull-initiate-firefox-latest.png b/screenshots/cta-peer-pull-initiate-firefox-latest.png
new file mode 120000
index 00000000..74339ee9
--- /dev/null
+++ b/screenshots/cta-peer-pull-initiate-firefox-latest.png
@@ -0,0 +1 @@
+cta-peer-pull-initiate-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-peer-pull-initiate-ios-0.png b/screenshots/cta-peer-pull-initiate-ios-0.png
new file mode 100644
index 00000000..421cae8c
--- /dev/null
+++ b/screenshots/cta-peer-pull-initiate-ios-0.png
Binary files differ
diff --git a/screenshots/cta-peer-pull-initiate-ios-latest.png b/screenshots/cta-peer-pull-initiate-ios-latest.png
new file mode 120000
index 00000000..e083752f
--- /dev/null
+++ b/screenshots/cta-peer-pull-initiate-ios-latest.png
@@ -0,0 +1 @@
+cta-peer-pull-initiate-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-peer-push-initiate-android-0.png b/screenshots/cta-peer-push-initiate-android-0.png
new file mode 100644
index 00000000..8ee0ef7d
--- /dev/null
+++ b/screenshots/cta-peer-push-initiate-android-0.png
Binary files differ
diff --git a/screenshots/cta-peer-push-initiate-android-latest.png b/screenshots/cta-peer-push-initiate-android-latest.png
new file mode 120000
index 00000000..ee8bd57a
--- /dev/null
+++ b/screenshots/cta-peer-push-initiate-android-latest.png
@@ -0,0 +1 @@
+cta-peer-push-initiate-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-peer-push-initiate-firefox-0.png b/screenshots/cta-peer-push-initiate-firefox-0.png
new file mode 100644
index 00000000..f566b0cb
--- /dev/null
+++ b/screenshots/cta-peer-push-initiate-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-peer-push-initiate-firefox-latest.png b/screenshots/cta-peer-push-initiate-firefox-latest.png
new file mode 120000
index 00000000..98a59294
--- /dev/null
+++ b/screenshots/cta-peer-push-initiate-firefox-latest.png
@@ -0,0 +1 @@
+cta-peer-push-initiate-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-peer-push-initiate-ios-0.png b/screenshots/cta-peer-push-initiate-ios-0.png
new file mode 100644
index 00000000..a574c880
--- /dev/null
+++ b/screenshots/cta-peer-push-initiate-ios-0.png
Binary files differ
diff --git a/screenshots/cta-peer-push-initiate-ios-latest.png b/screenshots/cta-peer-push-initiate-ios-latest.png
new file mode 120000
index 00000000..f42c0924
--- /dev/null
+++ b/screenshots/cta-peer-push-initiate-ios-latest.png
@@ -0,0 +1 @@
+cta-peer-push-initiate-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-url-entry-1-android-0.png b/screenshots/cta-url-entry-1-android-0.png
new file mode 100644
index 00000000..0705e7f0
--- /dev/null
+++ b/screenshots/cta-url-entry-1-android-0.png
Binary files differ
diff --git a/screenshots/cta-url-entry-1-android-latest.png b/screenshots/cta-url-entry-1-android-latest.png
new file mode 120000
index 00000000..3ff5ec48
--- /dev/null
+++ b/screenshots/cta-url-entry-1-android-latest.png
@@ -0,0 +1 @@
+cta-url-entry-1-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-url-entry-2-android-0.png b/screenshots/cta-url-entry-2-android-0.png
new file mode 100644
index 00000000..18ed9bdf
--- /dev/null
+++ b/screenshots/cta-url-entry-2-android-0.png
Binary files differ
diff --git a/screenshots/cta-url-entry-2-android-latest.png b/screenshots/cta-url-entry-2-android-latest.png
new file mode 120000
index 00000000..c589b4c9
--- /dev/null
+++ b/screenshots/cta-url-entry-2-android-latest.png
@@ -0,0 +1 @@
+cta-url-entry-2-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-url-entry-firefox-0.png b/screenshots/cta-url-entry-firefox-0.png
new file mode 100644
index 00000000..ba98a8e4
--- /dev/null
+++ b/screenshots/cta-url-entry-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-url-entry-firefox-latest.png b/screenshots/cta-url-entry-firefox-latest.png
new file mode 120000
index 00000000..f24b6cb8
--- /dev/null
+++ b/screenshots/cta-url-entry-firefox-latest.png
@@ -0,0 +1 @@
+cta-url-entry-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-wire-transfer-1-android-0.png b/screenshots/cta-wire-transfer-1-android-0.png
new file mode 100644
index 00000000..71e354f6
--- /dev/null
+++ b/screenshots/cta-wire-transfer-1-android-0.png
Binary files differ
diff --git a/screenshots/cta-wire-transfer-1-android-latest.png b/screenshots/cta-wire-transfer-1-android-latest.png
new file mode 120000
index 00000000..ec0bf1b0
--- /dev/null
+++ b/screenshots/cta-wire-transfer-1-android-latest.png
@@ -0,0 +1 @@
+cta-wire-transfer-1-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-wire-transfer-1-ios-0.png b/screenshots/cta-wire-transfer-1-ios-0.png
new file mode 100644
index 00000000..1d9fdbfd
--- /dev/null
+++ b/screenshots/cta-wire-transfer-1-ios-0.png
Binary files differ
diff --git a/screenshots/cta-wire-transfer-1-ios-latest.png b/screenshots/cta-wire-transfer-1-ios-latest.png
new file mode 120000
index 00000000..49cacb7f
--- /dev/null
+++ b/screenshots/cta-wire-transfer-1-ios-latest.png
@@ -0,0 +1 @@
+cta-wire-transfer-1-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-wire-transfer-2-android-0.png b/screenshots/cta-wire-transfer-2-android-0.png
new file mode 100644
index 00000000..719b890c
--- /dev/null
+++ b/screenshots/cta-wire-transfer-2-android-0.png
Binary files differ
diff --git a/screenshots/cta-wire-transfer-2-android-latest.png b/screenshots/cta-wire-transfer-2-android-latest.png
new file mode 120000
index 00000000..cb712f15
--- /dev/null
+++ b/screenshots/cta-wire-transfer-2-android-latest.png
@@ -0,0 +1 @@
+cta-wire-transfer-2-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-wire-transfer-2-ios-0.png b/screenshots/cta-wire-transfer-2-ios-0.png
new file mode 100644
index 00000000..3ea5b9ca
--- /dev/null
+++ b/screenshots/cta-wire-transfer-2-ios-0.png
Binary files differ
diff --git a/screenshots/cta-wire-transfer-2-ios-latest.png b/screenshots/cta-wire-transfer-2-ios-latest.png
new file mode 120000
index 00000000..6879480a
--- /dev/null
+++ b/screenshots/cta-wire-transfer-2-ios-latest.png
@@ -0,0 +1 @@
+cta-wire-transfer-2-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-wire-transfer-3-ios-0.png b/screenshots/cta-wire-transfer-3-ios-0.png
new file mode 100644
index 00000000..c15f9a5e
--- /dev/null
+++ b/screenshots/cta-wire-transfer-3-ios-0.png
Binary files differ
diff --git a/screenshots/cta-wire-transfer-3-ios-latest.png b/screenshots/cta-wire-transfer-3-ios-latest.png
new file mode 120000
index 00000000..daba13f8
--- /dev/null
+++ b/screenshots/cta-wire-transfer-3-ios-latest.png
@@ -0,0 +1 @@
+cta-wire-transfer-3-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-wire-transfer-firefox-0.png b/screenshots/cta-wire-transfer-firefox-0.png
new file mode 100644
index 00000000..7301cedc
--- /dev/null
+++ b/screenshots/cta-wire-transfer-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-wire-transfer-firefox-latest.png b/screenshots/cta-wire-transfer-firefox-latest.png
new file mode 120000
index 00000000..202edda1
--- /dev/null
+++ b/screenshots/cta-wire-transfer-firefox-latest.png
@@ -0,0 +1 @@
+cta-wire-transfer-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-1-android-0.png b/screenshots/cta-withdraw-1-android-0.png
new file mode 100644
index 00000000..3da47302
--- /dev/null
+++ b/screenshots/cta-withdraw-1-android-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-1-android-latest.png b/screenshots/cta-withdraw-1-android-latest.png
new file mode 120000
index 00000000..a183a53f
--- /dev/null
+++ b/screenshots/cta-withdraw-1-android-latest.png
@@ -0,0 +1 @@
+cta-withdraw-1-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-2-android-0.png b/screenshots/cta-withdraw-2-android-0.png
new file mode 100644
index 00000000..dbe4c7b1
--- /dev/null
+++ b/screenshots/cta-withdraw-2-android-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-2-android-latest.png b/screenshots/cta-withdraw-2-android-latest.png
new file mode 120000
index 00000000..6ca7417d
--- /dev/null
+++ b/screenshots/cta-withdraw-2-android-latest.png
@@ -0,0 +1 @@
+cta-withdraw-2-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-done-android-0.png b/screenshots/cta-withdraw-done-android-0.png
new file mode 100644
index 00000000..5860f280
--- /dev/null
+++ b/screenshots/cta-withdraw-done-android-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-done-android-latest.png b/screenshots/cta-withdraw-done-android-latest.png
new file mode 120000
index 00000000..7751f9d0
--- /dev/null
+++ b/screenshots/cta-withdraw-done-android-latest.png
@@ -0,0 +1 @@
+cta-withdraw-done-android-0.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-done-firefox-0.png b/screenshots/cta-withdraw-done-firefox-0.png
new file mode 100644
index 00000000..3a3fc2f6
--- /dev/null
+++ b/screenshots/cta-withdraw-done-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-done-firefox-latest.png b/screenshots/cta-withdraw-done-firefox-latest.png
new file mode 120000
index 00000000..f707ff77
--- /dev/null
+++ b/screenshots/cta-withdraw-done-firefox-latest.png
@@ -0,0 +1 @@
+cta-withdraw-done-firefox-0.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-done-ios-0.png b/screenshots/cta-withdraw-done-ios-0.png
new file mode 100644
index 00000000..93561c5d
--- /dev/null
+++ b/screenshots/cta-withdraw-done-ios-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-done-ios-latest.png b/screenshots/cta-withdraw-done-ios-latest.png
new file mode 120000
index 00000000..26f90634
--- /dev/null
+++ b/screenshots/cta-withdraw-done-ios-latest.png
@@ -0,0 +1 @@
+cta-withdraw-done-ios-0.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-firefox-0.png b/screenshots/cta-withdraw-firefox-0.png
new file mode 100644
index 00000000..e75fb875
--- /dev/null
+++ b/screenshots/cta-withdraw-firefox-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-firefox-1.png b/screenshots/cta-withdraw-firefox-1.png
new file mode 100644
index 00000000..61d3c0a4
--- /dev/null
+++ b/screenshots/cta-withdraw-firefox-1.png
Binary files differ
diff --git a/screenshots/cta-withdraw-firefox-latest.png b/screenshots/cta-withdraw-firefox-latest.png
new file mode 120000
index 00000000..189b3525
--- /dev/null
+++ b/screenshots/cta-withdraw-firefox-latest.png
@@ -0,0 +1 @@
+cta-withdraw-firefox-1.png \ No newline at end of file
diff --git a/screenshots/cta-withdraw-ios-0.png b/screenshots/cta-withdraw-ios-0.png
new file mode 100644
index 00000000..11dd9db0
--- /dev/null
+++ b/screenshots/cta-withdraw-ios-0.png
Binary files differ
diff --git a/screenshots/cta-withdraw-ios-latest.png b/screenshots/cta-withdraw-ios-latest.png
new file mode 120000
index 00000000..9c7d604b
--- /dev/null
+++ b/screenshots/cta-withdraw-ios-latest.png
@@ -0,0 +1 @@
+cta-withdraw-ios-0.png \ No newline at end of file
diff --git a/libeufin/enter_instance_details.png b/screenshots/enter_instance_details.png
index f2177091..f2177091 100644
--- a/libeufin/enter_instance_details.png
+++ b/screenshots/enter_instance_details.png
Binary files differ
diff --git a/libeufin/instance_iban_config.png b/screenshots/instance_iban_config.png
index 03fa8f36..03fa8f36 100644
--- a/libeufin/instance_iban_config.png
+++ b/screenshots/instance_iban_config.png
Binary files differ
diff --git a/libeufin/merchant_first_login.png b/screenshots/merchant_first_login.png
index 0baa0801..0baa0801 100644
--- a/libeufin/merchant_first_login.png
+++ b/screenshots/merchant_first_login.png
Binary files differ
diff --git a/libeufin/no_default_account_yet.png b/screenshots/no_default_account_yet.png
index c97c231d..c97c231d 100644
--- a/libeufin/no_default_account_yet.png
+++ b/screenshots/no_default_account_yet.png
Binary files differ
diff --git a/libeufin/payment_links.png b/screenshots/payment_links.png
index 0c58b286..0c58b286 100644
--- a/libeufin/payment_links.png
+++ b/screenshots/payment_links.png
Binary files differ
diff --git a/screenshots/transaction-list-android-0.png b/screenshots/transaction-list-android-0.png
new file mode 100644
index 00000000..e9309a83
--- /dev/null
+++ b/screenshots/transaction-list-android-0.png
Binary files differ
diff --git a/screenshots/transaction-list-android-latest.png b/screenshots/transaction-list-android-latest.png
new file mode 120000
index 00000000..d6123a74
--- /dev/null
+++ b/screenshots/transaction-list-android-latest.png
@@ -0,0 +1 @@
+transaction-list-android-0.png \ No newline at end of file
diff --git a/screenshots/transaction-list-firefox-0.png b/screenshots/transaction-list-firefox-0.png
new file mode 100644
index 00000000..d2d12ca8
--- /dev/null
+++ b/screenshots/transaction-list-firefox-0.png
Binary files differ
diff --git a/screenshots/transaction-list-firefox-latest.png b/screenshots/transaction-list-firefox-latest.png
new file mode 120000
index 00000000..463f0be8
--- /dev/null
+++ b/screenshots/transaction-list-firefox-latest.png
@@ -0,0 +1 @@
+transaction-list-firefox-0.png \ No newline at end of file
diff --git a/screenshots/transaction-list-ios-0.png b/screenshots/transaction-list-ios-0.png
new file mode 100644
index 00000000..6180c2c5
--- /dev/null
+++ b/screenshots/transaction-list-ios-0.png
Binary files differ
diff --git a/screenshots/transaction-list-ios-latest.png b/screenshots/transaction-list-ios-latest.png
new file mode 120000
index 00000000..e0d8b772
--- /dev/null
+++ b/screenshots/transaction-list-ios-latest.png
@@ -0,0 +1 @@
+transaction-list-ios-0.png \ No newline at end of file
diff --git a/taler-auditor-manual.rst b/taler-auditor-manual.rst
index 9f9bf1f7..94e86a8d 100644
--- a/taler-auditor-manual.rst
+++ b/taler-auditor-manual.rst
@@ -17,8 +17,13 @@
@author Christian Grothoff
-GNU Taler Auditor Operator Manual
-#################################
+Auditor Operator Manual
+#######################
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
Introduction
============
diff --git a/taler-challenger-manual.rst b/taler-challenger-manual.rst
index e4a59ee6..39b06710 100644
--- a/taler-challenger-manual.rst
+++ b/taler-challenger-manual.rst
@@ -1,7 +1,7 @@
..
This file is part of GNU TALER.
- Copyright (C) 2023 Taler Systems SA
+ Copyright (C) 2023, 2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -17,8 +17,13 @@
@author Christian Grothoff
@author Florian Dold
-GNU Taler Challenger Operator Manual
-####################################
+Challenger Operator Manual
+##########################
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
+
Introduction
============
@@ -519,3 +524,160 @@ The Challenger database can be re-initialized using:
However, running this command will result in all data in the database
being lost.
+
+
+.. _ChallengerCustomization:
+
+Template Customization
+======================
+
+The Challenger service comes with various HTML templates that are shown to
+guide users through the process. Challenger uses `Mustach
+<https://gitlab.com/jbol/mustach>`__ as the templating engine. This section
+describes the various templates. In general, the templates must be installed
+to the ``share/challenger/templates/`` directory. The file names must be of
+the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template and
+``$LANG`` is the 2-letter language code of the template. English templates
+must exist and will be used as a fallback. If the browser (user-agent) has
+provided language preferences in the HTTP header and the respective language
+exists, the correct language will be automatically served.
+
+The following subsections give details about each of the templates. The
+subsection title is the ``$NAME`` of the respective template.
+
+enter-$ADDRESS_TYPE-form
+------------------------
+
+These templates are used to ask the user to enter the address that challenger
+is expected to validate. Here, ``$ADDRESS_TYPE`` will be replaced by the
+``ADDRESS_TYPE`` configuration option in the ``[challenger]`` section of the
+configuration file. Typical values include ``address`` (for physical mailing
+addresses), ``phone`` (for mobile phone numbers) and ``email`` (for email
+addresses). For testing, ``file`` (where the TAN code is written into a local
+file) is also supported.
+
+The template is instantiated using the following information:
+
+ * restrictions: Object; map of keys (names of the fields of the address to be entered by the user) to objects with a "regex" (string) containing an extended Posix regular expression for allowed address field values, and a "hint"/"hint_i18n" giving a human-readable explanation to display if the value entered by the user does not match the regex. Keys that are not mapped to such an object have no restriction on the value provided by the user. See "ADDRESS_RESTRICTIONS" in the challenger configuration.
+ * fix_address: boolean; indicates if the given address cannot be changed
+ anymore, the form should be read-only if set to true.
+
+ * nonce: String; unique value identifying the challenge, should be shown
+ to the user so that they can recognize it when they receive the TAN code
+
+ * last_address: Object; form values from the previous submission if available,
+ details depend on the ``ADDRESS_TYPE``, should be used to pre-populate the form
+
+ * changes_left: Integer; number of times the address can still be changed,
+ may or may not be shown to the user
+
+enter-tan-form
+--------------
+
+This page should generate the HTML form for the user to enter the TAN code
+that they received at the respective address.
+
+The template is instantiated using the following information:
+
+ * nonce: String; unique value identifying the challenge, should be shown
+ to the user so that they can match it to the TAN code they received
+
+ * attempts_left: Integer; how many more attempts are allowed, might be
+ shown to the user, highlighting might be appropriate for low values
+ such as 1 or 2 (the form will never be used if the value is zero)
+
+ * address: Object; the address that is being validated, might be shown
+ or not
+
+ * transmitted: boolean; true if we just retransmitted the challenge,
+ false if we sent a challenge recently and thus refused to transmit it
+ again this time; might make a useful hint to the user
+
+ * next_tx_time: String; timestamp explaining when we would re-transmit
+ the challenge the next time (at the earliest) if requested by the user
+
+
+invalid-pin
+-----------
+
+The user has provided an invalid TAN code (HTTP 403 Forbidden).
+
+The template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * addresses_left: Integer; how many times is the user still allowed to
+ change the address; if 0, the user should not be shown a link to jump
+ to the address entry form
+
+ * pin_transmissions_left: Integer; how many times might the PIN still
+ be retransmitted
+
+ * auth_attempts_left: Integer; how many times might the user still try
+ entering the PIN code
+
+ * exhausted: Bool; if true, the PIN was not even evaluated as the user previously exhausted the number of attempts
+
+ * no_challenge: Bool; if true, the PIN was not even evaluated as no challenge was ever issued (the user must have skipped the step of providing their address first!)
+
+If both *pin_transmissions_left* and *auth_attempts_left* are zero, the link
+to re-enter the PIN should be hidden and the user should only be allowed to
+specify a different address. The form will never be generated if all three
+values are zero. (Thus there is always at least one valid choice when the form
+is shown.)
+
+
+validation-unknown
+------------------
+
+The user has tried to access a validation process that is not known to the
+backend (HTTP 404 Not Found).
+
+The template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * detail: String; optional, extended human-readable text provided to elaborate
+ on the error, should be shown to provide additional context
+
+
+invalid-request
+---------------
+
+The request of the client is invalid (HTTP 400 Bad Request).
+
+The template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * detail: String; optional, extended human-readable text provided to elaborate
+ on the error, should be shown to provide additional context
+
+
+internal-error
+--------------
+
+The service experienced an internal error (HTTP 500 Internal Server Error).
+
+The template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * detail: String; optional, extended human-readable text provided to elaborate
+ on the error, should be shown to provide additional context
diff --git a/taler-developer-manual.rst b/taler-developer-manual.rst
index ee7d93c3..3035e55d 100644
--- a/taler-developer-manual.rst
+++ b/taler-developer-manual.rst
@@ -28,6 +28,7 @@ Developer's Manual
.. contents:: Table of Contents
:depth: 2
+ :local:
Project Overview
@@ -92,8 +93,7 @@ overview:
sending invoices or payments to other wallets.
* taler-merchant-demos: various demonstration services operated at
- 'demo.taler.net', including a simple shop, donation page and a
- survey with reward functionality.
+ 'demo.taler.net', including a simple shop and a donation page.
There are other important repositories without code, including:
@@ -434,7 +434,7 @@ exported by ``~/.bashrc``.
Upgrading the ``demo`` environment should be done with care, and ideally be
coordinated on the mailing list before. It is our goal for ``demo`` to always
run a "working version" that is compatible with various published wallets.
-Please use the :doc:`demo upgrade checklist <checklist-demo-upgrade>` to make
+Please use the :doc:`demo upgrade checklist <checklists/checklist-demo-upgrade>` to make
sure everything is working.
Nginx is already configured to reach the services as exported by
Docker Compose.
@@ -476,8 +476,8 @@ All Taler components must be tagged with git before they are deployed on the
DD = day
SS = serial
-.. include:: checklist-demo-upgrade.rst
-
+.. include:: checklists/checklist-demo-upgrade.rst
+
Environments and Builders on taler.net
======================================
@@ -645,11 +645,16 @@ Developers and operators MUST NOT make changes to database schema
outside of this versioning. All tables of a GNU Taler component should live in their own schema.
+QA Plans
+========
+
+.. include:: checklists/qa-0.9.4.rst
+
Releases
========
-.. include:: checklist-release.rst
+.. include:: checklists/checklist-release.rst
Release Process
---------------
@@ -1519,18 +1524,16 @@ use when talking to end users or even system administrators.
trusted third party that verifies that the :term:`exchange` is operating correctly
bank
- traditional financial service provider who offers wire :term:`transfers <transfer>` between accounts
+ traditional financial service provider who offers
+ :term:`wire transfers <wire transfer>` between accounts
buyer
individual in control of a Taler :term:`wallet`, usually using it to
- :term:`spend` the :term:`coins` on :term:`contracts` (see also :term:`customer`).
+ :term:`spend` the :term:`coins <coin>` on :term:`contracts <contract>` (see also :term:`customer`).
close
- closes
- closed
- closing
operation an :term:`exchange` performs on a :term:`reserve` that has not been
- :term:`drained` by :term:`withdraw` operations. When closing a reserve, the
+ :term:`emptied <empty>` by :term:`withdraw` operations. When closing a reserve, the
exchange wires the remaining funds back to the customer, minus a :term:`fee`
for closing
@@ -1538,10 +1541,8 @@ use when talking to end users or even system administrators.
individual that directs the buyer (perhaps the same individual) to make a purchase
coin
- coins
coins are individual token representing a certain amount of value, also known as the :term:`denomination` of the coin
- commitment
refresh commitment
data that the wallet commits to during the :term:`melt` stage of the
:term:`refresh` protocol where it
@@ -1550,9 +1551,8 @@ use when talking to end users or even system administrators.
probabilistically (see: :term:`kappa`) during the :term:`reveal` stage.
contract
- contracts
formal agreement between :term:`merchant` and :term:`customer` specifying the
- :term:`contract terms` and signed by the merchant and the :term:`coins` of the
+ :term:`contract terms` and signed by the merchant and the :term:`coins <coin>` of the
customer
contract terms
@@ -1568,32 +1568,32 @@ use when talking to end users or even system administrators.
particular :term:`denomination`
deposit
- deposits
- depositing
operation by which a merchant passes coins to an exchange, expecting the
exchange to credit his bank account in the future using an
:term:`aggregate` :term:`wire transfer`
drain
- drained
- a :term:`reserve` is being drained when a :term:`wallet` is using the
- reserve's private key to :term:`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 :term:`closed` by the exchange.
+ process by which an exchange operator takes the profits
+ (from :term:`fees <fee>`) out of the escrow account and moves them into
+ their regular business account
dirty
- dirty coin
- a coin is dirty if its public key may be known to an entity other than
+ a :term:`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
+ empty
+ a :term:`reserve` is being emptied when a :term:`wallet` is using the
+ reserve's private key to :term:`withdraw` coins from it. This reduces
+ the balance of the reserve. Once the balance reaches zero, we say that
+ the reserve has been (fully) emptied. Reserves that are not emptied
+ (which is the normal process) are :term:`closed <close>` by the exchange.
+
exchange
Taler's payment service operator. Issues electronic coins during
withdrawal and redeems them when they are deposited by merchants
expired
- 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
@@ -1615,18 +1615,17 @@ use when talking to end users or even system administrators.
fee
an :term:`exchange` charges various fees for its service. The different
fees are specified in the protocol. There are fees per coin for
- :term:`withdrawing`, :term:`depositing`, :term:`melting`, and
- :term:`refunding`. Furthermore, there are fees per wire transfer
- for :term:`closing` a :term:`reserve`: and for
- :term:`aggregate` :term:`wire transfers` to the :term:`merchant`.
+ :term:`withdrawing <withdraw>`, :term:`depositing <deposit>`, :term:`melting <melt>`, and
+ :term:`refunding <refund>`. Furthermore, there are fees per wire transfer
+ when a :term:`reserve` is :term:`closed <close>`
+ and for :term:`aggregate` :term:`wire transfers <wire transfer>`
+ to the :term:`merchant`.
fresh
- fresh coin
- a coin is fresh if its public key is only known to the customer
+ a :term:`coin` is fresh if its public key is only known to the customer
- json
JSON
- JavaScript Object Notation
+ JavaScript Object Notation (JSON) is a
serialization format derived from the JavaScript language which is
commonly used in the Taler protocol as the payload of HTTP requests
and responses.
@@ -1636,11 +1635,11 @@ use when talking to end users or even system administrators.
The probability of successfully evading the income transparency with the
refresh protocol is 1:kappa.
- LibEuFin
- FIXME: explain
+ libeufin
+ Kotlin component that implements a regional currency bank and an
+ adapter to communicate via EBICS with European core banking systems.
link
- linking
specific step in the :term:`refresh` protocol that an exchange must offer
to prevent abuse of the :term:`refresh` mechanism. The link step is
not needed in normal operation, it just must be offered.
@@ -1650,9 +1649,7 @@ use when talking to end users or even system administrators.
message signing keys
melt
- melted
- melting
- step of the :term:`refresh` protocol where a :term:`dirty coin`
+ step of the :term:`refresh` protocol where a :term:`dirty` :term:`coin`
is invalidated to be reborn :term:`fresh` in a subsequent
:term:`reveal` step.
@@ -1678,19 +1675,19 @@ use when talking to end users or even system administrators.
recoup
Operation by which an exchange returns the value of coins affected
- by a :term:`revocation` to their :term:`owner`, either by allowing the owner to
+ by a :term:`revocation <revoke>` to their :term:`owner`, either by allowing the owner to
withdraw new coins or wiring funds back to the bank account of the :term:`owner`.
planchet
precursor data for a :term:`coin`. A planchet includes the coin's internal
secrets (coin private key, blinding factor), but lacks the RSA signature
- of the :term:`exchange`. When :term:`withdrawing`, a :term:`wallet`
+ of the :term:`exchange`. When :term:`withdrawing <withdraw>`, a :term:`wallet`
creates and persists a planchet before asking the exchange to sign it to
get the coin.
purchase
Refers to the overall process of negotiating a :term:`contract` and then
- making a payment with :term:`coins` to a :term:`merchant`.
+ making a payment with :term:`coins <coin>` to a :term:`merchant`.
privacy policy
Statement of an operator how they will protect the privacy of users.
@@ -1703,13 +1700,11 @@ use when talking to end users or even system administrators.
merchant backend.
refresh
- refreshing
- operation by which a :term:`dirty coin` is converted into one or more
- :term:`fresh` coins. Involves :term:`melting` the :term:`dirty coin` and
- then :term:`revealing` so-called :term:`transfer keys`.
+ operation by which a :term:`dirty` :term:`coin` is converted into one or more
+ :term:`fresh` coins. Involves :term:`melting <melt>` the :term:`dirty` coins and
+ then :term:`revealing <reveal>` so-called :term:`transfer keys <transfer key>`.
refund
- refunding
operation by which a merchant steps back from the right to funds that he
obtained from a :term:`deposit` operation, giving the right to the funds back
to the customer
@@ -1721,25 +1716,23 @@ use when talking to end users or even system administrators.
reserve
accounting mechanism used by the exchange to track customer funds
- from incoming :term:`wire transfers`. A reserve is created whenever
+ from incoming :term:`wire transfers <wire transfer>`. 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 :term:`wallet`
to :term:`withdraw` up to the amount received in :term:`fresh`
- :term:`coins` from the reserve, thereby draining the reserve. If a
- reserve is not drained, the exchange eventually :term:`closes` it.
+ :term:`coins <coin>` from the reserve, thereby emptying the reserve. If a
+ reserve is not emptied, the exchange will eventually :term:`close` 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.
reveal
- revealing
step in the :term:`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 :term:`fresh` coins.
revoke
- 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
@@ -1751,22 +1744,14 @@ use when talking to end users or even system administrators.
time.
spend
- spending
operation by which a customer gives a merchant the right to deposit
coins in return for merchandise
- transfer
- transfers
- wire transfer
- wire transfers
- method of sending funds between :term:`bank` accounts
-
transfer key
- transfer keys
special cryptographic key used in the :term:`refresh` protocol, some of which
are revealed during the :term:`reveal` step. Note that transfer keys have,
- despite the name, no relationship to :term:`wire transfers`. They merely
- help to transfer the value from a :term:`dirty coin` to a :term:`fresh coin`
+ despite the name, no relationship to :term:`wire transfers <wire transfer>`. They merely
+ help to transfer the value from a :term:`dirty` coin to a :term:`fresh` coin
terms
the general terms of service of an operator, possibly including
@@ -1799,25 +1784,27 @@ use when talking to end users or even system administrators.
Cross-browser API used to implement the GNU Taler wallet browser extension.
wire gateway
- FIXME: explain
+ API used by the exchange to talk with some real-time gross settlement system
+ (core banking system, blockchain) to notice inbound credits wire transfers
+ (during withdraw) and to trigger outbound debit wire transfers (primarily
+ for deposits).
+
+ wire transfer
+ a wire transfer is a method of sending funds between :term:`bank` accounts
wire transfer identifier
- 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.
withdraw
- withdrawing
- withdrawal
operation by which a :term:`wallet` can convert funds from a :term:`reserve` to
fresh coins
zombie
- zombie coin
- coin where the respective :term:`denomination key` is past its
- :term:`deposit` :term:`expiration` time, but which is still (again) valid
- for an operation because it was :term:`melted` while it was still
+ :term:`coin` where the respective :term:`denomination key` is past its
+ :term:`deposit` :term:`expiration <expired>` time, but which is still (again) valid
+ for an operation because it was :term:`melted <melt>` while it was still
valid, and then later again credited during a :term:`recoup` process
diff --git a/taler-exchange-manual.rst b/taler-exchange-manual.rst
index 742b0c8e..f0c345c7 100644
--- a/taler-exchange-manual.rst
+++ b/taler-exchange-manual.rst
@@ -1,7 +1,7 @@
..
This file is part of GNU TALER.
- Copyright (C) 2014-2023 Taler Systems SA
+ Copyright (C) 2014-2024 Taler Systems SA
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free Software
@@ -17,8 +17,13 @@
@author Christian Grothoff
@author Florian Dold
-GNU Taler Exchange Operator Manual
-##################################
+Exchange Operator Manual
+########################
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
Introduction
============
@@ -35,6 +40,7 @@ About this manual
This manual targets system administrators who want to install and
operate a GNU Taler exchange.
+
Organizational prerequisites
----------------------------
@@ -822,369 +828,32 @@ configuration of the online machine:
Wire Gateway Setup
==================
-The Taler Wire Gateway is an API that connects the Taler exchange to
-the underlying core banking system.
-
-LibEuFin is an implementation of the Wire Gateway API for the EBICS protocol.
-This section will walk through (1) installing and configuring LibEuFin and
-(2) connecting the Taler Exchange to LibEuFin.
-
-
-Installation and Basic Configuration
-------------------------------------
-
-First, install the ``libeufin`` package. This can be done on the ``exchange-online``
-machine or a different one.
-
-.. code-block:: shell-session
-
- [root@exchange-online]# apt-get install -y libeufin
-
-The main component of LibEuFin is called the Nexus. It implements a Web
-service that provides a JSON abstraction layer to access bank accounts.
-
-The HTTP port and database connection string can be edited in the configuration:
-
-.. code-block:: ini
- :caption: /etc/libeufin/nexus.env
-
- LIBEUFIN_NEXUS_PORT=5017
- LIBEUFIN_NEXUS_DB_CONNECTION=jdbc:sqlite:/var/lib/libeufin/nexus/nexus-db.sqlite3
-
-After configuring the database, you can start the service.
-The database is initialized automatically.
-
-
-.. code-block:: shell-session
-
- [root@exchange-online]# systemctl enable libeufin-nexus
- [root@exchange-online]# systemctl start libeufin-nexus
-
-You can now create a superuser account. The command to
-create the superuser needs direct database access, thus
-the configuration file is sourced first, and the relevant
-environment variable is exported.
-
-.. code-block:: console
-
- [root@exchange-online]# source /etc/libeufin/nexus.env
- [root@exchange-online]# export LIBEUFIN_NEXUS_DB_CONNECTION
- [root@exchange-online]# NEXUS_ADMIN_PW=$(tr -dc A-Za-z0-9 </dev/urandom | head -c 13)
- [root@exchange-online]# libeufin-nexus superuser admin --password $NEXUS_ADMIN_PW
-
-If you omit ``--password $NEXUS_ADMIN_PW``, you will interactively be asked for a password.
-For simplicity, a superuser can as well act as a normal user, but an API
-to create less privileged users is offered.
-
-.. note::
+The :ref:`Taler Wire Gateway <taler-wire-gateway-http-api>` is an API that
+connects the Taler exchange to the underlying core banking system. There are
+several implementations of wire gateways:
- User and permissions management in LibEuFin is still under development.
- In particular, permissions for non-superusers are very limited at the moment.
+ * `Project deploymerization <https://git.taler.net/depolymerization.git>`_ implements a wire gateway on top of Bitcoin or Ethereum
+ * The :ref:`libeufin-bank <libeufin-bank>` provides a wire gateway interface on top of a regional currency bank
+ * The **taler-fakebank-run** command is an in-memory bank simulator with a wire gateway interface for testing
+.. FIXME :ref:`libeufin-nexus <libeufin-nexus>` is an implementation of the Wire Gateway API for the EBICS protocol. Add to list above once nexus implements the TWG directly!
-Connecting Nexus with an EBICS account
---------------------------------------
-
-The command line interface of the LibEuFin Nexus needs the following three
-values to be defined in the environment: ``LIBEUFIN_NEXUS_URL``,
-``LIBEUFIN_NEXUS_USERNAME``, and ``LIBEUFIN_NEXUS_PASSWORD``. In this example,
-``LIBEUFIN_NEXUS_USERNAME`` should be set to ``admin``, and
-``LIBEUFIN_NEXUS_PASSWORD`` to the value hold in ``NEXUS_ADMIN_PW`` from the
-previous step (the ``libeufin-nexus superuser`` command). The
-``LIBEUFIN_NEXUS_URL`` could be given as ``http://localhost:5017/``.
-
-Next, we create a EBICS *bank connection* that Nexus can use to communicate with the bank.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- new-ebics-connection \
- --ebics-url $EBICS_BASE_URL \
- --host-id $EBICS_HOST_ID \
- --partner-id $EBICS_PARTNER_ID \
- --ebics-user-id $EBICS_USER_ID \
- $CONNECTION_NAME
-
-If this step executes correctly, Nexus will have created all the cryptographic
-material that is needed on the client side; in this EBICS example, it created
-the signature and identification keys. It is therefore advisable to *make
-a backup copy* of such keys.
-
-.. code-block:: console
+Before continuing, you need to decide which wire gateway you want to use,
+and install and configure it on your system. Afterwards, you need to
+have two key pieces of information from that setup:
- [root@exchange-online]# libeufin-cli \
- connections \
- export-backup \
- --passphrase $SECRET \
- --output-file $BACKUP_FILE \
- $CONNECTION_NAME
+ * The username and password to access the exchange's account in the system.
+ * The ``payto://`` URI of that account (see `RFC 8905 <https://www.rfc-editor.org/rfc/rfc8905>`_).
-At this point, Nexus needs to both communicate its keys to the bank, and
-download the bank's keys. This synchronization happens through the INI, HIA, and
-finally, HPB message types.
-
-After the electronic synchronization, the subscriber must confirm their keys
-by sending a physical mail to the bank. The following command helps generating
-such letter:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli connections get-key-letter $CONNECTION_NAME out.pdf
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- connect \
- $CONNECTION_NAME
-
-..
- FIXME: Maybe is not 100% clear that 'connecting' means exchanging keys
- with the bank?
-
-Once the connection is synchronized, Nexus needs to import locally the data
-corresponding to the bank accounts offered by the bank connection just made.
-The command below downloads the list of the bank accounts offered by ``$CONNECTION_NAME``.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- download-bank-accounts \
- $CONNECTION_NAME
-
-It is now possible to list the accounts offered by the connection.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- list-offered-bank-accounts \
- $CONNECTION_NAME
-
-.. note::
-
- The ``nexusBankAccountId`` field should at this step be ``null``,
- as we have not yet imported the bank account and thus the account
- does not yet have a local name.
-
-Nexus now needs an explicit import of the accounts it should manage. This
-step is needed to let the user pick a custom name for such accounts.
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli \
- connections \
- import-bank-account \
- --offered-account-id testacct01 \
- --nexus-bank-account-id $LOCAL_ACCOUNT_NAME \
- $CONNECTION_NAME
-
-Once a Nexus user imported a bank account (``$LOCAL_ACCOUNT_NAME``)
-under a certain connection (``$CONNECTION_NAME``), it is possible
-to accomplish the usual operations for any bank account: asking for the
-list of transactions, and making a payment.
-
-Testing: Requesting the transaction history
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-The LibEuFin Nexus keeps a local copy of the bank account's transaction
-history. Before querying transactions locally, it is necessary
-to request transactions for the bank account via the bank connection.
-
-This command asks Nexus to download the latest transaction reports/statements
-through the bank connection:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts fetch-transactions $LOCAL_ACCOUNT_NAME
-
-.. note::
-
- By default, the latest available transactions are fetched. It is also
- possible to specify a custom date range (or even all available transactions)
- and the type of transactions to fetch (inter-day statements or intra-day
- reports).
-
-..
- FIXME: Possibly the date range filter is still missing, see #6243.
-
-Once Nexus has stored all the information in the database, the
-client can ask to actually see the transactions:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts transactions $LOCAL_ACCOUNT_NAME
-
-Testing: Making payments
-^^^^^^^^^^^^^^^^^^^^^^^^
-
-Payments pass through two phases: preparation and submission. The preparation
-phase assigns the payment initiation a unique ID, which prevents accidental
-double submissions of payments in case of network failures or other
-disruptions.
-
-
-The following command prepares a payment:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts prepare-payment \
- --creditor-iban=$IBAN_TO_SEND_MONEY_TO \
- --creditor-bic=$BIC_TO_SEND_MONEY_TO \
- --creditor-name=$CREDITOR_NAME \
- --payment-amount=$AMOUNT \
- --payment-subject=$SUBJECT \
- $LOCAL_ACCOUNT_NAME
-
-Note: the ``$AMOUNT`` value needs the format ``X.Y:CURRENCY``; for example
-``EUR:10``, or ``EUR:1.01``.
-
-The previous command should return a value (``$UUID``) that uniquely
-identifies the prepared payment in the Nexus system. That is needed
-in the next step, to **send the payment instructions to the bank**:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts submit-payments \
- --payment-uuid $UUID \
- $LOCAL_ACCOUNT_NAME
-
-Automatic scheduling
-^^^^^^^^^^^^^^^^^^^^
-
-With an EBICS bank connection, the LibEuFin Nexus needs to regularly query for
-new transactions and (re-)submit prepared payments.
-
-It is possible to schedule these tasks via an external task scheduler such as
-cron(8). However, the nexus also has an internal task scheduling mechanism for
-accounts.
-
-
-The following three commands create a schedule for submitting payments hourly,
-fetching transactions (intra-day reports) every 5 minutes, and (inter-day statements)
-once at 11pm every day:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \
- --task-type="submit" \
- --task-name='submit-payments-hourly' \
- --task-cronspec='0 0 *'
-
- [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \
- --task-type="fetch" \
- --task-name='fetch-5min' \
- --task-cronspec='0 */5 *' \
- --task-param-level=report \
- --task-param-range-type=latest
-
- [root@exchange-online]# libeufin-cli accounts task-schedule $LOCAL_ACCOUNT_NAME \
- --task-type="fetch" \
- --task-name='fetch-daily' \
- --task-cronspec='0 0 23' \
- --task-param-level=statement \
- --task-param-range-type=latest
-
-The cronspec has the following format, which is slightly non-standard due to
-the ``SECONDS`` field
-
-.. code-block:: none
-
- SECONDS MINUTES HOURS DAY-OF-MONTH[optional] MONTH[optional] DAY-OF-WEEK[optional]
-
-
-Creating a Taler facade
-^^^^^^^^^^^^^^^^^^^^^^^
-
-Facades are additional abstraction layers that can serve
-specific purposes. For example, one application might need
-a filtered version of the transaction history, or it might
-want to refuse payments that do not conform to certain rules.
-
-At this moment, only the *Taler facade type* is implemented
-in the Nexus, and the command below instantiates one under a
-existing bank account / connection pair. You can freely
-assign an identifier for the ``$FACADE_NAME`` below:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli facades new-taler-wire-gateway-facade \
- --currency EUR \
- --facade-name $FACADE_NAME \
- $CONNECTION_NAME \
- $LOCAL_ACCOUNT_NAME
-
-At this point, the additional :doc:`taler-wire-gateway API <core/api-bank-wire>`
-becomes offered by the Nexus. The purpose is to let a Taler exchange rely on
-Nexus to manage its bank account.
-
-The base URL of the facade that can be used by the Taler exchange
-as the Taler Wire Gateway base URL can be seen by listing the facades:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli facades list
-
-Managing Permissions and Users
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This guide has so far assumed that a superuser is accessing the LibEuFin Nexus.
-However, it is advisable that the Nexus is accessed with users that only have a
-minimal set of permissions.
-
-The Nexus currently only has support for giving non-superusers access to Taler
-wire gateway facades.
-
-To create a new user, use the ``users`` subcommand of the CLI:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli users list
- # [ ... shows available users ... ]
-
- [root@exchange-online]# libeufin-cli users create $USERNAME
- # [ ... will prompt for password ... ]
-
-Permissions are managed with the ``permissions`` subcommand.
-The following commands grant permissions to view the transaction history
-and create payment initiations with a Taler wire gateway facade:
-
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli permissions grant \
- user $USERNAME \
- facade $FACADENAME \
- facade.talerwiregateway.history
-
- [root@exchange-online]# libeufin-cli permissions grant \
- user $USERNAME \
- facade $FACADENAME \
- facade.talerwiregateway.transfer
-
-..
- FIXME: The two commands above output an empty JSON object
- when successful. Possibly, we should suppress that (just like
- the other commands do).
-
-The list of all granted permissions can be reviewed:
-
-.. code-block:: console
-
- [root@exchange-online]# libeufin-cli permissions list
-
-
-.. _Bank-account:
+.. _exchange-bank-account-configuration:
Exchange Bank Account Configuration
-----------------------------------
An exchange must be configured with the right settings to access its bank
-account via a Taler Wire Gateway. An exchange can be configured to use
-multiple bank accounts by using multiple Wire Gateways. Typically only one
-Wire Gateway is used.
+account via a :ref:`Taler wire gateway <taler-wire-gateway-http-api>`. An
+exchange can be configured to use multiple bank accounts by using multiple
+wire gateways. Typically only one wire gateway is used.
To configure a bank account in Taler, we need to furnish two pieces of
information:
@@ -1195,8 +864,8 @@ information:
an IBAN or
``payto://x-taler-bank/localhost:8080/2`` for the 2nd bank account a
the Taler bank demonstrator running at ``localhost`` on port 8080.
- The first part of the URI following ``payto://`` (“iban” or
- “x-taler-bank”) is called the wire method.
+ The first part of the URI following ``payto://`` (``iban`` or
+ ``x-taler-bank``) is called the wire method.
- The ``taler-exchange-wirewatch`` and ``taler-exchange-transfer``
tools needs to be provided resources for authentication
@@ -1205,20 +874,22 @@ information:
for HTTP basic authentication.
-A Taler Wire Gateway is configured in a configuration section that follows the
-pattern ``exchange-account-$id``, where ``$id`` is an internal identifier for
-the bank account accessed by the exchange. The basic information for an
+Each Taler wire gateway is configured in a configuration section that follows
+the pattern ``exchange-account-$id``, where ``$id`` is an internal identifier
+for the bank account accessed by the exchange. The basic information for an
account should be put in ``/etc/taler/conf.d/exchange-business.conf``. The
secret credentials to access the Taler Wire Gateway API should be put into a
corresponding ``exchange-accountcredentials-$id`` section in
``/etc/taler/secrets/exchange-accountcredentials.conf``. The latter file
-should already be only readable for the ``taler-exchange-wire`` user. Other
-exchange processes should not have access to this information.
+should be only readable for the ``taler-exchange-wire`` user. Only the
+``taler-exchange-wirewatch`` and ``taler-exchange-transfer`` services should
+run as the ``taler-exchange-wire`` user. Other exchange processes do not need
+to have access to the account credentials.
You can configure multiple accounts for an exchange by creating sections
-starting with “exchange-account-” for the section name. You can ENABLE for
-each account whether it should be used, and for what (incoming or outgoing
-wire transfers):
+starting with ``exchange-account-`` for the section name. You must specify
+``ENABLE_``-settings for each account whether it should be used, and for what
+(incoming or outgoing wire transfers):
.. code-block:: ini
:caption: /etc/taler/conf.d/exchange-business.conf
@@ -1253,15 +924,15 @@ wire transfers):
# LibEuFin expects basic auth.
WIRE_GATEWAY_AUTH_METHOD = basic
- # Username and password set in LibEuFin.
+ # Username and password to access the Taler wire gateway.
USERNAME = ...
PASSWORD = ...
- # Base URL of the wire gateway set up with LibEuFin.
+ # Base URL of the Taler wire gateway.
WIRE_GATEWAY_URL = ...
-Such a Wire Gateway configuration can be tested with the following commands:
+Such a wire gateway configuration can be tested with the following commands:
.. code-block:: shell-session
@@ -1270,7 +941,8 @@ Such a Wire Gateway configuration can be tested with the following commands:
[root@exchange-online]# taler-exchange-wire-gateway-client \
--section exchange-accountcredentials-1 --credit-history
-
+On success, you will see some of your account's transaction history (or an
+empty history), while on failure you should see an error message.
.. _LegalSetup:
@@ -1301,12 +973,12 @@ Taler permits an exchange to require KYC data under the following circumstances:
* Wallet receives (via refunds) money resulting in a balance over a threshold
* Wallet receives money via P2P payments over a threshold
* Merchant receives money over a threshold
- * Reserve is "opened" for invoicing or rewards (**planned feature**)
+ * Reserve is "opened" for invoicing (**planned feature**)
Any of the above requests can trigger the KYC process,
which can be illustrated as follows:
-.. image:: kyc-process.png
+.. image:: images/kyc-process.png
At the end of the KYC process, the wallet re-tries the
original request, and assuming KYC was successful, the
@@ -1716,7 +1388,7 @@ started using a simple command:
At this point, the exchange service is not yet fully operational.
-To check whether the exchange is running correctly under the advertized
+To check whether the exchange is running correctly under the advertised
base URL, run:
.. code-block:: shell-session
@@ -1811,6 +1483,8 @@ periodically, as it signs the various online signing keys of the exchange
which periodically expire.
+.. _exchange-account-signing:
+
Account signing
---------------
@@ -1819,7 +1493,7 @@ The ``enable-account`` step is important to must be used to sign the
correct address to wire funds to. Note that for each bank account, additional
options **must** be set in the configuration file to tell the exchange how to
access the bank account. The offline tool *only* configures the externally
-visible portions of the setup. The chapter on `Bank account <_Bank-account>`_ configuration has further details.
+visible portions of the setup. The chapter on `bank account configuration <_exchange-bank-account-configuration>`_ has further details.
taler-exchange-offline accepts additional options to configure the use of the
account. For example, additional options can be used to add currency
@@ -2005,7 +1679,7 @@ makes the decision given the KYC attributes:
The given program will be given the KYC attributes in JSON format on standard
input, and must return 0 to continue without AML and non-zero to flag the
-account for manual review. To disable this triger, simply leave the option to
+account for manual review. To disable this trigger, simply leave the option to
its default value of '[/usr/bin/]true'. To flag all new users for manual
review, simply set the program to '[/usr/bin/]false'.
@@ -2013,7 +1687,7 @@ AML Forms
---------
AML forms are defined by the DD 54 dynamic forms.
-The shipped implementation with of the exchange is installed in
+The shipped implementation with of the exchange is installed in
.. code-block:: shell-session
@@ -2026,11 +1700,11 @@ every entry in the list the next properties are expected to be present:
``label``: used in the UI as the name of the form
``id``: identification name, this will be saved in the exchange database
-along with the values to correctly render the form again.
+along with the values to correctly render the form again.
It should simple, short and without any character outside numbers,
letters and underscore.
-``version``: when editing a form, instead of just replacing fields
+``version``: when editing a form, instead of just replacing fields
it will be better to create a new form with the same id and new version.
That way old forms in the database will used old definition of the form.
It should be a number.
@@ -2040,12 +1714,12 @@ See DD 54 dynamic forms.
.. attention::
- do not remove a form the list if it has been used. Otherwise you
+ do not remove a form the list if it has been used. Otherwise you
won't be able to see the information save in the exchange database.
To add a new one you can simply copy and paste one element, and edit it.
-It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
+It is much easier to download ``@gnu-taler/aml-backoffice-ui`` source
from ``https://git.taler.net/wallet-core.git/``, compile and copy the file
from the ``dist/prod``.
@@ -2268,6 +1942,323 @@ grant the permissions to the other exchange processes again.
+.. _ExchangeTemplateCustomization:
+
+Template Customization
+======================
+
+The Exchange comes with various HTML templates that are shown to
+guide users through the KYC process. The Exchange uses `Mustach
+<https://gitlab.com/jbol/mustach>`__ as the templating engine. This section
+describes the various templates. In general, the templates must be installed
+to the ``share/taler/exchange/templates/`` directory. The file names must be of
+the form ``$NAME.$LANG.must`` where ``$NAME`` is the name of the template and
+``$LANG`` is the 2-letter language code of the template. English templates
+must exist and will be used as a fallback. If the browser (user-agent) has
+provided language preferences in the HTTP header and the respective language
+exists, the correct language will be automatically served.
+
+The following subsections give details about each of the templates. Most
+subsection titles are the ``$NAME`` of the respective template.
+
+
+Generic Errors Templates
+------------------------
+
+A number of templates are used for generic errors. These are:
+
+ * kyc-proof-already-done (KYC process already completed)
+ * kyc-bad-request (400 Bad Request)
+ * kyc-proof-endpoint-unknown (404 Not Found for KYC logic)
+ * kyc-proof-internal-error (500 Internal Server Error)
+ * kyc-proof-target-unknown (404 Not Found for KYC operation)
+
+All of these templates are instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * message: String; optional, extended human-readable text provided to elaborate
+ on the error, should be shown to provide additional context
+
+
+kycaid-invalid-request
+----------------------
+
+The KYCaid plugin does not support requests to the
+``/kyc-proof/`` endpoint (HTTP 400 bad request).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * error: String; error code from the server
+
+ * error_details: String; optional error description from the server
+
+ * error_uri: optional URI with further details about the error from the server
+
+
+
+oauth2-authentication-failure
+-----------------------------
+
+The OAuth2 server said that the request was not
+properly authenticated (HTTP 403 Forbidden).
+
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+
+oauth2-authorization-failure
+----------------------------
+
+The OAuth2 server refused to return the KYC data
+because the authorization code provided was
+invalid (HTTP 403 Forbidden).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * error: String; error code from the server
+
+ * error_message: String; error message from the server
+
+
+oauth2-authorization-failure-malformed
+--------------------------------------
+
+The server refused the authorization, but then provided
+a malformed response (HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
+
+ * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
+
+
+oauth2-bad-request
+------------------
+
+The client made an invalid request (HTTP 400 Bad Request).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * message: String; additional error message elaborating on what was bad about the request
+
+
+oauth2-conversion-failure
+-------------------------
+
+Converting the KYC data into the exchange's internal
+format failed (HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
+
+ * converter: String; name of the conversion command that failed which was used by the Exchange
+
+ * attributes: Object; attributes returned by the conversion command, often NULL (after all, conversion failed)
+
+ * message: error message elaborating on the conversion failure
+
+
+oauth2-provider-failure
+-----------------------
+
+We did not get an acceptable response from the OAuth2
+provider (HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * message: String; could be NULL; text elaborating on the details of the failure
+
+
+persona-exchange-unauthorized
+-----------------------------
+
+The Persona server refused our request (HTTP 403 Forbidden from Persona, returned as a HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-load-failure
+--------------------
+
+The Persona server refused our request (HTTP 429 Too Many Requests from Persona, returned as a HTTP 503 Service Unavailable).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-exchange-unpaid
+-----------------------
+
+The Persona server refused our request (HTTP 402 Payment REquired from Persona, returned as a HTTP 503 Service Unavailable).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+
+persona-logic-failure
+---------------------
+
+The Persona server refused our request (HTTP 400, 403, 409, 422 from Persona, returned as a HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-invalid-response
+------------------------
+
+The Persona server refused our request in an
+unexpected way; returned as a HTTP 502 Bad Gateway.
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * debug: Bool; true if we are running in debug mode and are allowed to return HTML with potentially sensitive information
+
+ * server_response: Object; could be NULL; this includes the (malformed) OAuth2 server response, it should be shown to the use if "debug" is true
+
+
+persona-network-timeout
+-----------------------
+
+The Persona server refused our request (HTTP 408 from Persona, returned as a HTTP 504 Gateway Timeout).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
+persona-kyc-failed
+------------------
+
+The Persona server indicated a problem with the KYC process, saying it was not completed.
+
+This template is instantiated using the following information:
+
+ * persona_inquiry_id: String; internal ID of the inquiry within Persona, useful for further diagnostics by staff
+
+ * data: Object; could be NULL; this includes the server response, it contains extensive diagnostics, see Persona documentation on their ``/api/v1/inquiries/$ID``.
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+persona-provider-failure
+------------------------
+
+The Persona server refused our request (HTTP 500 from Persona, returned as a HTTP 502 Bad Gateway).
+
+This template is instantiated using the following information:
+
+ * ec: Integer; numeric Taler error code, should be shown to indicate the
+ error compactly for reporting to developers
+
+ * hint: String; human-readable Taler error code, should be shown for the
+ user to understand the error
+
+ * data: Object; data returned from Persona service, optional
+
+ * persona_http_status: Integer; HTTP status code returned by Persona
+
+
.. _ExchangeBenchmarking:
Benchmarking
diff --git a/taler-merchant-api-tutorial.rst b/taler-merchant-api-tutorial.rst
index 739cf07f..15e21e21 100644
--- a/taler-merchant-api-tutorial.rst
+++ b/taler-merchant-api-tutorial.rst
@@ -19,8 +19,12 @@
.. _merchant-api-tutorial:
-GNU Taler Merchant API Tutorial
-###############################
+Merchant API Tutorial
+#####################
+
+.. contents:: Table of Contents
+ :depth: 2
+ :local:
Introduction
============
@@ -63,10 +67,6 @@ If you want to look at some simple, running examples, check out these:
that accepts donations for software projects and gives donation
receipts.
-- The
- `survey <https://git.taler.net/taler-merchant-demos.git/tree/talermerchantdemos/survey>`__
- that gives users who answer a question a small reward.
-
- The `WooCommerce plugin <https://git.taler.net/gnu-taler-payment-for-woocommerce.git/>`__
which is a comprehensive integration into a Web shop including the refund business
process.
@@ -413,69 +413,6 @@ considered to identify a resource you can pay for and thus do not have to be
unique.
-.. _Giving-Customers-Rewards:
-.. index:: rewards
-
-Giving Customers Rewards
-========================
-
-GNU Taler allows Web sites to grant digital cash directly to a visitor. The
-idea is that some sites may want incentivize actions such as filling out a
-survey or trying a new feature. It is important to note that receiving rewards is
-not enforceable for the visitor, as there is no contract. It is simply a
-voluntary gesture of appreciation of the site to its visitor. However, once a
-reward has been granted, the visitor obtains full control over the funds provided
-by the site.
-
-The merchant backend of the site must be properly configured for rewards, and
-sufficient funds must be made available for rewards. See the :ref:`Taler User
-Guide <Rewarding-visitors>` for details.
-
-To check if rewards are configured properly and if there are sufficient
-funds available for granting rewards, query the ``/private/reserves`` endpoint:
-
-.. code-block:: python
-
- >>> import requests
- >>> requests.get("https://backend.demo.taler.net/private/reserves",
- ... headers={"Authorization": "Bearer secret-token:sandbox"})
- <Response [200]>
-
-Check that a reserve exists where the ``merchant_initial_amount`` is below the
-``committed_amount`` and that the reserve is ``active``.
-
-.. _authorize-reward:
-
-To authorize a reward, ``POST`` to ``/private/rewards``. The following fields
-are recognized in the JSON request object:
-
-- ``amount``: Amount that should be given to the visitor as a reward.
-
-- ``justification``: Description of why the reward was granted. Human-readable
- text not exposed to the customer, but used by the Back Office.
-
-- ``next_url``: The URL that the user’s browser should be redirected to by
- the wallet, once the reward has been processed.
-
-The response from the backend contains a ``taler_reward_url``. The
-customer’s browser must be redirected to this URL for the wallet to pick
-up the reward.
-
-.. _pick-up-reward:
-
-This code snipped illustrates giving a reward:
-
-.. code-block:: python
-
- >>> import requests
- >>> reward_req = dict(amount="KUDOS:0.5",
- ... justification="User filled out survey",
- ... next_url="https://merchant.com/thanks.html")
- >>> requests.post("https://backend.demo.taler.net/private/rewards", json=reward_req,
- ... headers={"Authorization": "Bearer secret-token:sandbox"})
- <Response [200]>
-
-
.. _Advanced-topics:
Advanced topics
diff --git a/taler-merchant-manual.rst b/taler-merchant-manual.rst
index 4959dd48..48605a55 100644
--- a/taler-merchant-manual.rst
+++ b/taler-merchant-manual.rst
@@ -18,8 +18,13 @@
.. _taler-merchant-backend-operator-manual:
-GNU Taler Merchant Backend Operator Manual
-##########################################
+Merchant Backend Operator Manual
+################################
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
Introduction
============
@@ -42,17 +47,6 @@ We expect some moderate familiarity with the compilation and
installation of Free Software packages. An understanding of cryptography
is not required.
-This first chapter of the manual will give a brief overview of the
-overall Taler architecture, describing the environment in which the
-Taler backend operates. The second chapter then explains how to install
-the software, including key dependencies. The third chapter will explain
-how to configure the backend, including in particular the configuration
-of the bank account details of the merchant.
-
-The last chapter gives some additional information about advanced topics
-which will be useful for system administrators but are not necessary for
-operating a basic backend.
-
.. _Architecture-overview:
Architecture overview
@@ -152,11 +146,12 @@ main Taler configuration (especially the accepted *currency* and *exchanges*).
acceptable to consider instances to be the "users" or "accounts" of a
merchant backend and the bearer token is equivalent to a passphrase.
+.. _instance-bank-account:
Instance Bank Accounts
----------------------
-.. index:: instance-bank-account
+.. index:: Bank account
To receive payments, an instance must have configured one or more bank
*accounts*. When configuring the bank account of an instance, one should
@@ -260,6 +255,61 @@ After the *legal expiration* (by default: a decade), contract information is
deleted when running the garbage collector using ``taler-merchant-dbinit``.
+.. _template:
+
+Templates
+---------
+
+.. index:: Template
+
+Usually, a merchant must use an authenticated endpoint to create an order and
+then share the link to the order with a wallet. Templates are a mechanism that
+allows wallets to create their own orders directly, using a public endpoint.
+The template fixes some properties of the contracts created from it, while
+other details may be left for the customer to provide. Templates are useful
+in cases where the point-of-sale of a merchant is offline (and thus cannot
+setup an order), or even in cases where a simple static QR code is desired to
+accept payments or donations.
+
+When generating a template, the "summary" text of the contract and the
+"amount" to be paid by the customer can be fixed or left for the customer to
+specify. If the customer is expected to provide either or both of these
+values, the template link (or QR code) can specify a default value. For
+example, a cafeteria with a fixed price lunch may use a "lunch" template with
+both values fixed to the lunch price and the "lunch" product, a bakery might
+fix the summary to "baked goods" but allow the customer to enter the amount
+based on the total price of the items being bought, and a charity may allow
+donating an arbitrary amount and summary message while also suggesting default
+values.
+
+If an offline merchant wants to confirm that a customer did actually pay the
+agreed amount using an order derived from a template, they can associate an
+OTP device with the template.
+
+
+.. _otp-device:
+
+OTP Devices
+-----------
+
+.. index:: OTP
+.. index:: TOTP
+
+A One-Time-Password (OTP) generator is a device or application that generates
+a 4 to 8 digit code typically used for authentication. The widely used TOTP
+standard is described in `RFC 6238 <https://www.rfc-editor.org/rfc/rfc6238>`_.
+For GNU Taler merchant backends, OTP devices are used as a way to assure a
+merchant without network connectivity that a customer made a digital
+payment. The idea is described in depth in our `SUERF Policy Brief
+<https://www.suerf.org/suer-policy-brief/69851/practical-offline-payments-using-one-time-passcodes>`_.
+To use this method, a merchant must configure the OTP device's shared secret
+in the merchant backend, and then associate the OTP device with a
+:ref:`template`. Once the customer has paid, they are given a list of OTP
+codes which must be shown to the merchant who can check that at least one of
+the codes matches their OTP device, proving that the customer made the
+payment.
+
+
Transfers
---------
@@ -273,55 +323,51 @@ the backend does not have access to the incoming wire transfers of the
merchant's bank account. In this case, merchants should manually provide the
backend with wire *transfer* data that specifies the *wire transfer subject*
and the amount that was received. Given this information, the backend can
-detect and report any irregularities that might arise.
+detect and report any irregularities that might arise.
-Rewards
--------
-.. index:: reward
-.. index:: pick up
+Webhooks
+--------
-Taler does not only allow a Website to be paid, but also to make voluntary,
-non-contractual payments to visitors, called *rewards*. Such rewards could be
-granted as a reward for filling in surveys or watching advertizements. For
-rewards, there is no contract, rewards are always voluntary actions by the Web
-site that do not arise from a contractual obligation. Before a Web site
-can create rewards, it must establish a reserve. Once a reserve has been
-established, the merchant can *grant* rewards, allowing wallets to *pick up*
-the reward.
+.. index:: webhook
-.. note::
+A webhook is a pre-defined HTTP request that the GNU Taler merchant backend
+will make upon certain events, such as an order being paid or refunded. When
+the configured event happens, the merchant backend will make an HTTP request
+to the endpoint configured in the webhook configuration, possibly sending
+selected data about the event to the respective Web service. Webhooks can be
+used to trigger additional business logic outside of the GNU Taler merchant
+backend.
- Rewards are an optional feature, and exchanges may disable rewards (usually
- if they see compliance issues). In this case, the reward feature will
- not be available.
+Installation
+============
-Reserves
---------
+This chapter describes how to install the GNU Taler merchant backend.
-.. index:: reserve
-.. index:: close
+.. _Generic-instructions:
-A *reserve* is a pool of electronic cash at an exchange under the control of
-a private key. Merchants withdraw coins from a reserve when granting
-rewards. A reserve is established by first generating the required key material
-in the merchant backend, and then wiring the desired amount of funds to the
-exchange.
+Installing the GNU Taler binary packages on Debian
+--------------------------------------------------
-An exchange will automatically *close* a reserve after a fixed period of time
-(typically about a month), wiring any remaining funds back to the merchant.
-While exchange APIs exists to (1) explicitly *open* a reserve to prevent it
-from being automatically closed and to (2) explicitly *close* a reserve at any
-time, the current merchant backend does not make use of these APIs.
+.. include:: frags/installing-debian.rst
+.. include:: frags/apt-install-taler-merchant.rst
-Installation
-============
-This chapter describes how to install the GNU Taler merchant backend.
+Installing the GNU Taler binary packages on Trisquel
+----------------------------------------------------
+
+.. include:: frags/installing-trisquel.rst
+
+
+Installing the GNU Taler binary packages on Ubuntu
+--------------------------------------------------
+
+.. include:: frags/installing-ubuntu.rst
+
+.. include:: frags/apt-install-taler-merchant.rst
-.. _Generic-instructions:
Installing from source
----------------------
@@ -360,30 +406,9 @@ libraries!
.. include:: frags/install-before-check.rst
-Installing the GNU Taler binary packages on Debian
---------------------------------------------------
-
-.. include:: frags/installing-debian.rst
-
-.. include:: frags/apt-install-taler-merchant.rst
-
-Installing the GNU Taler binary packages on Trisquel
-----------------------------------------------------
-
-.. include:: frags/installing-trisquel.rst
-
-
-Installing the GNU Taler binary packages on Ubuntu
---------------------------------------------------
-
-.. include:: frags/installing-ubuntu.rst
-
-.. include:: frags/apt-install-taler-merchant.rst
-
-
-How to configure the merchant’s backend
-=======================================
+How to configure the merchant backend
+=====================================
.. index:: taler.conf
@@ -536,7 +561,7 @@ For the ``postgres`` backend, you need to specify:
[merchantdb-postgres]
CONFIG = "postgres:///taler-merchant"
-This option specifies a PostgreSQL access path, typicallly using the format
+This option specifies a PostgreSQL access path, typically using the format
``postgres:///$DBNAME``, where ``$DBNAME`` is the name of the PostgreSQL
database you want to use (here, ``taler-merchant`` on the local machine).
Suppose ``$USER`` is the name of the user who will run the backend process
@@ -648,7 +673,7 @@ The following is an example for a complete backend configuration:
DATABASE = postgres
[merchantdb-postgres]
- CONFIG = postgres:///donations
+ CONFIG = postgres:///taler-merchant
[merchant-exchange-kudos]
EXCHANGE_BASE_URL = https://exchange.demo.taler.net/
@@ -674,20 +699,17 @@ Launching the backend
.. index:: taler-merchant-httpd
Assuming you have configured everything correctly, you can launch the
-merchant backend as ``$USER`` using
+merchant backend as ``$USER`` using (to provide a trivial example):
.. code-block:: console
$ taler-merchant-httpd &
$ taler-merchant-webhook &
$ taler-merchant-wirewatch &
+ $ taler-merchant-depositcheck &
+ $ taler-merchant-exchange &
-You only need to run ``taler-merchant-webhook`` if one of the instances is
-configured to trigger web hooks. Similarly, ``taler-merchant-wirewatch`` is
-only required if instances have accounts configured with automatic import of
-wire transfers via a bank wire gateway.
-
-To ensure these processes runs always in the background and also after
+To ensure these processes run always in the background and also after
rebooting, you should use systemd, cron or some other init system of your
operating system to launch the process. You should also periodically re-start
these services to prevent them from exhausing the memory utilization of the
@@ -698,8 +720,8 @@ how to start and stop daemons.
When using the Debian/Ubuntu packages, the systemd configuration
will already exist. You only need to enable and start the service
- using ``systemctl enable taler-merchant-httpd`` and
- ``systemctl start taler-merchant-httpd``. Additionally, you should
+ using ``systemctl enable taler-merchant.target`` and
+ ``systemctl start taler-merchant.target``. Additionally, you should
review the ``/etc/apache2/sites-available/taler-merchant.conf``
or ``/etc/nginx/sites-available/taler-merchant`` (these files
contain additional instructions to follow), symlink it to
@@ -707,7 +729,6 @@ how to start and stop daemons.
should be able to visit the merchant backend at the respective
HTTP(S) endpoint.
-
If everything worked as expected, the command
.. code-block:: console
@@ -719,7 +740,7 @@ should return some basic configuration status data about the service.
Please note that your backend might then be globally reachable without
any access control. You can either:
- * Use the ``--auth=$TOKEN`` command-line option to set an access token to be provided in an ``Authorize: Bearer $TOKEN`` HTTP header. Note that this can be used at anytime to override access control, but remains only in effect until a first instance is created or an existing instance authentication setting is modified.
+ * Use the ``--auth=$TOKEN`` command-line option to **taler-merchant-httpd** to set an access token to be provided in an ``Authorize: Bearer $TOKEN`` HTTP header. Note that this can be used at anytime to override access control, but remains only in effect until a first instance is created or an existing instance authentication setting is modified.
* Set the ``TALER_MERCHANT_TOKEN`` environment variable to ``$TOKEN`` for the same effect. This method has the advantage of ``$TOKEN`` not being visible as a command-line interface to other local users on the same machine.
* Set up an instance with an authentication token before some unauthorized person has a chance to access the backend. As the backend is useless without any instance and the chances of remote attackers during the initial configuration is low, this is probably sufficient for most use-cases. Still, keep the first two scenarios in mind in case you ever forget your access token!
@@ -734,15 +755,14 @@ and use TLS for improved network privacy, see :ref:`Secure setup <Secure-setup>`
Instance setup
==============
-First of all, we recommend the use of the single-page administration
-application (SPA) that is served by default at the base URL of the merchant
-backend. You can use it to perform all steps described in this section (and
-more!), using a simple Web interface instead of the ``wget`` commands given
-below.
+We recommend the use of the single-page administration application (SPA) that
+is served by default at the base URL of the merchant backend. You can use it
+to perform all steps described in this section (and more!), using a simple Web
+interface. Alternatively, you can also use the ``wget`` commands given below.
-Regardless of which tool you use, the first step for using the backend
+Regardless of which approach you use, the first step for using the backend
involves the creation of a ``default`` instance. The ``default`` instance can
-also create / delete / configure other instances, similar to the ``root``
+also create, configure or delete other instances, similar to the ``root``
account on UNIX. When no instance exists and ``taler-merchant-httpd`` was
started without the ``--auth`` option, then the backend is reachable without
any access control (unless you configured some in the reverse proxy).
@@ -761,8 +781,33 @@ times, once for each instance.
:ref:`reverse proxy <reverse-proxy-configuration>`.
-Setup without the Web interface
--------------------------------
+Instance setup with the SPA
+---------------------------
+
+In order to setup an instance, you need the merchant backend to already be
+running, and you must either have the credentials for the "default" instance,
+or no instance must be configured at all yet.
+
+To start, point your browser to ``$PROTO://backend.$DOMAIN_NAME/``, replacing
+"$PROTO" with "https" or (rarely) "http" and "$DOMAIN_NAME" with your
+organizations DNS domain or subdomain.
+
+.. note::
+
+ The label "backend" here is also just a suggestion, your administrator
+ can in principle choose any name.
+
+You should be welcomed by the following merchant backoffice page:
+
+.. image:: screenshots/merchant_first_login.png
+
+After supplying the required fields, primarily the name of your organization
+and the desired access token, click ``confirm``. You can change the instance
+settings later via the ``Settings`` entry in the menu on the left.
+
+
+Instance setup without the Web interface
+----------------------------------------
Instances can be created by POSTing a request to ``/management/instances``
without using the Web interface. This could be useful if you want to create
@@ -774,7 +819,7 @@ interface create a file ``instance.json`` with an
{
"id" : "default",
- "name": "example.com",
+ "name": "Example Inc.",
"address": { "country" : "zz" },
"auth": { "method" : "external"} ,
"jurisdiction": { "country" : "zz" },
@@ -805,9 +850,10 @@ Endpoints to modify (reconfigure), permanently disable (while keeping the data)
or purge (deleting all associated data) instances exist as well and are documented
in the :ref:`Merchant Backend API documentation <merchant-api>`.
+.. _instance-account-setup:
-Accounts
---------
+Instance account setup
+======================
Before you can use an instance productively, you need to configure one or more
bank accounts. These bank accounts will be provided to the Taler exchange
@@ -815,16 +861,47 @@ operator to tell it where to wire the income from your sales. Every bank
account has an associated *wire method* which determines how an exchange can
transfer the funds. The most commonly supported wire method is *iban*, which
implies that bank accounts are identified by IBAN numbers and wire transfers
-are to be executed between IBAN accounts.
+are to be executed between IBAN accounts. For regional currency setups, the
+wire method could also be *x-taler-bank*.
+
+.. note::
+
+ When using a regional currency, you need to first create a bank account at
+ the regional bank. You may need to contact the respective administrator who
+ can set one up. After being able to login to the new bank account, you can
+ see your bank account number by clicking on the ``Welcome, $USERNAME``
+ message in the profile page. Next to the bank account number, you can find
+ a convenient button to copy the number to the clipboard.
Not every exchange will support every *wire method*, and if you do not add a
bank account with a wire method that is supported by a particular exchange,
then you will not be able to receive payments via that exchange even if you
configured the merchant backend to trust that exchange.
-The simplest way to configure an account is to use the Web interface which
-has specific forms for different wire methods. Specifying the revenue gateway
-with username and password is optional and discussed below.
+The simplest way to configure an account is to use the Web interface which has
+specific forms for different wire methods. First, select ``Bank account`` at
+the left of the page. The following page should be shown:
+
+.. image:: screenshots/no_default_account_yet.png
+
+Click on the blue "+" sign on the top right of the page to add a new
+bank account. The following page should appear:
+
+.. image:: screenshots/enter_instance_details.png
+
+First, you should select the wire method, after which the dialog will show you
+additional fields specific to the wire method. For example, if youchoose
+``iban`` as the account type, the following page should appear:
+
+.. image:: screenshots/instance_iban_config.png
+
+Specifying the revenue gateway with username and password is optional and
+discussed in section :ref:`automatic-settlement-data-import` below.
+
+After providing the details and confirming, the shop is ready to generate orders
+and accept payments.
+
+
Detecting Settlement: Manually Adding Transfers
-----------------------------------------------
@@ -843,21 +920,55 @@ information, the merchant backend will inquire with the exchange which
individual payments were aggregated, check that the total amount is correct,
and will then flag the respective contracts as wired.
+You can manually enter wire transfers under ``Transfers``. However, this is
+tedious, and so if your banking setup supports it, we highly recommend
+using the automatic settlement data import.
+
+.. _automatic-settlement-data-import:
+
Automatic Settlement Data Import
--------------------------------
-To automatically import settlement data, you can provide the merchant backend
-with the address and access credentials of a Taler revenue API for each bank
-account of an instance. The revenue API endpoint will allow the merchant
-backend to observe all incoming wire transfers into your bank account and
-automatically import them into the list of wire transfers.
+To automatically import settlement data, you need to provide the merchant
+backend with the address and access credentials of a
+:ref:`taler-bank-merchant-http-api` for each bank account of an instance. The
+revenue API endpoint will allow the merchant backend to obtain a list of all
+incoming wire transfers into your bank account and automatically import them
+into the list of confirmed wire transfers.
Note that setting up a revenue API endpoint will usually require you to first
-ask your bank for EBICS access and to setup libeufin to provide the revenue
-API endpoint. The taler-bank used by regional currency setups also provides
-a revenue API endpoint.
+ask your bank for EBICS access and to set up :ref:`libeufin-nexus` to provide
+the revenue API endpoint. The :ref:`libeufin-bank` used by regional currency
+setups also provides a revenue API endpoint at
+``$BANK_URL/accounts/$ACCOUNT_NAME/taler-revenue/``. Thus, when using a
+regional currency setup, simply use the ``$BANK_URL`` of your bank and specify
+your bank login name and password in the :ref:`instance-account-setup` dialog.
+Manually creating an order using the SPA
+========================================
+
+Click on ``Orders`` at the top left corner of the merchant backoffice page; the
+following page should appear
+
+.. image:: screenshots/create_orders.png
+
+After having filled the required fields, the interface should show the
+following page with the related links to check the status of the order and let
+wallets pay for it.
+
+.. image:: screenshots/payment_links.png
+
+In order to test the setup, it should be now possible to use the command line wallet
+to withdraw Taler coins and spend them to pay for the order we just created.
+
+In practice, you will rarely if ever setup orders manually like this. Instead,
+a `GNU Taler e-commerce front-end
+<https://taler.net/en/docs.html#extensions>`_ or the
+:ref:`taler-merchant-pos-app` will do this on-demand. Here, you will only need
+to provide the respective front-ends with the URL of your instance
+(e.g. ``https://backend.$DOMAIN/instances/$NAME``) and your access token.
+
.. _Secure-setup:
@@ -867,11 +978,12 @@ Secure setup
.. index:: security
.. index:: TLS
-The Taler backend does not include even the most basic forms of access control
-or transport layer security. Thus, production setups **must** deploy the
-Taler backend behind an HTTP(S) server that acts as a *reverse proxy*,
-performs TLS termination and authentication and then forwards requests to the
-backend.
+The Taler backend is deliberately simple in terms of support for access
+control or transport layer security (TLS). Thus, production setups **must**
+deploy the Taler backend behind an HTTP(S) server that acts as a *reverse
+proxy*, performs TLS termination and authentication and then forwards requests
+to the backend.
+
Using UNIX domain sockets
-------------------------
@@ -996,15 +1108,83 @@ Legal conditions for using the service
.. include:: frags/legal.rst
+.. _MerchantTemplateCustomization:
-Mustach HTML Templates
+Template Customization
----------------------
-The installation process will install various HTML templates to be served
-to trigger the wallet interaction. You may change those templates to your
-own design. The templating language used is Mustach, and the templates
-are in the ``share/taler/merchant/templates/`` directory.
+The installation process will install various HTML templates to be served to
+trigger the wallet interaction. You may change those templates to your own
+design. The templating language used is `Mustach
+<https://gitlab.com/jbol/mustach>`__, and the templates are in the
+``share/taler/merchant/templates/`` directory.
+
+The file names must be of the form ``$NAME.$LANG.must`` where ``$NAME`` is the
+name of the template and ``$LANG`` is the 2-letter language code of the
+template. English templates must exist and will be used as a fallback. If the
+browser (user-agent) has provided language preferences in the HTTP header and
+the respective language exists, the correct language will be automatically
+served.
+
+The following subsections give details about each of the templates. The
+subsection titles are the ``$NAME`` of the respective template.
+
+request_payment
+^^^^^^^^^^^^^^^
+
+Page shown to request the user to make a payment.
+
+This template is instantiated using the following information:
+
+ * taler_pay_uri: String; the ``taler://pay/`` URI that must be given
+ to the wallet to initiate the payment
+
+ * taler_pay_qrcode_svg: Image; an SVG image of the QR code with the
+ ``taler_pay_uri``.
+
+ * order_summary: String; a text summarizing the order
+
+ * order_status_url: URL of the merchant backend where the order status
+ can be found, useful for long-polling to check if the order has been paid
+
+
+offer_refund
+^^^^^^^^^^^^
+
+Page shown to offer a customer a refund.
+
+This template is instantiated using the following information:
+
+ * taler_refund_uri: String; the ``taler://pay/`` URI that must be given
+ to the wallet to initiate the payment
+
+ * taler_refund_qrcode_svg: Image; an SVG image of the QR code with the
+ ``taler_pay_uri``.
+ * refund_amount: Amount; how much did the merchant refund
+
+ * refund_taken: Amount; how much did the customer already take back in refunds
+
+ * order_summary: String; a text summarizing the order
+
+
+
+show_order_details
+^^^^^^^^^^^^^^^^^^
+
+Page shown to the user when they go back to the payment page but
+no payment is required and no refund is present.
+
+This template is instantiated using the following information:
+
+ * order_summary: String; a text summarizing the order
+
+ * contract_terms: Object; the full contract terms (shoud probably
+ not be shown in full!)
+
+ * refund_amount: Amount; how much did the merchant refund
+
+ * refund_taken: Amount; how much did the customer already take back in refunds
Static files
------------
@@ -1131,6 +1311,7 @@ runtime by the setup logic provided by ``taler-unified-setup.sh``.
See :ref:`Taler Exchange Manual <Benchmark-choose-bank>` for how to use ``taler-unified-setup.sh`` to setup the system and in particular on how to specify the bank to be used.
+
Running taler-merchant-benchmark
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -1167,8 +1348,10 @@ second gives the chance to leave some payments unaggregated, and also to
use merchant instances other than the default (which is, actually, the
one used by default by the tool).
-Note: the ability of driving the aggregation policy is useful for testing
-the back-office facility.
+.. note::
+
+ The ability to drive the aggregation policy is useful for testing
+ the back-office facility.
Any subcommand is also equipped with the canonical ``--help`` option, so
feel free to issue the following command in order to explore all the
@@ -1195,9 +1378,6 @@ option:
-
-
-
Temporarily Abandoned Features
==============================
diff --git a/taler-merchant-pos-terminal.rst b/taler-merchant-pos-terminal.rst
index b5833369..efc487cb 100644
--- a/taler-merchant-pos-terminal.rst
+++ b/taler-merchant-pos-terminal.rst
@@ -15,15 +15,22 @@
@author Torsten Grote
-GNU Taler Merchant POS Manual
-#############################
+.. _taler-merchant-pos-app:
-The GNU Taler merchant POS (point of sale) terminal allows sellers to
+Merchant Point of Sale App
+##########################
+
+The GNU Taler merchant point of sale (POS) App allows sellers to
* process customers' orders by adding or removing products
* calculate the amount owed by the customer
* let the customer make a Taler payment via QR code or NFC
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
+
Android App
===========
@@ -64,38 +71,6 @@ Clicking this opens a menu with these items:
* Settings: Allows you to change the app configuration settings (URL and username/password)
and to forget the password (for locking the app).
-Testing nightly builds
-----------------------
-
-Every change to the app's source code triggers an automatic build
-that gets published in a F-Droid repository.
-If you don't have it already, download the `F-Droid app <https://f-droid.org/>`_
-and then click the following link (on your phone) to add the nightly repository.
-
- `GNU Taler Nightly F-Droid Repository <fdroidrepos://gnu-taler.gitlab.io/fdroid-repo-nightly/fdroid/repo?fingerprint=55F8A24F97FAB7B0960016AF393B7E57E7A0B13C2D2D36BAC50E1205923A7843>`_
-
-.. note::
- Nightly apps can be installed alongside official releases
- and thus are meant **only for testing purposes**.
- Use at your own risk!
-
-While not recommended, APKs can also be
-`downloaded directly <https://gitlab.com/gnu-taler/fdroid-repo-nightly/-/tree/master/fdroid%2Frepo>`__.
-
-Building from source
---------------------
-
-Import in and build with Android Studio or run on the command line:
-
-.. code-block:: console
-
- $ git clone https://git.taler.net/merchant-terminal-android.git
- $ cd merchant-terminal-android
- $ ./gradlew assembleRelease
-
-If you do not have the proprietary Android SDK installed,
-see the :doc:`taler-developer-manual`
-for :ref:`build instructions using free SDK rebuilds <Build-apps-from-source>`.
APIs and Data Formats
=====================
diff --git a/taler-monitoring-infrastructure.rst b/taler-monitoring-infrastructure.rst
new file mode 100644
index 00000000..3b809fb3
--- /dev/null
+++ b/taler-monitoring-infrastructure.rst
@@ -0,0 +1,197 @@
+..
+ This file is part of GNU TALER.
+
+ Copyright (C) 2014-2023 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+ @author Javier Sepulveda
+.. _taler-merchant-monitoring:
+
+GNU Taler monitoring
+####################
+
+.. image:: images/taler-monitoring-infrastructure.png
+
+In order to check the availability of our server infrastructure, we use the Grafana and Uptime KUMA monitoring programs.
+
+On the one hand Grafana let us to see *graphically* the server consumption resources, and even alert us of some specific situations.
+On the other hand with a more basic tool such as Uptime KUMA (which does mostly ping and https checks),
+we get the very first status information, as the very first countermeasure.
+
+Grafana
+=======
+
+- Our grafana instance can be reached at https://grafana.taler.net
+
+User accounts:
+--------------
+
+We have only two main user accounts:
+
+- One "admin" account for server administrators.
+- One general "read-only" account, for the rest of the team.
+
+How to install Grafana
+----------------------
+
+Please refer to the Grafana official website for installation instructions for your specific operating system. For the
+specific case of the GNU/Linux distribution Debian 12 (bookworm), you can use the next set of instructions.
+
+.. code-block:: console
+
+ # apt-get install -y apt-transport-https
+ # apt-get install -y software-properties-common wget
+ # wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
+ # echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee -a /etc/apt/sources.list.d/grafana.list
+ # apt update
+ # apt-get install grafana
+ # systemctl daemon-reload
+ # systemctl enable --now grafana-server
+
+.. note::
+
+ If you want to deploy grafana automatically, and if you have access to the --private git repository "migration-exercise-stable.git",
+ please clone it, and execute from Grafana subfolder the grafana.sh file. This script will install for you Grafana and will leave it up and running on port 3000 of your server.
+
+Grafana Dashboards
+------------------
+
+As we understand creating tailored Grafana dashboards, is very time consuming thing to do, and in the top of that
+you really have to to be very proficient to do that, we use the available and pre-built `Grafana dashboards <https://grafana.com/grafana/dashboards/>`_, which eventually we can also tweak a little, to fit our needs.
+
+Node Exporter
+++++++++++++++
+
+- More information can be found on the `Node Exporter <https://grafana.com/grafana/dashboards/1860-node-exporter-full/>`_ website.
+- Dashboard ID: 1860
+
+.. note::
+
+ If you want to deploy Postgres Exporter automatically and have access to the --private git repository "migration-exercise-stable.git", please clone it,
+ and execute from the subfolder taler.net/grafana/node-exporter.sh, this script will install for you Node Exporter and will leave it running on port 9100.
+ This script also will create, start, and enable on reboot a new service.
+
+Postgres Exporter
++++++++++++++++++
+
+- More information can be found on the `PostgreSQL exporter <https://grafana.com/grafana/dashboards/12485-postgresql-exporter/>`_ website.
+- Dashboard ID: 12485
+
+.. image:: images/grafana-postgres-exporter.png
+
+.. note::
+
+ If you want to deploy Postgres Exporter automatically and have access to the --private git repository "migration-exercise-stable.git", please clone it,
+ and execute from the subfolder taler.net/grafana/postgres-exporter.sh, this script will install for you Grafana and will leave it running on port 9187.
+
+Uptime Kuma from Grafana
+++++++++++++++++++++++++
+
+This is an easy to way to integrate all monitored websites from Uptime Kuma, into Grafana. Thus,
+from the same place (Grafana), you can check also the status of the website and the expiration date of the
+certificates.
+
+- More information can be found on the `Uptime Kuma for Grafana <https://grafana.com/grafana/dashboards/18278-uptime-kuma/>`_ website.
+- Dashboard ID: 18278
+
+.. image:: images/uptime-kuma-from-grafana.png
+
+Grafana Data Sources
+---------------------
+As a data source connector we use Prometheus.
+
+Prometheus
+++++++++++
+More information can be found in the `Grafana and Prometheus <https://grafana.com/docs/grafana/latest/getting-started/get-started-grafana-prometheus/>`_ website.
+
+.. note::
+
+ If you want to deploy Prometheus automatically and have access to the --private git repository "migration-exercise-stable.git", please clone it,
+ and execute from the subfolder taler.net/grafana/prometheus.sh, this script will install for you Grafana and will leave it running on port 9090.
+
+Managing logs
+-------------
+
+In order to manage logs, we use Loki + Promtail (Debian packages), which are very easy to integrate with Grafana and Prometheus.
+
+.. code-block:: console
+
+ # Install
+ # apt-get install loki promtail
+ # Start services
+ # systemctl start loki promtail
+ # Enable services on reboot
+ # systemctl enable loki
+ # systemctl enable promtail
+
+Loki and Promtail services in Grafana
+----------------------------------------------
+
+1) Make sure you have prometheus running on port 9090
+2) Make sure you have loki running on port 3100
+
+.. code-block:: console
+
+ systemctl status prometheus loki
+
+
+.. note::
+
+ We still don't have Loki and Promtail installed in production (taler.net), and neither
+ configured to track certain log files.
+
+Grafana Alerting
+----------------
+
+#. In order to use the Grafana alerting system rules, you need first to configure working SMTP service of your server.
+#. Once you have done the necessary changes on the Grafana configuration file, you have to either restart or reload the "grafana-server" service with the systemctl command as usual.
+#. Then go to the Grafana admin panel Alerting -> Contact points, and within the email address you are using for this purpose, check if SMTP is indeed working by pressing the "test" button.
+#. If that works, you will receive an email in your mailbox with the Grafana logo confirming that the server can satisfactorily send email messages.
+
+
+Uptime Kuma
+===========
+
+- URL: http://139.162.254.179:3001/dashboard
+- Users: One single administration account with full privileges.
+- Installation: With Docker
+
+.. image:: images/kuma.png
+
+.. note::
+
+ 1) In order to guarantee the KUMA is doing its work, it needs to be install 100% externally from the servers you want to monitor. (Server Kuma 1)
+ 2) Also, it is important to monitor the KUMA server itself, so you don't endup without a monitoring system. (Server Kuma 2)
+
+In our case, we do both. We have the two Uptime KUMA servers completely outside our server infrastructure, so one monitors the other, and
+the latter one, monitors our own Taler servers.
+
+Kuma monitor types
+-------------------
+
+Kuma counts with quite a few monitor types, such as https, TCP port or ping. In our case, we use mainly https requests,
+and pings, to make sure as a first check that our servers are responsive.
+
+Another handy feature that Kuma has, is the "Certificate Expiry Notification feature, which we also use, and eventually warn us about a certificate
+expiration dates.
+
+So in brief in our KUMA main server, we use these 3 monitor types (ping,https,certificate expiration) for each website that we monitor.
+
+Exceptionally for additional notifications, and specifically due of the importance of the Taler Operations server,
+we use in addition SMS notifications (clicksend provider). This way in case of KUMA detecting the Taler Operations unavailability,
+a SMS message will be sent to at the very least two persons from the deployment and operations department.
+
+How to edit notifications:
+
+.. image:: images/uptime-kuma-edit.png
+
diff --git a/taler-user-guide.rst b/taler-user-guide.rst
index a88faae3..8e42c0d2 100644
--- a/taler-user-guide.rst
+++ b/taler-user-guide.rst
@@ -16,8 +16,12 @@
@author Christian Grothoff
-GNU Taler User Guide
-####################
+User Guide
+##########
+
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
Introduction
============
@@ -38,8 +42,8 @@ an account at the bank. Some operations also require access to the merchant
backend.
-Withdrawing
-===========
+Withdrawing from bank accounts
+==============================
Withdrawing is the step where money is moved from a bank account into
a GNU Taler wallet. There are two main ways to do this.
@@ -70,7 +74,8 @@ Wallet initiated withdrawal
In this case, you will start the withdraw process from the GNU Taler wallet.
Under "Settings", you will find a list of exchanges. If the list is empty or
does not contain the desired exchange, you may have to first add the exchange
-by providing the respective URL.
+by providing the respective URL. The payment service provider operating the
+exchange service should have such a QR code on their Web site.
Next to the exchange, there is a drop-down menu with an option to "withdraw".
(If you already have money in your wallet, you will also find the same button
@@ -86,16 +91,16 @@ as instructed by the wallet. Once the money has arrived at the exchange, the
wallet will automatically withdraw the funds.
-Depositing
-==========
+Depositing into bank accounts
+=============================
If you have money in your wallet, you can use the "deposit" button to deposit
the funds into a bank account. The wallet will ask you to specify the amount
and the target bank account.
-Sending cash
-============
+Sending digital cash
+====================
Once you have digital cash, you can send it to another GNU Taler
wallet. Simply specify the amount and a human-readable reason for the
@@ -109,19 +114,19 @@ clicking the QR code scan button). Afterwards, review the reason text and
accept the funds to complete the transaction.
-Invoicing
-=========
+Receiving digital cash
+======================
-To receive funds from another user, you can send an invoice to another GNU
+To receive funds from another user, you can send a payment request to another GNU
Taler wallet. Simply specify the amount and a human-readable reason for the
-invoice. The wallet will then show a QR code (and give the option to export
-the invoice as a taler://-URL). Send the image of the QR code to the payer
+payment request. The wallet will then show a QR code (and give the option to export
+the payment request as a taler://-URL). Send the image of the QR code to the payer
wallet (or send the taler://-URL to the target wallet).
The target wallet should scan the QR code (or enter the text of the
taler://-URL into the URL import dialog which is available by holding or
clicking the QR code scan button). Afterwards, review the reason for
-the invoice and decide whether or not to pay the invoice. Selecting
+the payment request and decide whether or not to pay it. Selecting
"pay" will complete the transaction.
Depending on the configuration of the exchange, the receiving wallet may have
@@ -178,18 +183,18 @@ A simple way for merchants to accept GNU Taler payments is the use of the
point-of-sale app. The app can be installed on an Android phone or tablet
and is configured via a simple JSON file on a Web site:
- * In the app settings you need to specify the URL of the Web site where
- the app can download the categories, products and prices from which
- orders are to be compiled. You can optionally specify a username and
- password to authenticate to the Web server.
+* In the app settings you need to specify the URL of the Web site where
+ the app can download the categories, products and prices from which
+ orders are to be compiled. You can optionally specify a username and
+ password to authenticate to the Web server.
- * The syntax of the JSON file is described in the point-of-sale app
- manual. However, you may simply want to download the sample JSON
- file from our documentation and use it as a starting point.
+* The syntax of the JSON file is described in the point-of-sale app
+ manual. However, you may simply want to download the sample JSON
+ file from our documentation and use it as a starting point.
- * A key option is the merchant backend with the authorization key
- which must be included in this JSON configuration. You may point
- the point-of-sale app to any instance of a merchant backend.
+* A key option is the merchant backend with the authorization key
+ which must be included in this JSON configuration. You may point
+ the point-of-sale app to any instance of a merchant backend.
Once configured, the point-of-sale app allows the user to select a product
category and then to quickly add products from that category to an order. You
@@ -270,9 +275,8 @@ template does not specify a fixed amount, the payer will be prompted to enter
the amount to be paid (and possibly given the opportunity to specify or alter
the summary). Selecting "pay" will complete the transaction. If payment
confirmations are configured by the merchant backend, the wallet will then
-display a confirmation code that can be shown to the merchant as a proof of
-payment.
-
+display a TOTP confirmation code that can be shown to the merchant as a proof
+of payment.
@@ -305,8 +309,8 @@ Pay events
For "pay" events, the backend will provide the following
information to the Mustach templating engine:
- * :ref:`contract_terms <contract-terms>`: the contract terms of the paid order
- * order_id: the ID of the order that received the refund
+* :ref:`contract_terms <contract-terms>`: the contract terms of the paid order
+* order_id: the ID of the order that received the refund
Refund events
@@ -315,119 +319,10 @@ Refund events
For "refund" events, the backend will provide the following information to the
Mustach templating engine:
- * timestamp: time of the refund (in nanoseconds since 1970)
- * order_id: the ID of the order that received the refund
- * :ref:`contract_terms <contract-terms>`: the full JSON of the contract terms of the refunded order
- * refund_amout: the amount that was being refunded
- * reason: the reason entered by the merchant staff for granting the refund;
- be careful, you probably want to inform your staff if a webhook may expose
- this information to the consumer
-
-
-.. _Rewarding-visitors:
-
-Rewarding visitors
-==================
-
-.. index:: rewards
-
-Taler can also be used to reward digital cash to Web site visitors. For
-example, you may be running an online survey, and you want to reward those
-people that have dutifully completed the survey. If they have installed a
-Taler wallet, you can provide them with a reward for their deeds. This section
-describes how to setup the Taler merchant backend for rewarding.
-
-There are three basic steps that must happen to reward a visitor.
-
-.. _Fund-the-reserve:
-
-Fund the reserve
-----------------
-
-.. index:: reserve
-
-First, the reserve must be setup in the merchant backend. A reserve
-is always tied to a particular instance. To create a reserve with
-10 KUDOS at instance ``default`` using the demo exchange, use:
-
-.. code-block:: console
-
- $ taler-merchant-setup-reserve \
- -a KUDOS:10 \
- -e https://exchange.demo.taler.net/ \
- -m http://localhost:8888/instances/default
-
-The above command assumes that the merchant runs on localhost on
-port 8888.
-For more information, including how to transmit authentication information
-to the backend, see :doc:`manpages/taler-merchant-setup-reserve.1`.
-
-The command will output a ``payto://`` URI which specifies where to
-wire the funds and which wire transfer subject to use.
-
- .. note::
-
- FIXME: add full example output.
-
-In our example, the output for the wire transfer subject is:
-
-.. code-block:: none
-
- QPE24X8PBX3BZ6E7GQ5VAVHV32FWTTCADR0TRQ183MSSJD2CHNEG
-
-You now need to make a wire transfer to the exchange’s bank account
-using the given wire transfer subject.
-
-Make your wire transfer and (optionally) check at
-“https://exchange/reserves/QPE24X...” whether your transfer has arrived at the
-exchange.
-
-Once the funds have arrived, you can start to use the reserve for
-rewarding.
-
-Note that an exchange will typically close a reserve after four weeks, wiring
-all remaining funds back to the sender’s account. Thus, you should plan to
-wire funds corresponding to a campaign of about two weeks to the exchange
-initially. If your campaign runs longer, you should setup another reserve
-every other week to ensure one is always ready.
-
-.. _Authorize-a-reward:
-
-Authorize a reward
-------------------
-
-When your frontend has reached the point where a client is supposed to receive
-a reward, it needs to first authorize the reward. For this, the frontend must use
-a POST to ``/private/reserves/$RESERVE_PUB/authorize-reward``. To authorize a
-reward, the frontend has to provide the following information in the body of the
-POST request:
-
-- The amount of the reward
-
-- The justification (only used internally for the back-office)
-
-- The URL where the wallet should navigate next after the reward was
- processed
-
-- The reward-pickup URL (see next section)
-
-In response to this request, the backend will return a reward token, an
-expiration time and the exchange URL. The expiration time will indicate
-how long the reward is valid (when the reserve expires). The reward token is
-an opaque string that contains all the information needed by the wallet
-to process the reward. The frontend must send this reward token to the browser
-in a special “402 Payment Required” response inside the ``Taler``
-header.
-
-The frontend should handle errors returned by the backend, such as
-misconfigured instances or a lack of remaining funds for rewarding.
-
-.. _Picking-up-of-the-reward:
-
-Picking up of the reward
-------------------------
-
-The wallet will POST a JSON object to the shop’s
-``/rewards/$REWARD_ID/pickup`` handler.
-The frontend must then forward this request to the backend. The response
-generated by the backend can then be forwarded directly to the wallet.
+* timestamp: time of the refund (in nanoseconds since 1970)
+* order_id: the ID of the order that received the refund
+* :ref:`contract_terms <contract-terms>`: the full JSON of the contract terms of the refunded order
+* refund_amount: the amount that was being refunded
+* reason: the reason entered by the merchant staff for granting the refund;
+ be careful, you probably want to inform your staff if a webhook may expose
+ this information to the consumer
diff --git a/taler-wallet.rst b/taler-wallet.rst
index 04a77e7d..4a975340 100644
--- a/taler-wallet.rst
+++ b/taler-wallet.rst
@@ -1,8 +1,28 @@
-GNU Taler Wallet Manual
-#######################
+..
+ This file is part of GNU TALER.
+ Copyright (C) 2014-2024 Taler Systems SA
+
+ TALER is free software; you can redistribute it and/or modify it under the
+ terms of the GNU Affero General Public License as published by the Free Software
+ Foundation; either version 2.1, or (at your option) any later version.
+
+ TALER is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License along with
+ TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+
+
+Wallet Manual
+#############
The GNU Taler wallet allows customers to withdraw and spend digital cash.
+.. contents:: Table of Contents
+ :depth: 1
+ :local:
+
WebExtension Wallet
===================
@@ -172,6 +192,53 @@ Manual withdrawing
--amount EUR:5
+P2P push payments
+-----------------
+
+The following code generates a P2P push transaction over 1 CHF
+with an expiration time of 30 days (assuming the wallet has a
+sufficient balance):
+
+.. code-block:: console
+
+ $ taler-wallet-cli p2p initiate-push-debit \
+ --purse-expiration="30 d" \
+ --summary="The summary" \
+ CHF:1
+
+The final URL can then be found in the transaction list:
+
+.. code-block:: console
+
+ $ taler-wallet-cli transactions
+
+Background wallet
+-----------------
+
+A wallet can be launched in the background:
+
+.. code-block:: console
+
+ $ taler-wallet-cli advanced serve &
+
+You can then run various Taler operations faster against
+this one persistent instance:
+
+.. code-block:: console
+
+ $ taler-wallet-cli --wallet-connection=wallet-core.sock ...
+
+Here ``...`` needs to be changed to the commando to run.
+Make sure to run
+
+.. code-block:: console
+
+ $ taler-wallet-cli --wallet-connection=wallet-core.sock \
+ run-until-done
+
+to wait for pending transactions to complete.
+
+
Testing an exchange deployment
------------------------------
@@ -207,6 +274,48 @@ is functional:
# The "deposit group id" can be found in the output of the transactions list.
$ taler-wallet-cli deposit track $DEPOSIT_GROUP_ID
+.. _withdraw-simulation:
+
+
+Paying for an order
+===================
+
+.. note::
+
+ This section is in dire need for some editing...
+
+This section explains how to pay for an order in a scenario where the fiat bank
+is simulated. The simulation takes place by crafting ad-hoc XML files as if the
+bank would have issued them. Such XML files carry information about incoming payments
+to the regional currency master bank account. Finally, the XML files are passed
+to LibEuFin nexus via a convenient CLI method. The responsible script for such
+simulation is ``withdraw.sh``.
+
+Run ``./withdraw.sh`` without any arguments. Assuming that you ran the command
+as the ``test-user``, after the execution, 5 units of the regional currency should
+be found in the CLI wallet owned by ``test-user``.
+
+
+Check it with:
+
+.. code-block:: console
+
+ $ taler-wallet-cli balance
+
+If so, call the wallet in the following way to finally pay for the order just created:
+
+.. code-block:: console
+
+ $ taler-wallet-cli handle-uri "$TALER_PAY_URI"
+
+.. note::
+
+ Reset the state before going to production, as it impacts the way nexus
+ asks records to the bank. In particular, delete: any database and the
+ files ``config/user.conf`` and ``config/internal.conf``, and finally run
+ ``./main.sh`` again.
+
+
@@ -389,7 +498,6 @@ Things we still need tests for:
Or when the merchant is not reachable? Or the bank?
This can be tested by temporarily killing those services.
* How does the wallet deal with processing the same ``taler://(pay|withdraw)`` URI twice?
-* Test rewards (accepting/refusing a reward)
* Test refunds
* Test for :ref:`session-based payments <repurchase>`
* Test case for auto-refunds
diff --git a/wallet/wallet-core.md b/wallet/wallet-core.md
index 2e34fb4f..977e100d 100644
--- a/wallet/wallet-core.md
+++ b/wallet/wallet-core.md
@@ -15,8 +15,10 @@ This file is auto-generated from [wallet-core](https://git.taler.net/wallet-core
* [ConvertWithdrawalAmountOp](#convertwithdrawalamountop)
### Managing Transactions
* [GetTransactionsOp](#gettransactionsop)
+* [ListAssociatedRefreshesOp](#listassociatedrefreshesop)
* [TestingGetSampleTransactionsOp](#testinggetsampletransactionsop)
* [GetTransactionByIdOp](#gettransactionbyidop)
+* [GetWithdrawalTransactionByUriOp](#getwithdrawaltransactionbyuriop)
* [RetryPendingNowOp](#retrypendingnowop)
* [DeleteTransactionOp](#deletetransactionop)
* [RetryTransactionOp](#retrytransactionop)
@@ -37,12 +39,17 @@ This file is auto-generated from [wallet-core](https://git.taler.net/wallet-core
* [ConfirmPayOp](#confirmpayop)
* [StartRefundQueryForUriOp](#startrefundqueryforuriop)
* [StartRefundQueryOp](#startrefundqueryop)
-### Rewards
-* [PrepareTipOp](#preparetipop)
-* [AcceptTipOp](#accepttipop)
+### Global Currency management
+* [ListGlobalCurrencyAuditorsOp](#listglobalcurrencyauditorsop)
+* [ListGlobalCurrencyExchangesOp](#listglobalcurrencyexchangesop)
+* [AddGlobalCurrencyExchangeOp](#addglobalcurrencyexchangeop)
+* [AddGlobalCurrencyAuditorOp](#addglobalcurrencyauditorop)
+* [RemoveGlobalCurrencyExchangeOp](#removeglobalcurrencyexchangeop)
+* [RemoveGlobalCurrencyAuditorOp](#removeglobalcurrencyauditorop)
### Exchange Management
* [ListExchangesOp](#listexchangesop)
* [ListExchangesForScopedCurrencyOp](#listexchangesforscopedcurrencyop)
+* [PrepareWithdrawExchangeOp](#preparewithdrawexchangeop)
* [AddExchangeOp](#addexchangeop)
* [UpdateExchangeEntryOp](#updateexchangeentryop)
* [ListKnownBankAccountsOp](#listknownbankaccountsop)
@@ -51,7 +58,9 @@ This file is auto-generated from [wallet-core](https://git.taler.net/wallet-core
* [SetExchangeTosAcceptedOp](#setexchangetosacceptedop)
* [GetExchangeTosOp](#getexchangetosop)
* [GetExchangeDetailedInfoOp](#getexchangedetailedinfoop)
-* [ListCurrenciesOp](#listcurrenciesop)
+* [GetExchangeEntryByUrlOp](#getexchangeentrybyurlop)
+* [GetExchangeResourcesOp](#getexchangeresourcesop)
+* [DeleteExchangeOp](#deleteexchangeop)
* [GetCurrencySpecificationOp](#getcurrencyspecificationop)
### Deposits
* [GenerateDepositGroupTxIdOp](#generatedepositgrouptxidop)
@@ -377,9 +386,17 @@ export type GetTransactionsOp = {
export interface TransactionsRequest {
/**
* return only transactions in the given currency
+ *
+ * it will be removed in next release
+ *
+ * @deprecated use scopeInfo
*/
currency?: string;
/**
+ * return only transactions in the given scopeInfo
+ */
+ scopeInfo?: ScopeInfo;
+ /**
* if present, results will be limited to transactions related to the given search string
*/
search?: string;
@@ -398,6 +415,32 @@ export interface TransactionsRequest {
```
+### ListAssociatedRefreshesOp
+```typescript
+/**
+ * List refresh transactions associated with another transaction.
+ */
+export type ListAssociatedRefreshesOp = {
+ op: WalletApiOperation.ListAssociatedRefreshes;
+ request: ListAssociatedRefreshesRequest;
+ response: ListAssociatedRefreshesResponse;
+};
+// ListAssociatedRefreshes = "listAssociatedRefreshes"
+
+```
+```typescript
+export interface ListAssociatedRefreshesRequest {
+ transactionId: string;
+}
+
+```
+```typescript
+export interface ListAssociatedRefreshesResponse {
+ transactionIds: string[];
+}
+
+```
+
### TestingGetSampleTransactionsOp
```typescript
/**
@@ -429,6 +472,23 @@ export interface TransactionByIdRequest {
```
+### GetWithdrawalTransactionByUriOp
+```typescript
+export type GetWithdrawalTransactionByUriOp = {
+ op: WalletApiOperation.GetWithdrawalTransactionByUri;
+ request: WithdrawalTransactionByURIRequest;
+ response: TransactionWithdrawal | undefined;
+};
+// GetWithdrawalTransactionByUri = "getWithdrawalTransactionByUri"
+
+```
+```typescript
+export interface WithdrawalTransactionByURIRequest {
+ talerWithdrawUri: string;
+}
+
+```
+
### RetryPendingNowOp
```typescript
export type RetryPendingNowOp = {
@@ -554,7 +614,7 @@ export type ResumeTransactionOp = {
export type GetWithdrawalDetailsForAmountOp = {
op: WalletApiOperation.GetWithdrawalDetailsForAmount;
request: GetWithdrawalDetailsForAmountRequest;
- response: ManualWithdrawalDetails;
+ response: WithdrawalDetailsForAmount;
};
// GetWithdrawalDetailsForAmount = "getWithdrawalDetailsForAmount"
@@ -568,10 +628,12 @@ export interface GetWithdrawalDetailsForAmountRequest {
```
```typescript
-export interface ManualWithdrawalDetails {
+export interface WithdrawalDetailsForAmount {
/**
* Did the user accept the current version of the exchange's
* terms of service?
+ *
+ * @deprecated the client should query the exchange entry instead
*/
tosAccepted: boolean;
/**
@@ -591,18 +653,22 @@ export interface ManualWithdrawalDetails {
/**
* Ways to pay the exchange.
*
- * @deprecated in favor of withdrawalAccountList
+ * @deprecated in favor of withdrawalAccountsList
*/
paytoUris: string[];
/**
* Ways to pay the exchange, including accounts that require currency conversion.
*/
- withdrawalAccountList: WithdrawalExchangeAccountDetails[];
+ withdrawalAccountsList: WithdrawalExchangeAccountDetails[];
/**
* If the exchange supports age-restricted coins it will return
* the array of ages.
*/
ageRestrictionOptions?: number[];
+ /**
+ * Scope info of the currency withdrawn.
+ */
+ scopeInfo: ScopeInfo;
}
```
@@ -624,17 +690,29 @@ export type GetWithdrawalDetailsForUriOp = {
export interface GetWithdrawalDetailsForUriRequest {
talerWithdrawUri: string;
restrictAge?: number;
+ notifyChangeFromPendingTimeoutMs?: number;
}
```
```typescript
export interface WithdrawUriInfoResponse {
+ operationId: string;
+ status: WithdrawalOperationStatus;
+ confirmTransferUrl?: string;
amount: AmountString;
defaultExchangeBaseUrl?: string;
possibleExchanges: ExchangeListItem[];
}
```
+```typescript
+export type WithdrawalOperationStatus =
+ | "pending"
+ | "selected"
+ | "aborted"
+ | "confirmed";
+
+```
### AcceptBankIntegratedWithdrawalOp
```typescript
@@ -692,6 +770,8 @@ export interface AcceptManualWithdrawalRequest {
export interface AcceptManualWithdrawalResult {
/**
* Payto URIs that can be used to fund the withdrawal.
+ *
+ * @deprecated in favor of withdrawalAccountsList
*/
exchangePaytoUris: string[];
/**
@@ -854,7 +934,7 @@ export interface ConfirmPayRequest {
* @deprecated use transactionId instead
*/
proposalId?: string;
- transactionId?: string;
+ transactionId?: TransactionIdStr;
sessionId?: string;
forcedCoinSel?: ForcedCoinSel;
}
@@ -905,6 +985,9 @@ export interface PrepareRefundRequest {
```
```typescript
export interface StartRefundQueryForUriResponse {
+ /**
+ * Transaction id of the *payment* where the refund query was started.
+ */
transactionId: TransactionIdStr;
}
@@ -927,92 +1010,120 @@ export interface StartRefundQueryRequest {
```
-### PrepareTipOp
+### ListGlobalCurrencyAuditorsOp
```typescript
-/**
- * Query and store information about a reward.
- */
-export type PrepareTipOp = {
- op: WalletApiOperation.PrepareReward;
- request: PrepareRewardRequest;
- response: PrepareRewardResult;
+export type ListGlobalCurrencyAuditorsOp = {
+ op: WalletApiOperation.ListGlobalCurrencyAuditors;
+ request: EmptyObject;
+ response: ListGlobalCurrencyAuditorsResponse;
};
-// PrepareReward = "prepareReward"
+// ListGlobalCurrencyAuditors = "listGlobalCurrencyAuditors"
```
```typescript
-export interface PrepareRewardRequest {
- talerRewardUri: string;
+export interface ListGlobalCurrencyAuditorsResponse {
+ auditors: {
+ currency: string;
+ auditorBaseUrl: string;
+ auditorPub: string;
+ }[];
}
```
+
+### ListGlobalCurrencyExchangesOp
```typescript
-export interface PrepareTipResult {
- /**
- * Unique ID for the tip assigned by the wallet.
- * Typically different from the merchant-generated tip ID.
- *
- * @deprecated use transactionId instead
- */
- walletRewardId: string;
- /**
- * Tip transaction ID.
- */
- transactionId: string;
- /**
- * Has the tip already been accepted?
- */
- accepted: boolean;
- /**
- * Amount that the merchant gave.
- */
- rewardAmountRaw: AmountString;
- /**
- * Amount that arrived at the wallet.
- * Might be lower than the raw amount due to fees.
- */
- rewardAmountEffective: AmountString;
- /**
- * Base URL of the merchant backend giving then tip.
- */
- merchantBaseUrl: string;
- /**
- * Base URL of the exchange that is used to withdraw the tip.
- * Determined by the merchant, the wallet/user has no choice here.
- */
+export type ListGlobalCurrencyExchangesOp = {
+ op: WalletApiOperation.ListGlobalCurrencyExchanges;
+ request: EmptyObject;
+ response: ListGlobalCurrencyExchangesResponse;
+};
+// ListGlobalCurrencyExchanges = "listGlobalCurrencyExchanges"
+
+```
+```typescript
+export interface ListGlobalCurrencyExchangesResponse {
+ exchanges: {
+ currency: string;
+ exchangeBaseUrl: string;
+ exchangeMasterPub: string;
+ }[];
+}
+
+```
+
+### AddGlobalCurrencyExchangeOp
+```typescript
+export type AddGlobalCurrencyExchangeOp = {
+ op: WalletApiOperation.AddGlobalCurrencyExchange;
+ request: AddGlobalCurrencyExchangeRequest;
+ response: EmptyObject;
+};
+// AddGlobalCurrencyExchange = "addGlobalCurrencyExchange"
+
+```
+```typescript
+export interface AddGlobalCurrencyExchangeRequest {
+ currency: string;
exchangeBaseUrl: string;
- /**
- * Time when the tip will expire. After it expired, it can't be picked
- * up anymore.
- */
- expirationTimestamp: TalerProtocolTimestamp;
+ exchangeMasterPub: string;
}
```
-### AcceptTipOp
+### AddGlobalCurrencyAuditorOp
```typescript
-/**
- * Accept a reward.
- */
-export type AcceptTipOp = {
- op: WalletApiOperation.AcceptReward;
- request: AcceptRewardRequest;
- response: AcceptTipResponse;
+export type AddGlobalCurrencyAuditorOp = {
+ op: WalletApiOperation.AddGlobalCurrencyAuditor;
+ request: AddGlobalCurrencyAuditorRequest;
+ response: EmptyObject;
};
-// AcceptReward = "acceptReward"
+// AddGlobalCurrencyAuditor = "addGlobalCurrencyAuditor"
```
```typescript
-export interface AcceptRewardRequest {
- walletRewardId: string;
+export interface AddGlobalCurrencyAuditorRequest {
+ currency: string;
+ auditorBaseUrl: string;
+ auditorPub: string;
}
```
+
+### RemoveGlobalCurrencyExchangeOp
```typescript
-export interface AcceptTipResponse {
- transactionId: TransactionIdStr;
- next_url?: string;
+export type RemoveGlobalCurrencyExchangeOp = {
+ op: WalletApiOperation.RemoveGlobalCurrencyExchange;
+ request: RemoveGlobalCurrencyExchangeRequest;
+ response: EmptyObject;
+};
+// RemoveGlobalCurrencyExchange = "removeGlobalCurrencyExchange"
+
+```
+```typescript
+export interface RemoveGlobalCurrencyExchangeRequest {
+ currency: string;
+ exchangeBaseUrl: string;
+ exchangeMasterPub: string;
+}
+
+```
+
+### RemoveGlobalCurrencyAuditorOp
+```typescript
+export type RemoveGlobalCurrencyAuditorOp = {
+ op: WalletApiOperation.RemoveGlobalCurrencyAuditor;
+ request: RemoveGlobalCurrencyAuditorRequest;
+ response: EmptyObject;
+};
+// RemoveGlobalCurrencyAuditor = "removeGlobalCurrencyAuditor"
+
+```
+```typescript
+export interface RemoveGlobalCurrencyAuditorRequest {
+ currency: string;
+ auditorBaseUrl: string;
+ auditorPub: string;
}
```
@@ -1070,6 +1181,45 @@ export interface ShortExchangeListItem {
```
+### PrepareWithdrawExchangeOp
+```typescript
+/**
+ * Prepare for withdrawing via a taler://withdraw-exchange URI.
+ */
+export type PrepareWithdrawExchangeOp = {
+ op: WalletApiOperation.PrepareWithdrawExchange;
+ request: PrepareWithdrawExchangeRequest;
+ response: PrepareWithdrawExchangeResponse;
+};
+// PrepareWithdrawExchange = "prepareWithdrawExchange"
+
+```
+```typescript
+export interface PrepareWithdrawExchangeRequest {
+ /**
+ * A taler://withdraw-exchange URI.
+ */
+ talerUri: string;
+}
+
+```
+```typescript
+export interface PrepareWithdrawExchangeResponse {
+ /**
+ * Base URL of the exchange that already existed
+ * or was ephemerally added as an exchange entry to
+ * the wallet.
+ */
+ exchangeBaseUrl: string;
+ /**
+ * Amount from the taler://withdraw-exchange URI.
+ * Only present if specified in the URI.
+ */
+ amount?: AmountString;
+}
+
+```
+
### AddExchangeOp
```typescript
/**
@@ -1100,6 +1250,7 @@ export type UpdateExchangeEntryOp = {
```typescript
export interface UpdateExchangeEntryRequest {
exchangeBaseUrl: string;
+ force?: boolean;
}
```
@@ -1264,6 +1415,7 @@ export type GetExchangeTosOp = {
export interface GetExchangeTosRequest {
exchangeBaseUrl: string;
acceptedFormat?: string[];
+ acceptLanguage?: string;
}
```
@@ -1286,6 +1438,16 @@ export interface GetExchangeTosResult {
* Accepted content type
*/
contentType: string;
+ /**
+ * Language of the returned content.
+ *
+ * If missing, language is unknown.
+ */
+ contentLanguage: string | undefined;
+ /**
+ * Available languages as advertised by the exchange.
+ */
+ tosAvailableLanguages: string[];
tosStatus: ExchangeTosStatus;
}
@@ -1350,31 +1512,69 @@ export interface FeeDescription {
```
-### ListCurrenciesOp
+### GetExchangeEntryByUrlOp
```typescript
/**
- * List currencies known to the wallet.
+ * Get the current terms of a service of an exchange.
*/
-export type ListCurrenciesOp = {
- op: WalletApiOperation.ListCurrencies;
- request: EmptyObject;
- response: WalletCurrencyInfo;
+export type GetExchangeEntryByUrlOp = {
+ op: WalletApiOperation.GetExchangeEntryByUrl;
+ request: GetExchangeEntryByUrlRequest;
+ response: GetExchangeEntryByUrlResponse;
};
-// ListCurrencies = "listCurrencies"
+// GetExchangeEntryByUrl = "getExchangeEntryByUrl"
```
```typescript
-export interface WalletCurrencyInfo {
- trustedAuditors: {
- currency: string;
- auditorPub: string;
- auditorBaseUrl: string;
- }[];
- trustedExchanges: {
- currency: string;
- exchangeMasterPub: string;
- exchangeBaseUrl: string;
- }[];
+export interface GetExchangeEntryByUrlRequest {
+ exchangeBaseUrl: string;
+}
+
+```
+
+### GetExchangeResourcesOp
+```typescript
+/**
+ * Get resources associated with an exchange.
+ */
+export type GetExchangeResourcesOp = {
+ op: WalletApiOperation.GetExchangeResources;
+ request: GetExchangeResourcesRequest;
+ response: GetExchangeResourcesResponse;
+};
+// GetExchangeResources = "getExchangeResources"
+
+```
+```typescript
+export interface GetExchangeResourcesRequest {
+ exchangeBaseUrl: string;
+}
+
+```
+```typescript
+export interface GetExchangeResourcesResponse {
+ hasResources: boolean;
+}
+
+```
+
+### DeleteExchangeOp
+```typescript
+/**
+ * Get resources associated with an exchange.
+ */
+export type DeleteExchangeOp = {
+ op: WalletApiOperation.GetExchangeResources;
+ request: DeleteExchangeRequest;
+ response: EmptyObject;
+};
+// GetExchangeResources = "getExchangeResources"
+
+```
+```typescript
+export interface DeleteExchangeRequest {
+ exchangeBaseUrl: string;
+ purge?: boolean;
}
```
@@ -1401,18 +1601,6 @@ export interface GetCurrencySpecificationResponse {
}
```
-```typescript
-export interface CurrencySpecification {
- name: string;
- num_fractional_input_digits: Integer;
- num_fractional_normal_digits: Integer;
- num_fractional_trailing_zero_digits: Integer;
- alt_unit_names: {
- [log10: string]: string;
- };
-}
-
-```
### GenerateDepositGroupTxIdOp
```typescript
@@ -1462,7 +1650,7 @@ export interface CreateDepositGroupRequest {
* that occur while the operation has been created but
* before the creation request has returned.
*/
- transactionId?: string;
+ transactionId?: TransactionIdStr;
depositPaytoUri: string;
amount: AmountString;
}
@@ -1908,6 +2096,17 @@ export interface CheckPeerPushDebitRequest {
export interface CheckPeerPushDebitResponse {
amountRaw: AmountString;
amountEffective: AmountString;
+ exchangeBaseUrl: string;
+ /**
+ * Maximum expiration date, based on how close the coins
+ * used for the payment are to expiry.
+ *
+ * The value is based on when the wallet would typically
+ * automatically refresh the coins on its own, leaving enough
+ * time to get a refund for the push payment and refresh the
+ * coin.
+ */
+ maxExpirationDate: TalerProtocolTimestamp;
}
```
@@ -1965,14 +2164,18 @@ export interface PreparePeerPushCreditRequest {
```typescript
export interface PreparePeerPushCreditResponse {
contractTerms: PeerContractTerms;
+ amountRaw: AmountString;
+ amountEffective: AmountString;
+ transactionId: TransactionIdStr;
+ exchangeBaseUrl: string;
+ /**
+ * @deprecated use transaction ID instead.
+ */
+ peerPushCreditId: string;
/**
* @deprecated
*/
amount: AmountString;
- amountRaw: AmountString;
- amountEffective: AmountString;
- peerPushCreditId: string;
- transactionId: string;
}
```
@@ -2100,7 +2303,7 @@ export interface PreparePeerPullDebitResponse {
amountRaw: AmountString;
amountEffective: AmountString;
peerPullDebitId: string;
- transactionId: string;
+ transactionId: TransactionIdStr;
}
```
@@ -2126,7 +2329,7 @@ export interface ConfirmPeerPullDebitRequest {
* @deprecated use transactionId instead
*/
peerPullDebitId?: string;
- transactionId?: string;
+ transactionId?: TransactionIdStr;
}
```
@@ -2172,12 +2375,18 @@ export type ExportDbOp = {
```typescript
export type ImportDbOp = {
op: WalletApiOperation.ImportDb;
- request: any;
- response: any;
+ request: ImportDbRequest;
+ response: EmptyObject;
};
// ImportDb = "importDb"
```
+```typescript
+export interface ImportDbRequest {
+ dump: any;
+}
+
+```
### ClearDbOp
```typescript
@@ -2968,7 +3177,7 @@ export type TestingWaitTransactionStateOp = {
```
```typescript
export interface TestingWaitTransactionRequest {
- transactionId: string;
+ transactionId: TransactionIdStr;
txState: TransactionState;
}
@@ -3020,15 +3229,27 @@ export interface ForceRefreshRequest {
## Common Declarations
```typescript
export interface WalletCoreVersion {
+ implementationSemver: string;
+ implementationGitHash: string;
/**
- * @deprecated
+ * Wallet-core protocol version supported by this implementation
+ * of the API ("server" version).
*/
- hash: string | undefined;
version: string;
exchange: string;
merchant: string;
+ bankIntegrationApiRange: string;
+ bankConversionApiRange: string;
+ corebankApiRange: string;
+ /**
+ * @deprecated as bank was split into multiple APIs with separate versioning
+ */
bank: string;
/**
+ * @deprecated
+ */
+ hash: string | undefined;
+ /**
* @deprecated will be removed
*/
devMode: boolean;
@@ -3089,7 +3310,8 @@ export type Transaction =
| TransactionPeerPullDebit
| TransactionPeerPushCredit
| TransactionPeerPushDebit
- | TransactionInternalWithdrawal;
+ | TransactionInternalWithdrawal
+ | TransactionRecoup;
```
```typescript
/**
@@ -3159,6 +3381,7 @@ export declare enum TransactionType {
PeerPushCredit = "peer-push-credit",
PeerPullDebit = "peer-pull-debit",
PeerPullCredit = "peer-pull-credit",
+ Recoup = "recoup",
}
```
```typescript
@@ -3228,6 +3451,7 @@ export declare enum TransactionMinorState {
CheckRefund = "check-refund",
CreatePurse = "create-purse",
DeletePurse = "delete-purse",
+ RefreshExpired = "refresh-expired",
Ready = "ready",
Merge = "merge",
Repurchase = "repurchase",
@@ -3321,17 +3545,49 @@ export interface WithdrawalExchangeAccountDetails {
*/
paytoUri: string;
/**
+ * Status that indicates whether the account can be used
+ * by the user to send funds for a withdrawal.
+ *
+ * ok: account should be shown to the user
+ * error: account should not be shown to the user, UIs might render the error (in conversionError),
+ * especially in dev mode.
+ */
+ status: "ok" | "error";
+ /**
* Transfer amount. Might be in a different currency than the requested
* amount for withdrawal.
*
* Redundant with the amount in paytoUri, just included to avoid parsing.
+ *
+ * Only included if this account does a currency conversion.
+ */
+ transferAmount?: AmountString;
+ /**
+ * Currency specification for the external currency.
+ *
+ * Only included if this account requires a currency conversion.
*/
- transferAmount: AmountString;
+ currencySpecification?: CurrencySpecification;
/**
* Further restrictions for sending money to the
* exchange.
*/
creditRestrictions?: AccountRestriction[];
+ /**
+ * Error that happened when attempting to request the conversion rate.
+ */
+ conversionError?: TalerErrorDetail;
+}
+```
+```typescript
+export interface CurrencySpecification {
+ name: string;
+ num_fractional_input_digits: Integer;
+ num_fractional_normal_digits: Integer;
+ num_fractional_trailing_zero_digits: Integer;
+ alt_unit_names: {
+ [log10: string]: string;
+ };
}
```
```typescript
@@ -3376,6 +3632,7 @@ interface WithdrawalDetailsForTalerBankIntegrationApi {
* Is the reserve ready for withdrawal?
*/
reserveIsReady: boolean;
+ exchangeCreditAccountDetails?: WithdrawalExchangeAccountDetails[];
}
```
```typescript
@@ -3569,6 +3826,7 @@ export declare enum RefreshReason {
AbortPay = "abort-pay",
AbortDeposit = "abort-deposit",
AbortPeerPushDebit = "abort-peer-push-debit",
+ AbortPeerPullDebit = "abort-peer-pull-debit",
Recoup = "recoup",
BackupRestored = "backup-restored",
Scheduled = "scheduled",
@@ -3632,8 +3890,10 @@ export interface TransactionPeerPullCredit extends TransactionCommon {
amountEffective: AmountString;
/**
* URI to send to the other party.
+ *
+ * Only available in the right state.
*/
- talerUri: string;
+ talerUri: string | undefined;
}
```
```typescript
@@ -3738,11 +3998,22 @@ export interface TransactionInternalWithdrawal extends TransactionCommon {
}
```
```typescript
+/**
+ * The exchange revoked a key and the wallet recoups funds.
+ */
+export interface TransactionRecoup extends TransactionCommon {
+ type: TransactionType.Recoup;
+}
+```
+```typescript
export interface AbortTransactionRequest {
transactionId: TransactionIdStr;
}
```
```typescript
+/**
+ * Info about an exchange entry in the wallet.
+ */
export interface ExchangeListItem {
exchangeBaseUrl: string;
currency: string | undefined;
@@ -3751,6 +4022,7 @@ export interface ExchangeListItem {
exchangeEntryStatus: ExchangeEntryStatus;
exchangeUpdateStatus: ExchangeUpdateStatus;
ageRestrictionOptions: number[];
+ scopeInfo: ScopeInfo | undefined;
/**
* Information about the last error that occurred when trying
* to update the exchange info.
@@ -3775,12 +4047,11 @@ export declare enum ExchangeEntryStatus {
```typescript
export declare enum ExchangeUpdateStatus {
Initial = "initial",
- InitialUpdate = "initial(update)",
+ InitialUpdate = "initial-update",
Suspended = "suspended",
- Failed = "failed",
- OutdatedUpdate = "outdated(update)",
+ UnavailableUpdate = "unavailable-update",
Ready = "ready",
- ReadyUpdate = "ready(update)",
+ ReadyUpdate = "ready-update",
}
```
```typescript
@@ -4062,8 +4333,11 @@ export interface ForcedCoinSel {
```typescript
export interface AddExchangeRequest {
exchangeBaseUrl: string;
- masterPub?: string;
+ /**
+ * @deprecated use a separate API call to start a forced exchange update instead
+ */
forceUpdate?: boolean;
+ masterPub?: string;
}
```
```typescript