ops: GOA vanilla landings stats wdGet + collect greening
This commit is contained in:
parent
0d881cd726
commit
337d253691
24 changed files with 1074 additions and 107 deletions
|
|
@ -34,6 +34,10 @@ BANK = os.environ.get("BANK_URL", "http://127.0.0.1:9012").rstrip("/")
|
|||
BANK_PUBLIC = os.environ.get("BANK_PUBLIC", "https://bank.hacktivism.ch").rstrip("/")
|
||||
USER = os.environ.get("BANK_USER", "explorer")
|
||||
AMOUNT = os.environ.get("AMOUNT", "GOA:10")
|
||||
EXCHANGE = (
|
||||
os.environ.get("EXCHANGE_URL", "https://exchange.hacktivism.ch/").rstrip("/")
|
||||
+ "/"
|
||||
)
|
||||
LANDING = Path(os.environ.get("LANDING_DIR", "/var/www/bank-landing"))
|
||||
LISTEN = ("127.0.0.1", int(os.environ.get("DEMO_WITHDRAW_PORT", "19096")))
|
||||
|
||||
|
|
@ -112,7 +116,7 @@ def http_json(method: str, url: str, body=None, headers=None, auth=None):
|
|||
return e.code, {"raw": raw[:500]}
|
||||
|
||||
|
||||
def mint_withdraw() -> dict:
|
||||
def mint_withdraw(amount: str | None = None) -> dict:
|
||||
pw = load_pass()
|
||||
code, tok = http_json(
|
||||
"POST",
|
||||
|
|
@ -123,10 +127,14 @@ def mint_withdraw() -> dict:
|
|||
if code != 200 or not tok.get("access_token"):
|
||||
raise RuntimeError(f"token failed HTTP {code}: {tok}")
|
||||
access = tok["access_token"]
|
||||
amt = amount or AMOUNT
|
||||
if ":" not in str(amt):
|
||||
amt = f"GOA:{amt}"
|
||||
# FP pattern: amount + exchange_url (not suggested_amount alone)
|
||||
code, wd = http_json(
|
||||
"POST",
|
||||
f"{BANK}/accounts/{USER}/withdrawals",
|
||||
{"suggested_amount": AMOUNT},
|
||||
{"amount": amt, "exchange_url": EXCHANGE},
|
||||
headers={"Authorization": f"Bearer {access}"},
|
||||
)
|
||||
if code not in (200, 201):
|
||||
|
|
@ -142,7 +150,7 @@ def mint_withdraw() -> dict:
|
|||
uri = normalize_taler_withdraw_uri(str(uri).strip())
|
||||
LANDING.mkdir(parents=True, exist_ok=True)
|
||||
(LANDING / "withdraw.uri").write_text(uri + "\n")
|
||||
(LANDING / "withdraw.amount").write_text(AMOUNT + "\n")
|
||||
(LANDING / "withdraw.amount").write_text(amt + "\n")
|
||||
(LANDING / "withdraw.created").write_text(
|
||||
time.strftime("%Y-%m-%dT%H:%MZ", time.gmtime()) + "\n"
|
||||
)
|
||||
|
|
@ -151,7 +159,8 @@ def mint_withdraw() -> dict:
|
|||
"ok": True,
|
||||
"taler_withdraw_uri": uri,
|
||||
"withdrawal_id": wid,
|
||||
"amount": AMOUNT,
|
||||
"amount": amt,
|
||||
"exchange_url": EXCHANGE,
|
||||
"pool_account": USER,
|
||||
"taler_integration_base": f"{BANK_PUBLIC}/taler-integration/",
|
||||
"hint": "Open in GNU Taler Wallet (iOS/Android/desktop). No bank registration.",
|
||||
|
|
@ -301,15 +310,54 @@ class Handler(BaseHTTPRequestHandler):
|
|||
self._cors()
|
||||
self.end_headers()
|
||||
|
||||
def do_GET(self):
|
||||
path = self.path.split("?", 1)[0]
|
||||
def _proxy_wd(self, parsed):
|
||||
"""GET withdrawal-operation: inject suggested/required exchange (Android/iOS)."""
|
||||
q = ("?" + parsed.query) if parsed.query else ""
|
||||
url = f"{BANK}{parsed.path}{q}"
|
||||
ctx = ssl.create_default_context()
|
||||
req = urllib.request.Request(url, method="GET")
|
||||
try:
|
||||
with urllib.request.urlopen(req, context=ctx, timeout=70) as r:
|
||||
raw = r.read()
|
||||
status = r.status
|
||||
except urllib.error.HTTPError as e:
|
||||
raw = e.read()
|
||||
status = e.code
|
||||
except Exception as e:
|
||||
raw = json.dumps({"ok": False, "error": str(e)}).encode()
|
||||
status = 502
|
||||
try:
|
||||
body = json.loads(raw.decode() or "{}")
|
||||
if isinstance(body, dict):
|
||||
body.setdefault("suggested_exchange", EXCHANGE)
|
||||
body.setdefault("required_exchange", EXCHANGE)
|
||||
raw = json.dumps(body).encode()
|
||||
except Exception:
|
||||
pass
|
||||
self.send_response(status)
|
||||
self._cors()
|
||||
self.send_header("Content-Type", "application/json")
|
||||
self.send_header("Content-Length", str(len(raw)))
|
||||
self.end_headers()
|
||||
self.wfile.write(raw)
|
||||
|
||||
def do_GET(self):
|
||||
from urllib.parse import parse_qs, urlparse
|
||||
|
||||
parsed = urlparse(self.path)
|
||||
path = parsed.path
|
||||
qs = parse_qs(parsed.query)
|
||||
try:
|
||||
if path.startswith("/taler-integration/withdrawal-operation/"):
|
||||
self._proxy_wd(parsed)
|
||||
return
|
||||
if path in (
|
||||
"/",
|
||||
"/demo-withdraw.json",
|
||||
"/intro/demo-withdraw.json",
|
||||
):
|
||||
body = mint_withdraw()
|
||||
amt = (qs.get("amount") or qs.get("n") or [None])[0]
|
||||
body = mint_withdraw(amt)
|
||||
elif path in (
|
||||
"/auto-account.json",
|
||||
"/intro/auto-account.json",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue