bank landing: one-step withdraw-exchange + Android/iOS links
Short intro; wallet install; single taler://withdraw-exchange QR.
This commit is contained in:
parent
8729e69e87
commit
5af039ca03
2 changed files with 96 additions and 145 deletions
|
|
@ -13,33 +13,25 @@ open your own bank account, and point merchants at `taler.hacktivism.ch`.
|
|||
|
||||
## User flow (documented on the page)
|
||||
|
||||
### Two steps (only path)
|
||||
Same **one-step** pattern as [taler-ops.ch Android/iOS guides](https://taler-ops.ch/en/users-android.html):
|
||||
|
||||
1. **`taler://add-exchange/exchange.hacktivism.ch/`** — add exchange, accept ToS.
|
||||
2. **Demo withdraw URI** from `withdraw.uri` — bank-integrated withdraw (default `GOA:10`).
|
||||
1. **Install wallet** — Android (Play Store / F-Droid) and iOS (App Store), plus hub `wallet.taler.net`.
|
||||
2. **One QR / link** — `taler://withdraw-exchange/exchange.hacktivism.ch/`
|
||||
Adds the GOA exchange **and** starts withdrawal (accept ToS → enter amount).
|
||||
|
||||
If the demo withdraw is already **confirmed/aborted**, the page points at the bank UI instead.
|
||||
The old two-step path (`taler://add-exchange/…` + demo `taler://withdraw/…` from `withdraw.uri`) is **removed** from the landing.
|
||||
|
||||
Optional: bank UI (`/webui/`) and merchant (`taler.hacktivism.ch`) stay further down.
|
||||
|
||||
### 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/
|
||||
taler-wallet-cli withdraw accept-uri --exchange https://exchange.hacktivism.ch/ 'taler://withdraw/…'
|
||||
# then bank confirm (demo often auto-confirms) + run-until-done
|
||||
# then withdraw from the exchange (amount chosen in wallet UI)
|
||||
```
|
||||
|
||||
### URI note (`:443`)
|
||||
|
||||
libeufin may emit:
|
||||
|
||||
```text
|
||||
taler://withdraw/bank.hacktivism.ch:443/taler-integration/<uuid>
|
||||
```
|
||||
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@
|
|||
.sub {
|
||||
color: var(--muted);
|
||||
margin: 0 auto;
|
||||
max-width: 28rem;
|
||||
max-width: 30rem;
|
||||
font-size: 1.05rem;
|
||||
line-height: 1.45;
|
||||
}
|
||||
|
|
@ -83,7 +83,6 @@
|
|||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
/* Big step cards */
|
||||
.step-card {
|
||||
background: var(--card);
|
||||
backdrop-filter: blur(12px);
|
||||
|
|
@ -168,7 +167,9 @@
|
|||
font-size: 0.85rem;
|
||||
color: #3a342c;
|
||||
font-weight: 700;
|
||||
max-width: 220px;
|
||||
max-width: 240px;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
.cta {
|
||||
display: inline-block;
|
||||
|
|
@ -196,15 +197,6 @@
|
|||
text-align: center;
|
||||
max-width: 100%;
|
||||
}
|
||||
#status {
|
||||
min-height: 1.1em;
|
||||
font-size: 0.85rem;
|
||||
color: var(--muted);
|
||||
margin: 0.4rem 0 0;
|
||||
text-align: center;
|
||||
}
|
||||
#status.err { color: #f0a090; }
|
||||
#status.ok { color: var(--accent2); }
|
||||
code {
|
||||
font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: 0.86em;
|
||||
|
|
@ -214,7 +206,42 @@
|
|||
color: #f0d090;
|
||||
}
|
||||
|
||||
/* Distinct “more options” section further down */
|
||||
/* App store buttons */
|
||||
.app-links {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.55rem;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
.app-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 0.4rem;
|
||||
min-width: 9.5rem;
|
||||
text-decoration: none;
|
||||
font-weight: 700;
|
||||
font-size: 0.92rem;
|
||||
padding: 0.65rem 0.95rem;
|
||||
border-radius: 11px;
|
||||
border: 1px solid rgba(232, 168, 56, 0.4);
|
||||
background: rgba(0, 0, 0, 0.28);
|
||||
color: #f0d090;
|
||||
}
|
||||
.app-btn:hover { filter: brightness(1.08); border-color: rgba(240, 200, 106, 0.7); }
|
||||
.app-btn.ios {
|
||||
border-color: rgba(62, 207, 191, 0.4);
|
||||
color: #b8f5ec;
|
||||
}
|
||||
.app-btn.hub {
|
||||
flex: 1 1 100%;
|
||||
border-color: rgba(201, 184, 160, 0.35);
|
||||
color: var(--muted);
|
||||
font-weight: 600;
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.more-section {
|
||||
margin-top: 2.75rem;
|
||||
padding-top: 1.75rem;
|
||||
|
|
@ -285,7 +312,6 @@
|
|||
transform-origin: center top;
|
||||
opacity: 0.95;
|
||||
}
|
||||
/* Live stats (written by in-container landing-stats.sh → stats.json) */
|
||||
.stats {
|
||||
background: rgba(18, 28, 28, 0.55);
|
||||
border: 1px solid rgba(62, 207, 191, 0.28);
|
||||
|
|
@ -335,7 +361,6 @@
|
|||
text-align: center;
|
||||
}
|
||||
.stat .v.teal { color: #5eead4; }
|
||||
.stat .v.muted { color: var(--muted); font-size: 0.92rem; font-weight: 600; }
|
||||
.stat.wide { grid-column: 1 / -1; }
|
||||
.wd-list {
|
||||
list-style: none;
|
||||
|
|
@ -391,14 +416,14 @@
|
|||
<body>
|
||||
<main>
|
||||
<header class="hero">
|
||||
<span class="badge">Intergalactic · GOA · no IBAN</span>
|
||||
<span class="badge">Exploration · GOA</span>
|
||||
<h1>GOA Exploration Bank</h1>
|
||||
<p class="sub">
|
||||
Two steps to put <strong>GOA</strong> in your GNU Taler wallet.
|
||||
Install the wallet, then <strong>one QR</strong> adds the exchange and starts a withdraw.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<!-- ========== LIVE STATS (stats.json from bank container) ========== -->
|
||||
<!-- ========== LIVE STATS ========== -->
|
||||
<section class="stats" id="stats" aria-labelledby="stats-title" hidden>
|
||||
<h2 id="stats-title">GOA flow</h2>
|
||||
<div class="stats-grid">
|
||||
|
|
@ -483,64 +508,62 @@
|
|||
<p class="stats-foot" id="st-perf-foot">Memory from /proc + cgroup inside podman container.</p>
|
||||
</section>
|
||||
|
||||
<!-- ========== STEP 1 ========== -->
|
||||
<!-- ========== STEP 1: install apps ========== -->
|
||||
<section class="step-card" aria-labelledby="step1-title">
|
||||
<h2 id="step1-title"><span class="step-num">1</span> Add the exchange</h2>
|
||||
<p class="step-tagline">Tell the wallet where GOA coins come from.</p>
|
||||
<h2 id="step1-title"><span class="step-num">1</span> Get the wallet</h2>
|
||||
<p class="step-tagline">Android or iOS</p>
|
||||
<div class="step-body">
|
||||
<ol>
|
||||
<li>Install the <strong>GNU Taler Wallet</strong> (phone app or browser extension).</li>
|
||||
<li>Scan the QR with the wallet, or tap the button.</li>
|
||||
<li>Confirm / trust <code>exchange.hacktivism.ch</code>.</li>
|
||||
</ol>
|
||||
<div class="qr-box">
|
||||
<div id="qr-exchange"></div>
|
||||
<div class="qr-label">Add exchange in wallet</div>
|
||||
<div class="app-links">
|
||||
<a class="app-btn"
|
||||
href="https://play.google.com/store/apps/details?id=net.taler.wallet"
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
Android · Play Store
|
||||
</a>
|
||||
<a class="app-btn"
|
||||
href="https://f-droid.org/en/packages/net.taler.wallet.fdroid/"
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
Android · F-Droid
|
||||
</a>
|
||||
<a class="app-btn ios"
|
||||
href="https://apps.apple.com/app/taler-wallet/id6463440117"
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
iOS · App Store
|
||||
</a>
|
||||
<a class="app-btn hub"
|
||||
href="https://wallet.taler.net/"
|
||||
target="_blank" rel="noopener noreferrer">
|
||||
All platforms · wallet.taler.net
|
||||
</a>
|
||||
</div>
|
||||
<a class="cta" id="open-exchange" href="taler://add-exchange/exchange.hacktivism.ch/">
|
||||
Open in wallet app →
|
||||
</a>
|
||||
<p class="meta">taler://add-exchange/exchange.hacktivism.ch/</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ========== STEP 2 ========== -->
|
||||
<!-- ========== STEP 2: one-step withdraw-exchange ========== -->
|
||||
<section class="step-card step-money" aria-labelledby="step2-title">
|
||||
<h2 id="step2-title"><span class="step-num">2</span> Get the money</h2>
|
||||
<p class="step-tagline">Withdraw GOA into the wallet you just set up.</p>
|
||||
<h2 id="step2-title"><span class="step-num">2</span> Withdraw GOA</h2>
|
||||
<p class="step-tagline">One-step: add exchange + withdraw</p>
|
||||
<div class="step-body">
|
||||
<ol>
|
||||
<li>Scan this second QR with the <strong>same wallet</strong>.</li>
|
||||
<li>Default amount is <code>GOA:10</code> — confirm in the wallet.</li>
|
||||
<li>If the wallet waits on a bank transfer: leave it open a moment — demo withdrawals are auto-confirmed.</li>
|
||||
</ol>
|
||||
<div class="qr-box">
|
||||
<div id="qr-withdraw"></div>
|
||||
<div class="qr-label" id="qr-withdraw-label">Withdraw GOA:10</div>
|
||||
<div id="qr-withdraw-exchange"></div>
|
||||
<div class="qr-label">Scan or open in wallet</div>
|
||||
</div>
|
||||
<a class="cta teal" id="open-wallet" href="#">Open withdraw in wallet →</a>
|
||||
<p id="status">Preparing withdraw QR…</p>
|
||||
<p class="meta" id="uri-line" hidden></p>
|
||||
<a class="cta teal" id="open-withdraw-exchange"
|
||||
href="taler://withdraw-exchange/exchange.hacktivism.ch/">
|
||||
Open in wallet →
|
||||
</a>
|
||||
<p class="meta">taler://withdraw-exchange/exchange.hacktivism.ch/</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ========== FURTHER DOWN: own account ========== -->
|
||||
<!-- ========== Optional bank UI ========== -->
|
||||
<div class="more-section">
|
||||
<span class="more-label">Optional · own bank account</span>
|
||||
<span class="more-label">Optional · bank UI & merchant</span>
|
||||
<div class="more-card">
|
||||
<h2>Need your own balance or merchant setup?</h2>
|
||||
<h2>Own bank account or shop?</h2>
|
||||
<p>
|
||||
The two steps above use a <strong>demo withdraw</strong> prepared by the bank.
|
||||
For your own GOA balance, repeated withdraws, or receiving payments as a merchant,
|
||||
create an account:
|
||||
Register in the bank UI for your own balance, or set up a shop at
|
||||
<a href="https://taler.hacktivism.ch/" style="color:#f0c86a">taler.hacktivism.ch</a>.
|
||||
</p>
|
||||
<ol>
|
||||
<li>Register in the bank UI (username + password).</li>
|
||||
<li>Get a credit (transfer / ops) — new accounts start at <code>GOA:0</code>.</li>
|
||||
<li>Log in → <strong>Withdraw</strong> (wallet still needs the exchange from step 1).</li>
|
||||
<li>To accept payments: set up a shop at
|
||||
<a href="https://taler.hacktivism.ch/" style="color:#f0c86a">taler.hacktivism.ch</a>.</li>
|
||||
</ol>
|
||||
<div class="more-qr">
|
||||
<div class="qr-box">
|
||||
<div id="qr-webui"></div>
|
||||
|
|
@ -548,7 +571,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<div class="more-actions">
|
||||
<a class="cta-sec" href="/webui/">Open bank UI (register / login) →</a>
|
||||
<a class="cta-sec" href="/webui/">Open bank UI →</a>
|
||||
<a class="cta-sec merchant" href="https://taler.hacktivism.ch/">Merchant backend →</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -572,17 +595,8 @@
|
|||
<script>
|
||||
(function () {
|
||||
var WEBUI = "https://bank.hacktivism.ch/webui/";
|
||||
var ADD_EXCHANGE = "taler://add-exchange/exchange.hacktivism.ch/";
|
||||
var statusEl = document.getElementById("status");
|
||||
var uriLine = document.getElementById("uri-line");
|
||||
var openWallet = document.getElementById("open-wallet");
|
||||
var label = document.getElementById("qr-withdraw-label");
|
||||
|
||||
function setStatus(msg, cls) {
|
||||
if (!statusEl) return;
|
||||
statusEl.textContent = msg;
|
||||
statusEl.className = cls || "";
|
||||
}
|
||||
/* taler-ops one-step: add exchange + start withdraw */
|
||||
var WITHDRAW_EXCHANGE = "taler://withdraw-exchange/exchange.hacktivism.ch/";
|
||||
|
||||
function makeQr(el, text) {
|
||||
if (!el) return;
|
||||
|
|
@ -599,35 +613,12 @@
|
|||
});
|
||||
}
|
||||
|
||||
makeQr(document.getElementById("qr-exchange"), ADD_EXCHANGE);
|
||||
makeQr(document.getElementById("qr-withdraw-exchange"), WITHDRAW_EXCHANGE);
|
||||
makeQr(document.getElementById("qr-webui"), WEBUI);
|
||||
|
||||
var defaultAmount = "GOA:10";
|
||||
|
||||
function strip443(uri) {
|
||||
if (!uri) return uri;
|
||||
return uri.replace(/bank\.hacktivism\.ch:443/g, "bank.hacktivism.ch");
|
||||
}
|
||||
|
||||
function useUri(uri, amount) {
|
||||
if (!uri) return false;
|
||||
uri = strip443(uri.trim());
|
||||
var amt = amount || defaultAmount;
|
||||
makeQr(document.getElementById("qr-withdraw"), uri);
|
||||
if (openWallet) openWallet.href = uri;
|
||||
if (uriLine) {
|
||||
uriLine.hidden = false;
|
||||
uriLine.textContent = uri;
|
||||
}
|
||||
if (label) label.textContent = "Withdraw " + amt;
|
||||
setStatus("Ready — default " + amt + ". Scan with the wallet (after step 1).", "ok");
|
||||
return true;
|
||||
}
|
||||
|
||||
function fmtCest(unix, fallback) {
|
||||
var base = "";
|
||||
if (fallback) {
|
||||
// strip trailing CEST/CET/Z if present; we append Europe/Zurich
|
||||
base = String(fallback).replace(/\s*(CEST|CET|UTC|Z)\s*$/i, "").trim();
|
||||
} else if (unix != null && unix !== "") {
|
||||
try {
|
||||
|
|
@ -769,7 +760,7 @@
|
|||
note.textContent = "";
|
||||
}
|
||||
})
|
||||
.catch(function (e) {
|
||||
.catch(function () {
|
||||
if (foot) {
|
||||
foot.hidden = false;
|
||||
foot.className = "stats-foot err";
|
||||
|
|
@ -778,38 +769,6 @@
|
|||
});
|
||||
}
|
||||
loadStats();
|
||||
|
||||
Promise.all([
|
||||
fetch("withdraw.uri", { cache: "no-store" }).then(function (r) {
|
||||
return r.ok ? r.text() : Promise.reject();
|
||||
}),
|
||||
fetch("withdraw.amount", { cache: "no-store" }).then(function (r) {
|
||||
return r.ok ? r.text() : Promise.resolve(defaultAmount);
|
||||
}).catch(function () { return defaultAmount; }),
|
||||
fetch("stats.json", { cache: "no-store" }).then(function (r) {
|
||||
return r.ok ? r.json() : null;
|
||||
}).catch(function () { return null; })
|
||||
])
|
||||
.then(function (parts) {
|
||||
var uri = (parts[0] || "").trim();
|
||||
var amt = (parts[1] || defaultAmount).trim() || defaultAmount;
|
||||
var st = parts[2];
|
||||
if (st && st.demo && st.demo.ready === false) {
|
||||
// Spent demo withdraw — prefer bank UI path
|
||||
fallback("Demo withdraw already used (" + (st.demo.status || "?") + ") — open bank UI below or wait for ops refresh.");
|
||||
return;
|
||||
}
|
||||
if (useUri(uri, amt)) return;
|
||||
fallback();
|
||||
})
|
||||
.catch(function () { fallback(); });
|
||||
|
||||
function fallback(msg) {
|
||||
makeQr(document.getElementById("qr-withdraw"), WEBUI);
|
||||
if (openWallet) openWallet.href = WEBUI;
|
||||
if (label) label.textContent = "Bank UI (no demo withdraw)";
|
||||
setStatus(msg || "No demo withdraw right now — use optional bank account below.", "err");
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue