docs: bank shared withdraw, auto-account, merchant shop landing

Document bank landing layout, demo-withdraw + auto-account APIs
(goa-bank-acc-*, balance 0), explorer-only auto-confirm, QR_Taler, and
merchant shop/stats behaviour. Refresh taler-bank script index.
This commit is contained in:
Hernâni Marques 2026-07-10 20:50:36 +02:00
parent 930716a94d
commit 6a212d14c6
No known key found for this signature in database
3 changed files with 153 additions and 48 deletions

View file

@ -1,38 +1,78 @@
# 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`.
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 Store / F-Droid) and iOS (App Store), plus hub `wallet.taler.net`.
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.
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)”).
### Optional paths
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**.
- **Own bank account** — register in `/webui/`, then withdraw (private balance).
- **`taler://withdraw-exchange/…`** — only useful if you already have a bank balance to withdraw from.
### Optional: personal bank account (auto-created)
### How it works (community pool)
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 click creates a **one-shot** withdrawal from that pool (not a personal login).
3. Wallet accepts the URI; bank auto-confirm + exchange settle → coins in the app.
4. Balance is **shared**; demo amounts only.
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: `scripts/taler-bank/demo-withdraw-api.py`, `refresh-demo-withdraw.sh`, `auto-confirm-withdrawals.sh`, `install-demo-withdraw-api.sh`.
### 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)
@ -62,11 +102,12 @@ Stats are **not** computed on the laptop or host browser. A small script runs
### 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”
- **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)
@ -74,27 +115,18 @@ Stats are **not** computed on the laptop or host browser. A small script runs
{
"ok": true,
"currency": "GOA",
"generated_at": "2026-07-09T18:55Z",
"account": "explorer",
"balance": "GOA:960",
"generated_at": "2026-07-10T20:35+02:00",
"balance_explorer": "GOA:960",
"bank_accounts": { "total": 56, "users": 55 },
"wallets": { "unique_reserves": 51 },
"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" }
"count": 51,
"last_24h": { "amount": "GOA:…" },
"last_7d": { "amount": "GOA:…" }
},
"flow": {
"debits_scanned": "GOA:40",
"credits_scanned": "GOA:1000",
"tx_scanned": 5
},
"demo": {
"uri": "taler://withdraw/…",
"amount": "GOA:10",
"status": "confirmed",
"ready": false
"incoming": { "amount": "GOA:…", "count": 68 },
"withdraw": { "amount": "GOA:…", "count": 51 }
},
"source": "in-container landing-stats.sh"
}
@ -144,22 +176,35 @@ Landing root (nginx in bank container), typically under something like
| File | Role |
|------|------|
| `index.html` | landing (steps + stats panel) |
| `qrcode.min.js` | QR helper |
| `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
## Deploy landing HTML + helper API
```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
# 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)

View file

@ -1,6 +1,6 @@
# Merchant landing (`taler.hacktivism.ch` intro)
Static intro for the **GOA merchant** backend.
Static intro for the **GOA merchant** backend (dual currency GOA + CHF).
| Item | Value |
|------|--------|
@ -8,8 +8,32 @@ Static intro for the **GOA merchant** backend.
| In-container path | `/var/www/merchant-landing/` |
| nginx | listen **9015** (`nginx-landing.conf`) |
| **Host port to publish / wire** | **`9015`** → `127.0.0.1:9015` |
| Public path (once Caddy wired) | e.g. `https://taler.hacktivism.ch/intro/` |
| Public path | `https://taler.hacktivism.ch/intro/` |
## Features (page)
| Piece | Notes |
|-------|--------|
| Wallet fold | Collapsed “Get the wallet · Android / iOS / web browsers” |
| Web icons | Chrome · Firefox · Opera · Ubuntu Touch (gold+blue; [taler.net wallet](https://www.taler.net/de/wallet.html)) |
| GOA shop samples | `data-product` buttons → public template pay (`goa-shop` instance) |
| Shop pay popup | `shop-pay.js` / `shop-pay.css`**QR_Taler** (blue ring + `qr-logo.svg`), settlement payto expandable |
| Get GOA first | Hint + link to bank; `p(l)ay` with violet `(l)` |
| Stats | Dual-currency aggregates; **recent activity** split GOA/CHF (≤5 each); refund badge violet |
| Performance | Live HTTP probes + container RSS |
Shop product ids/amounts must stay in sync with
`scripts/taler-monitoring/check_e2e.sh``E2E_SHOP_PRODUCTS`
(e2e random-picks **2** products per run by default).
## Deploy
See `scripts/taler-landing/deploy-landings.sh`.
```bash
podman cp configs/merchant-landing/index.html \
taler-hacktivism:/var/www/merchant-landing/index.html
podman cp configs/merchant-landing/shop-pay.js \
taler-hacktivism:/var/www/merchant-landing/shop-pay.js
# shop-pay.css, qr-logo.svg, qrcode.min.js as needed
```
Also see `scripts/taler-landing/deploy-landings.sh` if present.

View file

@ -9,6 +9,11 @@ Container: **`taler-hacktivism-bank`** (libeufin-bank, GOA, **no IBAN**).
| `check_bank-health.sh` | `/usr/local/bin/` | libeufin-bank / any |
| `landing-stats.sh` | `/usr/local/bin/` | root (in container) — writes `/var/www/bank-landing/stats.json` |
| `landing-stats-install.sh` | host only | root/podman — copies + runs + optional cron |
| `demo-withdraw-api.py` | `/usr/local/bin/` | root — loopback **:19096** |
| `install-demo-withdraw-api.sh` | host only | installs API + nginx + auto-confirm |
| `auto-confirm-withdrawals.sh` | `/usr/local/bin/` | root — **explorer-only** confirm loop |
| `refresh-demo-withdraw.sh` | `/usr/local/bin/` | refresh static `withdraw.uri` |
| `credit-account.sh` | host/ops | admin → user credit |
## Usage
@ -30,6 +35,37 @@ Container: **`taler-hacktivism-bank`** (libeufin-bank, GOA, **no IBAN**).
Details + JSON schema: `configs/bank-landing/README.md`.
## Demo withdraw + auto-account API
`demo-withdraw-api.py` listens on **127.0.0.1:19096** (proxied by nginx on the landing):
| Path | Behaviour |
|------|-----------|
| `GET /demo-withdraw.json` | Mint one-shot withdraw from shared **`explorer`** pool; write `withdraw.uri` + watch ids |
| `GET /auto-account.json` | Public `POST /accounts` with generated **`goa-bank-acc-<hex>`** user + password; **balance GOA:0**; return credentials once |
Install / restart:
```bash
./install-demo-withdraw-api.sh
# Public checks:
curl -sS https://bank.hacktivism.ch/intro/demo-withdraw.json | head
curl -sS https://bank.hacktivism.ch/intro/auto-account.json | head # creates a real account
```
Requires **python3** in the bank container. Env: `BANK_URL`, `BANK_USER`/`BANK_PASS`
(or `/root/bank-explorer-password.txt`), `AMOUNT` (default `GOA:10` for shared withdraws).
### Auto-confirm (explorer only)
```bash
# loop inside container — refuses non-explorer unless ALLOW_NON_EXPLORER=1
auto-confirm-withdrawals.sh --loop 4
```
Only confirms withdrawals owned by **`explorer`** when status is `selected`
(community demo path). Does not confirm arbitrary customer withdraws.
## Config
See `configs/taler-hacktivism-bank/`.
See `configs/taler-hacktivism-bank/` and `configs/bank-landing/`.