bank: demo withdraw/credit helpers (container; no public landing yet)
This commit is contained in:
parent
cd3ffadcde
commit
96f0943319
4 changed files with 365 additions and 0 deletions
96
scripts/taler-bank/credit-account.sh
Executable file
96
scripts/taler-bank/credit-account.sh
Executable file
|
|
@ -0,0 +1,96 @@
|
|||
#!/bin/bash
|
||||
# Credit a bank user by transferring from admin (creates regional GOA via admin debit).
|
||||
# Run as root on koopa host (bank on 127.0.0.1:9012).
|
||||
#
|
||||
# Usage:
|
||||
# credit-account.sh [USERNAME] [AMOUNT]
|
||||
# credit-account.sh explorer GOA:1000
|
||||
set -euo pipefail
|
||||
|
||||
BANK="${BANK_URL:-http://127.0.0.1:9012}"
|
||||
TO_USER="${1:-explorer}"
|
||||
AMOUNT="${2:-GOA:1000}"
|
||||
ADMIN_PASS="${BANK_ADMIN_PASS:-}"
|
||||
if [ -z "$ADMIN_PASS" ] && [ -f /root/bank-admin-password.txt ]; then
|
||||
ADMIN_PASS=$(tr -d '\n' </root/bank-admin-password.txt)
|
||||
fi
|
||||
[ -n "$ADMIN_PASS" ] || { echo "Need BANK_ADMIN_PASS or /root/bank-admin-password.txt" >&2; exit 1; }
|
||||
|
||||
W=$(mktemp -d)
|
||||
trap 'rm -rf "$W"' EXIT
|
||||
|
||||
echo '{"scope":"readwrite"}' >"$W/tok.json"
|
||||
curl -sS -m 15 -u "admin:${ADMIN_PASS}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d @"$W/tok.json" \
|
||||
"${BANK}/accounts/admin/token" >"$W/tok.out"
|
||||
TOKEN=$(python3 -c "import json;print(json.load(open('$W/tok.out')).get('access_token',''))")
|
||||
[ -n "$TOKEN" ] || { echo "admin token failed:"; cat "$W/tok.out"; exit 1; }
|
||||
|
||||
# payto for x-taler-bank regional accounts
|
||||
PAYTO="payto://x-taler-bank/bank.hacktivism.ch/${TO_USER}?receiver-name=${TO_USER}&message=credit-from-admin"
|
||||
|
||||
python3 - "$AMOUNT" "$PAYTO" "$W/tx.json" <<'PY'
|
||||
import json, sys, os
|
||||
amount, payto, out = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||
# ShortHashCode: Crockford base32 of 32 random bytes (52 chars)
|
||||
_ALPH = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
|
||||
def crockford32(data: bytes) -> str:
|
||||
n = int.from_bytes(data, "big")
|
||||
bits = len(data) * 8
|
||||
outc = []
|
||||
while bits > 0:
|
||||
bits -= 5
|
||||
outc.append(_ALPH[(n >> bits) & 31] if bits >= 0 else _ALPH[(n << (-bits)) & 31])
|
||||
if bits <= 0:
|
||||
break
|
||||
# pad to full groups
|
||||
s = "".join(outc)
|
||||
# simpler bit stream
|
||||
return None
|
||||
def crock32(b: bytes) -> str:
|
||||
bits = 0
|
||||
val = 0
|
||||
outc = []
|
||||
for byte in b:
|
||||
val = (val << 8) | byte
|
||||
bits += 8
|
||||
while bits >= 5:
|
||||
bits -= 5
|
||||
outc.append(_ALPH[(val >> bits) & 31])
|
||||
if bits:
|
||||
outc.append(_ALPH[(val << (5 - bits)) & 31])
|
||||
return "".join(outc)
|
||||
uid = crock32(os.urandom(32))
|
||||
json.dump({"payto_uri": payto, "amount": amount, "request_uid": uid}, open(out, "w"))
|
||||
print("request_uid", uid, "len", len(uid))
|
||||
PY
|
||||
|
||||
echo "POST admin -> $TO_USER amount=$AMOUNT"
|
||||
curl -sS -m 15 \
|
||||
-H "Authorization: Bearer ${TOKEN}" \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d @"$W/tx.json" \
|
||||
"${BANK}/accounts/admin/transactions" | tee "$W/tx.out"
|
||||
echo
|
||||
|
||||
# show balances
|
||||
for u in admin "$TO_USER"; do
|
||||
curl -sS -m 10 -u "admin:${ADMIN_PASS}" \
|
||||
-H 'Content-Type: application/json' -d '{"scope":"readonly"}' \
|
||||
"${BANK}/accounts/admin/token" >"$W/rtok" 2>/dev/null || true
|
||||
done
|
||||
|
||||
# re-token readonly and print target balance
|
||||
echo '{"scope":"readonly"}' >"$W/rtok.json"
|
||||
# admin can GET any account
|
||||
curl -sS -m 10 -H "Authorization: Bearer ${TOKEN}" \
|
||||
"${BANK}/accounts/${TO_USER}" | tee "$W/acc.out"
|
||||
echo
|
||||
python3 -c "
|
||||
import json
|
||||
d=json.load(open('$W/acc.out'))
|
||||
b=d.get('balance') or {}
|
||||
print('RESULT', '${TO_USER}', 'balance=', b.get('amount'), b.get('credit_debit_indicator'))
|
||||
print('debit_threshold=', d.get('debit_threshold'))
|
||||
"
|
||||
Loading…
Add table
Add a link
Reference in a new issue