# Bank landing (`bank.hacktivism.ch`) English intro for **GOA exploration**: put coins in a GNU Taler wallet, optionally open your own bank account, and point merchants at `taler.hacktivism.ch`. | Public URL | What | |------------|------| | `https://bank.hacktivism.ch/` · `/intro/` | Landing (nginx in bank container → host **9013**, Caddy) | | `https://bank.hacktivism.ch/intro/stats.json` | **Live stats** (written *inside* bank container) | | `https://bank.hacktivism.ch/webui/` | libeufin-bank SPA (register · login · withdraw) when libeufin is up on **9012** | | `https://exchange.hacktivism.ch/` | Exchange (ToS `/terms`, keys `/keys`) | | `https://taler.hacktivism.ch/` | Merchant backend | ## User flow (documented on the page) ### Two steps (only path) 1. **`taler://add-exchange/exchange.hacktivism.ch/`** — add exchange, accept ToS. 2. **Demo withdraw URI** from `withdraw.uri` — bank-integrated withdraw (default `GOA:10`). If the demo withdraw is already **confirmed/aborted**, the page points at the bank UI instead. ### CLI sketch (fresh wallet DB) ```bash taler-wallet-cli exchanges add https://exchange.hacktivism.ch/ taler-wallet-cli exchanges accept-tos https://exchange.hacktivism.ch/ taler-wallet-cli withdraw accept-uri --exchange https://exchange.hacktivism.ch/ 'taler://withdraw/…' # then bank confirm (demo often auto-confirms) + run-until-done ``` ### URI note (`:443`) libeufin may emit: ```text taler://withdraw/bank.hacktivism.ch:443/taler-integration/ ``` Explicit default HTTPS port. Valid for wallets; the landing page **strips `:443`** for QR / open links when the host is the public bank name. Both forms work. --- ## Live stats (in bank container) Stats are **not** computed on the laptop or host browser. A small script runs **inside the bank container**, queries libeufin for the demo funding account (`explorer`), and writes a public JSON file next to the landing assets. | Piece | Path / role | |-------|-------------| | Generator (in-container) | `/usr/local/bin/landing-stats.sh` | | Source in admin-log | `scripts/taler-bank/landing-stats.sh` | | Host installer | `scripts/taler-bank/landing-stats-install.sh` | | Output | `/var/www/bank-landing/stats.json` → `https://bank.hacktivism.ch/intro/stats.json` | | Landing UI | `index.html` section **GOA flow · live** | ### What the page shows - **Bank accounts** — registered accounts (libeufin `GET /accounts`, admin) - **Wallets involved** — unique reserve pubs from Taler withdrawal debits (≈ individual wallet withdraws) - **Withdraws / total out** — customer debit withdrawals only (exchange mirror skipped) - **Last withdraws** — recent list with amount, time (**CEST** / `Europe/Zurich`), bank username - **Last 24h / 7d** — count · amount - Footer: updated time (CEST), user-account count, accounts that funded withdraws — **no** “demo QR / pool explorer” ### `stats.json` shape (abridged) ```json { "ok": true, "currency": "GOA", "generated_at": "2026-07-09T18:55Z", "account": "explorer", "balance": "GOA:960", "withdraws": { "count": 4, "total_amount": "GOA:40", "last_amount": "GOA:10", "last_at": "2026-07-09T08:49Z", "last_24h": { "count": 2, "amount": "GOA:20" }, "last_7d": { "count": 4, "amount": "GOA:40" } }, "flow": { "debits_scanned": "GOA:40", "credits_scanned": "GOA:1000", "tx_scanned": 5 }, "demo": { "uri": "taler://withdraw/…", "amount": "GOA:10", "status": "confirmed", "ready": false }, "source": "in-container landing-stats.sh" } ``` ### Install + refresh (on koopa host) ```bash # from laptop: copy scripts, then on koopa: cd /path/to/koopa-admin-log/scripts/taler-bank # copy into container + one-shot run sudo ./landing-stats-install.sh # every minute inside the container (* * * * *) sudo ./landing-stats-install.sh --cron # optional: LANDING_STATS_CRON='*/5 * * * *' ./landing-stats-install.sh --cron # later: only re-run sudo ./landing-stats-install.sh --run-only ``` Requirements **inside** the container: - `curl`, `awk` (mawk OK), `sed`, `date` — **no python** - libeufin-bank listening on loopback (script auto-detects `PORT` / 9012 / 8080) - `/root/bank-explorer-password.txt` (or `BANK_PASS=…` on the `podman exec`) - writable `/var/www/bank-landing/` (same tree nginx uses for `/intro/`) `make-demo-withdraw-qr.sh` also calls `landing-stats.sh` after refreshing the demo URI, when the binary is already installed at `/usr/local/bin/landing-stats.sh`. ### Manual one-liner (debug) ```bash podman exec -e LANDING_DIR=/var/www/bank-landing taler-hacktivism-bank \ /usr/local/bin/landing-stats.sh curl -sS https://bank.hacktivism.ch/intro/stats.json | python3 -m json.tool ``` --- ## Host / container files Landing root (nginx in bank container), typically under something like `/var/www/bank-landing/` or the container path mapped for **9013**: | File | Role | |------|------| | `index.html` | landing (steps + stats panel) | | `qrcode.min.js` | QR helper | | `stats.json` | **live stats** (from in-container script) | | `withdraw.uri` | current demo `taler://withdraw/…` (optional) | | `withdraw.amount` | e.g. `GOA:10` (optional) | | `withdraw-watch.ids` | ids for auto-confirm helper (optional) | ## Deploy landing HTML ```bash # from laptop (example) — path depends on where nginx in the bank container reads from scp koopa-admin-log/configs/bank-landing/index.html \ koopa-admin-log/configs/bank-landing/qrcode.min.js \ hernani@koopa:/tmp/bank-landing/ # then copy into the bank container / host path used by nginx :9013 podman cp /tmp/bank-landing/index.html taler-hacktivism-bank:/var/www/bank-landing/index.html ``` ### Demo QR refresh (in container, no python) ```bash podman exec taler-hacktivism-bank /usr/local/bin/refresh-demo-withdraw.sh # source: scripts/taler-bank/refresh-demo-withdraw.sh ``` Older host script (needs python3): `scripts/taler-bank/make-demo-withdraw-qr.sh`