# Bank landing (`bank.hacktivism.ch`) English intro for **GOA exploration** (badge: **Intergalactic · GOA · no IBAN**): 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/intro/demo-withdraw.json` | Mint **shared-pool** (`explorer`) withdraw URI | | `https://bank.hacktivism.ch/intro/auto-account.json` | Auto-create **personal** bank user (credentials once; balance **GOA:0**) | | `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 | ## Page layout (top → bottom) 1. Hero (badge, short shared-account line) 2. **Get the wallet** — Play / F-Droid / iOS / web hub (Chrome · Firefox · Opera · Ubuntu Touch; gold+blue icons, [taler.net wallet](https://www.taler.net/de/wallet.html)) 3. **Withdraw GOA** — QR_Taler frame (blue ring + logo), open CTA, live pool balance note 4. **How the shared account works** — collapsed fold (click to expand) 5. **Optional · bank UI & GOA shop** — collapsed fold: auto-create account + credentials + QR_Taler for bank UI; mini shop 6. **GOA flow** stats 7. **Performance** 8. Footer ## User flow (documented on the page) ### Primary path (works without your own bank account) 1. **Install wallet** — Android (Play / F-Droid), iOS, Ubuntu Touch (via Waydroid + Android wallet), web (Chrome/Firefox/Opera on taler.net). 2. **One QR / link** — live `taler://withdraw/…` from the **community-shared** bank pool (`explorer`). Minted via `GET /intro/demo-withdraw.json` (or fallback `withdraw.uri`). Auto-confirm finishes the bank side so coins reach the wallet. 3. **Surprising balance note** — shows live `balance_explorer` from `stats.json` (“pool holds GOA:… (shared, but also yours)”). QR encoding matches merchant shop popup (**QR_Taler**): animated `#0042B3` conic ring, off-DOM PNG, center `qr-logo.svg` (`shop-pay.css` classes). Label text: **Scan in wallet**. ### Optional: personal bank account (auto-created) In the optional fold: 1. User clicks **Create my bank account**. 2. Browser calls `GET /intro/auto-account.json` (no form fields). 3. Server registers a new libeufin user via public `POST /accounts`. 4. UI shows **username / password / balance GOA:0** once (“created for you”; not stored for recovery). 5. Username shape: **`goa-bank-acc-<16-hex>`**. 6. QR_Taler + link open `/webui/` so the user can log in with those credentials. Balance **starts at zero** — not the shared `explorer` pool. ### How the shared pool works 1. Shared account `explorer` is pre-funded with GOA. 2. Each demo withdraw is a **one-shot** op from that pool (not a personal login). 3. Wallet accepts the URI; **auto-confirm only for `explorer`** (see `auto-confirm-withdrawals.sh`). 4. Pool balance is communal; amounts you withdraw are yours in the wallet. ### Helpers | Script | Role | |--------|------| | `scripts/taler-bank/demo-withdraw-api.py` | Loopback HTTP **:19096** — `/demo-withdraw.json` + `/auto-account.json` | | `scripts/taler-bank/install-demo-withdraw-api.sh` | Copy into bank container, nginx locations, start API + auto-confirm loop | | `scripts/taler-bank/auto-confirm-withdrawals.sh` | Confirm **explorer-only** withdrawals when status=`selected` | | `scripts/taler-bank/refresh-demo-withdraw.sh` | Refresh static `withdraw.uri` (no python) | | `configs/bank-landing/nginx-landing.conf` | `/intro/demo-withdraw.json`, `/intro/auto-account.json` proxies | Needs **python3** in the bank container for `demo-withdraw-api.py`. ### CLI sketch (fresh wallet DB) ```bash # equivalent one-step in CLI terms: taler-wallet-cli exchanges add https://exchange.hacktivism.ch/ taler-wallet-cli exchanges accept-tos https://exchange.hacktivism.ch/ # then withdraw from the exchange (amount chosen in wallet UI) ``` --- ## 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 - **Withdraws / bank credits** — flow amounts (exchange mirror skipped where noted) - **Last withdraws** — recent list with amount, time (**CEST** / `Europe/Zurich`) - **Last 24h / 7d** — amount - **`balance_explorer`** — live shared-pool balance (shown on withdraw step) - Performance probes + container RSS (bottom of page) ### `stats.json` shape (abridged) ```json { "ok": true, "currency": "GOA", "generated_at": "2026-07-10T20:35+02:00", "balance_explorer": "GOA:960", "bank_accounts": { "total": 56, "users": 55 }, "wallets": { "unique_reserves": 51 }, "withdraws": { "count": 51, "last_24h": { "amount": "GOA:…" }, "last_7d": { "amount": "GOA:…" } }, "flow": { "incoming": { "amount": "GOA:…", "count": 68 }, "withdraw": { "amount": "GOA:…", "count": 51 } }, "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 (wallet, shared withdraw, folds, stats) | | `shop-pay.css` / `shop-pay.js` | GOA shop popup + **QR_Taler** frame styles | | `qr-logo.svg` | center logo on QR_Taler frames | | `qrcode.min.js` | QR encode helper | | `stats.json` | **live stats** (from in-container script) | | `nginx-landing.conf` | bank container nginx (**9013**) | | `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 + helper API ```bash # landing assets podman cp configs/bank-landing/index.html \ taler-hacktivism-bank:/var/www/bank-landing/index.html podman cp configs/bank-landing/shop-pay.js \ taler-hacktivism-bank:/var/www/bank-landing/shop-pay.js # … shop-pay.css, qr-logo.svg, qrcode.min.js as needed # demo-withdraw + auto-account API (python3 in container) ./scripts/taler-bank/install-demo-withdraw-api.sh # or manually: podman cp scripts/taler-bank/demo-withdraw-api.py \ taler-hacktivism-bank:/usr/local/bin/demo-withdraw-api.py podman cp configs/bank-landing/nginx-landing.conf \ taler-hacktivism-bank:/etc/nginx/sites-available/bank-landing # restart: python3 /usr/local/bin/demo-withdraw-api.py on 127.0.0.1:19096 # nginx -s reload; auto-confirm-withdrawals.sh --loop ``` ### 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`