koopa-admin-log/scripts/taler-bank/credit-account.sh

96 lines
3.1 KiB
Bash
Executable file

#!/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'))
"