#!/bin/bash # Auto-confirm bank withdrawals for the community demo pool ONLY. # # Only account: explorer (override only if you really mean another pool user # via BANK_USER, but still confirms with that user's token only — never # confirms other customers' withdrawals). # # Run once: auto-confirm-withdrawals.sh # Loop: auto-confirm-withdrawals.sh --loop [SECS] # # Env: # BANK_URL (default http://127.0.0.1:9012) # BANK_USER (default explorer) — must be the pool account # BANK_PASS or /root/bank-explorer-password.txt # LANDING_DIR (default /var/www/bank-landing) # ALLOW_NON_EXPLORER=1 — allow BANK_USER other than explorer (off by default) set -euo pipefail BANK="${BANK_URL:-http://127.0.0.1:9012}" BANK="${BANK%/}" USER="${BANK_USER:-explorer}" LANDING_DIR="${LANDING_DIR:-/var/www/bank-landing}" LOOP=0 SLEEP=5 if [ "${1:-}" = "--loop" ]; then LOOP=1 SLEEP="${2:-5}" fi # Safety: only the shared community account unless explicitly overridden if [ "$USER" != "explorer" ] && [ "${ALLOW_NON_EXPLORER:-0}" != "1" ]; then echo "refusing BANK_USER=$USER — auto-confirm is for explorer only (set ALLOW_NON_EXPLORER=1 to override)" >&2 exit 1 fi PASS="${BANK_PASS:-}" if [ -z "$PASS" ]; then for f in "/root/bank-${USER}-password.txt" /root/bank-explorer-password.txt; do if [ -f "$f" ]; then PASS=$(tr -d '\n' <"$f"); break; fi done fi [ -n "$PASS" ] || { echo "no password for $USER" >&2; exit 1; } # JSON field extract without python (bank container may lack python3) json_str() { # json_str FIELD < json-text-or-file local field="$1" local data if [ -f "${2:-}" ]; then data=$(cat "$2"); else data=$(cat); fi printf '%s' "$data" | sed -n "s/.*\"${field}\"[[:space:]]*:[[:space:]]*\"\\([^\"]*\\)\".*/\\1/p" | head -1 } token() { curl -sS -m 12 -u "${USER}:${PASS}" \ -H 'Content-Type: application/json' \ -d '{"scope":"readwrite","refreshable":true}' \ "${BANK}/accounts/${USER}/token" } # IDs created for the community pool (landing + watch list only) known_ids() { if [ -f "${LANDING_DIR}/withdraw.uri" ]; then basename "$(tr -d '\n' <"${LANDING_DIR}/withdraw.uri")" fi if [ -f "${LANDING_DIR}/withdraw-watch.ids" ]; then # strip empty / comments grep -E '^[0-9a-fA-F-]{36}$' "${LANDING_DIR}/withdraw-watch.ids" || true fi } confirm_one() { local wid="$1" local tok="$2" local info st uname conf # Public status — must belong to explorer (pool), not another customer info=$(curl -sS -m 10 "${BANK}/withdrawals/${wid}" 2>/dev/null || true) [ -n "$info" ] || return 0 st=$(printf '%s' "$info" | sed -n 's/.*"status"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1) uname=$(printf '%s' "$info" | sed -n 's/.*"username"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1) # Only confirm withdrawals owned by the pool account if [ -n "$uname" ] && [ "$uname" != "$USER" ]; then echo "skip $wid owner=$uname (only confirm $USER)" return 0 fi # If API omits username, still only confirm via explorer token (cannot confirm others) if [ -z "$uname" ]; then # require sender_wire / payto to mention explorer when present case "$info" in *explorer*) ;; *) # still try only if status selected — confirm endpoint is under explorer account ;; esac fi if [ "$st" != "selected" ]; then echo "skip $wid status=${st:-?} owner=${uname:-?}" return 0 fi echo "confirming $wid as $USER (community pool) ..." conf=$(curl -sS -m 15 -o /tmp/acw-conf.out -w '%{http_code}' \ -X POST \ -H "Authorization: Bearer ${tok}" \ -H 'Content-Type: application/json' \ -d '{}' \ "${BANK}/accounts/${USER}/withdrawals/${wid}/confirm") echo " HTTP $conf $(head -c 200 /tmp/acw-conf.out 2>/dev/null || true)" curl -sS -m 8 "${BANK}/withdrawals/${wid}" 2>/dev/null \ | sed -n 's/.*"status"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/ now status=\1/p' | head -1 || true } once() { local tjson tok ids tjson=$(token) tok=$(printf '%s' "$tjson" | sed -n 's/.*"access_token"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' | head -1) if [ -z "$tok" ]; then echo "token fail for $USER: $tjson" >&2 return 1 fi ids=$(known_ids | sort -u) if [ -z "$ids" ]; then echo "no withdrawal ids to watch (landing withdraw.uri / withdraw-watch.ids)" return 0 fi while read -r wid; do [ -n "$wid" ] || continue confirm_one "$wid" "$tok" done <<<"$ids" } if [ "$LOOP" -eq 1 ]; then echo "auto-confirm loop every ${SLEEP}s for pool user=$USER only" while true; do once || true sleep "$SLEEP" done else once fi