350 lines
16 KiB
Bash
Executable file
350 lines
16 KiB
Bash
Executable file
#!/bin/bash
|
|
# Extreme amount tests for GOA: largest practical price vs atomic/tiny coin.
|
|
#
|
|
# Live denoms (exchange.hacktivism.ch): GOA:0.000001 … GOA:10
|
|
# Currency TINY / round unit: GOA:0.00000001 (Atomic-GOA)
|
|
#
|
|
# Run on the local machine (wallet) with ssh BatchMode to koopa for bank/merchant ops.
|
|
# Requires: monorepo taler-wallet-cli, passwords on koopa /root/*-password.txt
|
|
#
|
|
# Usage:
|
|
# ./run-extreme-amount-tests.sh
|
|
# HIGH_AMOUNT=GOA:500 TINY_AMOUNT=GOA:0.000001 ./run-extreme-amount-tests.sh
|
|
set -euo pipefail
|
|
|
|
ROOT=$(cd "$(dirname "$0")/../.." && pwd)
|
|
SCRATCH="${ROOT}/.tmp/extreme-$(date -u +%Y%m%d-%H%M%S)"
|
|
mkdir -p "$SCRATCH"
|
|
chmod 700 "$SCRATCH"
|
|
|
|
MONO="${MONO:-/Users/newkamek/src/taler/taler-typescript-core/packages/taler-wallet-cli/bin/taler-wallet-cli.mjs}"
|
|
WDB="${WDB:-$SCRATCH/wallet.sqlite3}"
|
|
EX="${EXCHANGE_URL:-https://exchange.hacktivism.ch/}"
|
|
KOOPA="${KOOPA_HOST:-koopa}"
|
|
INST="${MERCHANT_INSTANCE:-goa-demo-cp4zqk}"
|
|
BANK_PUBLIC="${BANK_PUBLIC:-https://bank.hacktivism.ch}"
|
|
MER_PUBLIC="${MER_PUBLIC:-https://taler.hacktivism.ch}"
|
|
|
|
# High price: many max-denom (GOA:10) coins. Tiny: smallest issued coin.
|
|
HIGH_AMOUNT="${HIGH_AMOUNT:-GOA:1000}"
|
|
TINY_AMOUNT="${TINY_AMOUNT:-GOA:0.000001}"
|
|
# True atomic (round unit) — may fail if no coin below 1e-6
|
|
ATOMIC_AMOUNT="${ATOMIC_AMOUNT:-GOA:0.00000001}"
|
|
# Fat bank balance for withdraw buffer
|
|
FAT_CREDIT="${FAT_CREDIT:-GOA:50000}"
|
|
FAT_USER="${FAT_USER:-extreme-fat}"
|
|
# withdraw a bit more than HIGH
|
|
WITHDRAW_AMOUNT="${WITHDRAW_AMOUNT:-GOA:1500}"
|
|
|
|
wcli() { node "$MONO" --wallet-db="$WDB" --no-throttle --skip-defaults "$@"; }
|
|
|
|
log() { printf '%s %s\n' "$(date -u +%H:%M:%S)" "$*"; }
|
|
die() { echo "FAIL: $*" >&2; exit 1; }
|
|
|
|
command -v node >/dev/null || die "node missing"
|
|
[ -f "$MONO" ] || die "wallet missing: $MONO"
|
|
ssh -o BatchMode=yes -o ConnectTimeout=10 "$KOOPA" 'echo ok' >/dev/null || die "ssh $KOOPA failed"
|
|
|
|
log "scratch=$SCRATCH"
|
|
log "HIGH=$HIGH_AMOUNT TINY=$TINY_AMOUNT ATOMIC=$ATOMIC_AMOUNT WITHDRAW=$WITHDRAW_AMOUNT FAT=$FAT_USER+$FAT_CREDIT"
|
|
|
|
# --- 1) koopa: bank account + credit + templates + orders ---
|
|
log "=== koopa setup (admin credit, templates, orders) ==="
|
|
# Generate bank password locally (not committed)
|
|
FAT_PW=$(python3 -c 'import secrets; print(secrets.token_urlsafe(12))')
|
|
echo "$FAT_PW" >"$SCRATCH/fat-bank.password"
|
|
chmod 600 "$SCRATCH/fat-bank.password"
|
|
|
|
cat >"$SCRATCH/koopa-setup.sh" <<EOS
|
|
#!/bin/bash
|
|
set +e
|
|
exec > /tmp/extreme-setup.out 2>&1
|
|
set -x
|
|
INST=$INST
|
|
FAT_USER=$FAT_USER
|
|
FAT_PW='$(printf %s "$FAT_PW" | sed "s/'/'\\\\''/g")'
|
|
FAT_CREDIT=$FAT_CREDIT
|
|
HIGH_AMOUNT=$HIGH_AMOUNT
|
|
TINY_AMOUNT=$TINY_AMOUNT
|
|
ATOMIC_AMOUNT=$ATOMIC_AMOUNT
|
|
BANK=http://127.0.0.1:9012
|
|
MER=https://127.0.0.1:9010
|
|
|
|
ADMIN_PASS=\$(tr -d '\\n' </root/bank-admin-password.txt)
|
|
MPW=\$(tr -d '\\n' </root/merchant-\${INST}-password.txt)
|
|
AUTH="Authorization: Bearer secret-token:\${MPW}"
|
|
|
|
# admin token
|
|
AT=\$(curl -sS -u "admin:\${ADMIN_PASS}" -H 'Content-Type: application/json' \\
|
|
-d '{"scope":"readwrite"}' "\${BANK}/accounts/admin/token" \\
|
|
| python3 -c 'import sys,json;print(json.load(sys.stdin).get("access_token",""))')
|
|
[ -n "\$AT" ] || { echo FAIL_admin_token; exit 1; }
|
|
|
|
# create or reuse bank account
|
|
code=\$(curl -sS -o /tmp/acc-create.json -w '%{http_code}' -X POST \\
|
|
-H "Authorization: Bearer \${AT}" -H 'Content-Type: application/json' \\
|
|
-d "{\\"username\\":\\"\${FAT_USER}\\",\\"password\\":\\"\${FAT_PW}\\",\\"name\\":\\"Extreme Fat Wallet\\",\\"is_public\\":false,\\"is_taler_exchange\\":false,\\"debit_threshold\\":\\"GOA:1000000\\"}" \\
|
|
"\${BANK}/accounts")
|
|
echo create_account_http=\$code
|
|
cat /tmp/acc-create.json; echo
|
|
# if exists (409), reset password via admin if possible
|
|
if [ "\$code" != "200" ] && [ "\$code" != "201" ] && [ "\$code" != "204" ]; then
|
|
echo "account may exist; try credit anyway"
|
|
fi
|
|
|
|
# credit from admin (idempotent enough — we just need lots of GOA)
|
|
python3 - <<'PY'
|
|
import json, os, urllib.request, base64
|
|
bank=os.environ.get("BANK","http://127.0.0.1:9012")
|
|
PY
|
|
# use host credit-account if present
|
|
if [ -x /root/koopa-admin-log/scripts/taler-bank/credit-account.sh ]; then
|
|
/root/koopa-admin-log/scripts/taler-bank/credit-account.sh "\$FAT_USER" "\$FAT_CREDIT" || true
|
|
elif [ -x /Users/newkamek/src/koopa/koopa-admin-log/scripts/taler-bank/credit-account.sh ]; then
|
|
true
|
|
else
|
|
# inline credit
|
|
PAYTO="payto://x-taler-bank/bank.hacktivism.ch/\${FAT_USER}?receiver-name=\${FAT_USER}&message=extreme-credit"
|
|
UID=\$(python3 -c 'import os; a="0123456789ABCDEFGHJKMNPQRSTVWXYZ"; b=os.urandom(32); bits=0;v=0;o=[]
|
|
for byte in b:
|
|
v=(v<<8)|byte; bits+=8
|
|
while bits>=5:
|
|
bits-=5; o.append(a[(v>>bits)&31])
|
|
if bits: o.append(a[(v<<(5-bits))&31])
|
|
print("".join(o))')
|
|
curl -sS -H "Authorization: Bearer \${AT}" -H 'Content-Type: application/json' \\
|
|
-d "{\\"payto_uri\\":\\"\${PAYTO}\\",\\"amount\\":\\"\${FAT_CREDIT}\\",\\"request_uid\\":\\"\${UID}\\"}" \\
|
|
"\${BANK}/accounts/admin/transactions" | tee /tmp/credit.out
|
|
echo
|
|
fi
|
|
|
|
# balance
|
|
curl -sS -H "Authorization: Bearer \${AT}" "\${BANK}/accounts/\${FAT_USER}" | tee /tmp/fat-bal.json
|
|
echo
|
|
python3 -c 'import json;d=json.load(open("/tmp/fat-bal.json"));print("FAT_BALANCE", (d.get("balance") or {}).get("amount"), (d.get("balance") or {}).get("credit_debit_indicator"))'
|
|
|
|
# store bank pw for host-side withdraw
|
|
printf '%s' "\$FAT_PW" > /root/bank-\${FAT_USER}-password.txt
|
|
chmod 600 /root/bank-\${FAT_USER}-password.txt
|
|
|
|
# templates
|
|
for id_summary_amount in \\
|
|
"extreme-high|extreme high price|\${HIGH_AMOUNT}" \\
|
|
"extreme-tiny|extreme tiny coin|\${TINY_AMOUNT}" \\
|
|
"extreme-atomic|true atomic round unit|\${ATOMIC_AMOUNT}"
|
|
do
|
|
IFS='|' read -r TID SUM AMT <<<"\$id_summary_amount"
|
|
body=\$(python3 -c "import json; print(json.dumps({
|
|
'template_id': '\$TID',
|
|
'template_description': '\$SUM',
|
|
'editable_defaults': False,
|
|
'template_contract': {
|
|
'summary': '\$SUM',
|
|
'amount': '\$AMT',
|
|
'minimum_age': 0,
|
|
},
|
|
}))")
|
|
# try POST then PATCH
|
|
code=\$(curl -sk -o /tmp/tpl.json -w '%{http_code}' -X POST -H "\$AUTH" -H 'Content-Type: application/json' \\
|
|
-d "\$body" "\${MER}/instances/\${INST}/private/templates")
|
|
echo "template_\$TID post=\$code \$(head -c 120 /tmp/tpl.json)"
|
|
if [ "\$code" = "409" ] || [ "\$code" = "400" ]; then
|
|
curl -sk -X PATCH -H "\$AUTH" -H 'Content-Type: application/json' \\
|
|
-d "\$body" "\${MER}/instances/\${INST}/private/templates/\${TID}" -w " patch=%{http_code}\\n"
|
|
fi
|
|
done
|
|
|
|
# also list templates
|
|
curl -sk -H "\$AUTH" "\${MER}/instances/\${INST}/private/templates" | python3 -m json.tool | head -80
|
|
|
|
# create two firm orders (high + tiny) for deterministic pay URIs
|
|
create_order() {
|
|
local sum="\$1" amt="\$2" tag="\$3"
|
|
curl -sk -X POST -H "\$AUTH" -H 'Content-Type: application/json' \\
|
|
-d "{\\"order\\":{\\"summary\\":\\"\${sum}\\",\\"amount\\":\\"\${amt}\\",\\"fulfillment_message\\":\\"extreme-ok\\"},\\"create_token\\":true}" \\
|
|
"\${MER}/instances/\${INST}/private/orders" > "/tmp/ord-\${tag}.json"
|
|
python3 - "\$tag" <<'PY'
|
|
import json,sys
|
|
tag=sys.argv[1]
|
|
d=json.load(open(f"/tmp/ord-{tag}.json"))
|
|
print(f"ORDER_{tag.upper()}", d.get("order_id"), "token", (d.get("token") or "")[:12])
|
|
open(f"/tmp/oid-{tag}.txt","w").write(d.get("order_id") or "")
|
|
open(f"/tmp/otok-{tag}.txt","w").write(d.get("token") or "")
|
|
PY
|
|
}
|
|
create_order "extreme-high-order" "\$HIGH_AMOUNT" high
|
|
create_order "extreme-tiny-order" "\$TINY_AMOUNT" tiny
|
|
create_order "extreme-atomic-order" "\$ATOMIC_AMOUNT" atomic
|
|
|
|
# create bank integrated withdrawal for fat user
|
|
BT=\$(curl -sS -u "\${FAT_USER}:\${FAT_PW}" -H 'Content-Type: application/json' \\
|
|
-d '{"scope":"readwrite"}' "\${BANK}/accounts/\${FAT_USER}/token" \\
|
|
| python3 -c 'import sys,json;print(json.load(sys.stdin).get("access_token",""))')
|
|
curl -sS -H "Authorization: Bearer \${BT}" -H 'Content-Type: application/json' \\
|
|
-d "{\\"amount\\":\\"\$WITHDRAW_AMOUNT\\",\\"exchange_url\\":\\"https://exchange.hacktivism.ch/\\"}" \\
|
|
"\${BANK}/accounts/\${FAT_USER}/withdrawals" | tee /tmp/wd-create.json
|
|
echo
|
|
python3 - <<'PY'
|
|
import json
|
|
d=json.load(open("/tmp/wd-create.json"))
|
|
wid=d.get("withdrawal_id") or d.get("id")
|
|
uri=d.get("taler_withdraw_uri")
|
|
print("WID", wid)
|
|
print("WURI", uri)
|
|
open("/tmp/wid.txt","w").write(wid or "")
|
|
open("/tmp/wuri.txt","w").write(uri or "")
|
|
PY
|
|
|
|
# publish artifacts for hernani-readable pull
|
|
cp /tmp/oid-*.txt /tmp/otok-*.txt /tmp/wuri.txt /tmp/wid.txt /tmp/fat-bal.json /tmp/extreme-setup.out /home/hernani/ 2>/dev/null || true
|
|
chmod 644 /home/hernani/oid-*.txt /home/hernani/otok-*.txt /home/hernani/wuri.txt /home/hernani/wid.txt 2>/dev/null || true
|
|
|
|
echo SETUP_EXTREME_OK
|
|
EOS
|
|
|
|
# inject WITHDRAW_AMOUNT into script (heredoc already expanded partially - fix)
|
|
# The setup script uses $WITHDRAW_AMOUNT as shell var on koopa - need to export into script
|
|
sed -i.bak "s|\$WITHDRAW_AMOUNT|$WITHDRAW_AMOUNT|g" "$SCRATCH/koopa-setup.sh" 2>/dev/null || \
|
|
sed -i '' "s|\$WITHDRAW_AMOUNT|$WITHDRAW_AMOUNT|g" "$SCRATCH/koopa-setup.sh"
|
|
|
|
scp -o BatchMode=yes "$SCRATCH/koopa-setup.sh" "${KOOPA}:/tmp/extreme-setup.sh"
|
|
# also scp credit-account for reliable credit
|
|
scp -o BatchMode=yes "$ROOT/scripts/taler-bank/credit-account.sh" "${KOOPA}:/tmp/credit-account.sh" || true
|
|
|
|
# run via screen window 0 (root@koopa) — screen-run cannot source local-machine paths
|
|
SESSION=$(screen -ls 2>/dev/null | awk 'match($0, /[0-9]+\.[A-Za-z0-9._-]+/) { print substr($0, RSTART, RLENGTH); exit }')
|
|
[ -n "$SESSION" ] || die "no screen session"
|
|
screen -S "$SESSION" -p 0 -X stuff $'bash /tmp/extreme-setup.sh; chmod 644 /tmp/extreme-setup.out /home/hernani/*.txt 2>/dev/null\n'
|
|
|
|
for i in $(seq 1 90); do
|
|
if ssh -o BatchMode=yes "$KOOPA" 'grep -q SETUP_EXTREME_OK /tmp/extreme-setup.out 2>/dev/null'; then
|
|
log "setup ready @${i}s"
|
|
break
|
|
fi
|
|
sleep 1
|
|
[ "$i" -eq 90 ] && { ssh -o BatchMode=yes "$KOOPA" 'tail -80 /tmp/extreme-setup.out' || true; die "setup timeout"; }
|
|
done
|
|
ssh -o BatchMode=yes "$KOOPA" 'cat /tmp/extreme-setup.out' >"$SCRATCH/koopa-setup.out" || true
|
|
# pull artifacts (hernani-readable)
|
|
scp -o BatchMode=yes "${KOOPA}:/home/hernani/wuri.txt" "${KOOPA}:/home/hernani/wid.txt" \
|
|
"${KOOPA}:/home/hernani/oid-high.txt" "${KOOPA}:/home/hernani/oid-tiny.txt" \
|
|
"${KOOPA}:/home/hernani/oid-atomic.txt" \
|
|
"${KOOPA}:/home/hernani/otok-high.txt" "${KOOPA}:/home/hernani/otok-tiny.txt" \
|
|
"${KOOPA}:/home/hernani/otok-atomic.txt" \
|
|
"$SCRATCH/" 2>/dev/null || true
|
|
|
|
WURI=$(tr -d '\n' <"$SCRATCH/wuri.txt" 2>/dev/null || true)
|
|
WID=$(tr -d '\n' <"$SCRATCH/wid.txt" 2>/dev/null || true)
|
|
OID_HIGH=$(tr -d '\n' <"$SCRATCH/oid-high.txt" 2>/dev/null || true)
|
|
OID_TINY=$(tr -d '\n' <"$SCRATCH/oid-tiny.txt" 2>/dev/null || true)
|
|
OID_ATOMIC=$(tr -d '\n' <"$SCRATCH/oid-atomic.txt" 2>/dev/null || true)
|
|
TOK_HIGH=$(tr -d '\n' <"$SCRATCH/otok-high.txt" 2>/dev/null || true)
|
|
TOK_TINY=$(tr -d '\n' <"$SCRATCH/otok-tiny.txt" 2>/dev/null || true)
|
|
TOK_ATOMIC=$(tr -d '\n' <"$SCRATCH/otok-atomic.txt" 2>/dev/null || true)
|
|
|
|
log "WURI=$WURI"
|
|
log "orders high=$OID_HIGH tiny=$OID_TINY atomic=$OID_ATOMIC"
|
|
[ -n "$WURI" ] || die "no withdraw URI"
|
|
[ -n "$OID_HIGH" ] && [ -n "$OID_TINY" ] || die "orders missing"
|
|
|
|
# ensure auto-confirm watches this withdrawal
|
|
ssh -o BatchMode=yes "$KOOPA" "echo $WID >> /var/www/bank-landing/withdraw-watch.ids 2>/dev/null; sort -u /var/www/bank-landing/withdraw-watch.ids -o /var/www/bank-landing/withdraw-watch.ids 2>/dev/null; true"
|
|
# root confirm via screen
|
|
screen -S "$SESSION" -p 0 -X stuff $'BPW=$(tr -d "\\n" </root/bank-'"$FAT_USER"'-password.txt); BT=$(curl -sS -u "'"$FAT_USER"':${BPW}" -H "Content-Type: application/json" -d "{\"scope\":\"readwrite\"}" http://127.0.0.1:9012/accounts/'"$FAT_USER"'/token | python3 -c "import sys,json;print(json.load(sys.stdin).get(\"access_token\",\"\"))"); curl -sS -X POST -H "Authorization: Bearer ${BT}" http://127.0.0.1:9012/accounts/'"$FAT_USER"'/withdrawals/'"$WID"'/confirm; echo CONF_DONE\n'
|
|
|
|
# --- 2) wallet withdraw ---
|
|
log "=== wallet: add exchange + ToS ==="
|
|
wcli exchanges add "$EX" 2>&1 | tee "$SCRATCH/ex-add.out" || true
|
|
wcli exchanges update "$EX" 2>&1 | tee "$SCRATCH/ex-upd.out" || true
|
|
wcli exchanges tos "$EX" 2>&1 | tee "$SCRATCH/ex-tos.out" || true
|
|
wcli exchanges accept-tos "$EX" 2>&1 | tee "$SCRATCH/ex-accept.out" || true
|
|
|
|
log "=== withdraw accept-uri ==="
|
|
wcli withdraw accept-uri --exchange "$EX" "$WURI" 2>&1 | tee "$SCRATCH/accept-uri.out" || true
|
|
|
|
for round in $(seq 1 20); do
|
|
log "run-until-done round $round"
|
|
wcli run-until-done 2>&1 | tee -a "$SCRATCH/rud.out" || true
|
|
wcli balance 2>&1 | tee "$SCRATCH/bal-$round.out"
|
|
if grep -qE "GOA:" "$SCRATCH/bal-$round.out"; then
|
|
# check non-zero available
|
|
if python3 -c 'import re,sys; t=open(sys.argv[1]).read();
|
|
m=re.search(r"available[^0-9A-Z]*GOA:([0-9.]+)", t)
|
|
print(m.group(1) if m else ""); sys.exit(0 if m and float(m.group(1))>0 else 1)' "$SCRATCH/bal-$round.out" 2>/dev/null; then
|
|
log "coins available"
|
|
break
|
|
fi
|
|
fi
|
|
# re-confirm withdraw on bank
|
|
screen -S "$SESSION" -p 0 -X stuff $'BPW=$(tr -d "\\n" </root/bank-'"$FAT_USER"'-password.txt); BT=$(curl -sS -u "'"$FAT_USER"':${BPW}" -H "Content-Type: application/json" -d "{\"scope\":\"readwrite\"}" http://127.0.0.1:9012/accounts/'"$FAT_USER"'/token | python3 -c "import sys,json;print(json.load(sys.stdin).get(\"access_token\",\"\"))"); curl -sS -X POST -H "Authorization: Bearer ${BT}" http://127.0.0.1:9012/accounts/'"$FAT_USER"'/withdrawals/'"$WID"'/confirm 2>/dev/null; echo\n'
|
|
sleep 3
|
|
done
|
|
|
|
wcli balance 2>&1 | tee "$SCRATCH/balance-after-withdraw.out"
|
|
wcli transactions 2>&1 | tee "$SCRATCH/tx-after-withdraw.out" | head -100
|
|
|
|
# --- 3) pay high + tiny (+ try atomic) ---
|
|
pay_order() {
|
|
local tag="$1" oid="$2" tok="$3"
|
|
local uri="taler://pay/taler.hacktivism.ch/instances/${INST}/${oid}/?c=${tok}"
|
|
echo "$uri" >"$SCRATCH/pay-${tag}.uri"
|
|
log "=== pay $tag order=$oid ==="
|
|
log "uri=$uri"
|
|
wcli handle-uri "$uri" 2>&1 | tee "$SCRATCH/pay-${tag}-handle.out" || true
|
|
# some wallets use payments prepare/confirm
|
|
wcli run-until-done 2>&1 | tee -a "$SCRATCH/pay-${tag}-rud.out" || true
|
|
# check merchant
|
|
ssh -o BatchMode=yes "$KOOPA" "MPW=\$(tr -d '\\n' </root/merchant-${INST}-password.txt); curl -sk -H \"Authorization: Bearer secret-token:\${MPW}\" https://127.0.0.1:9010/instances/${INST}/private/orders/${oid}" \
|
|
>"$SCRATCH/order-${tag}-status.json" 2>/dev/null || true
|
|
python3 - "$SCRATCH/order-${tag}-status.json" "$tag" <<'PY' || true
|
|
import json,sys
|
|
p,tag=sys.argv[1],sys.argv[2]
|
|
try:
|
|
d=json.load(open(p))
|
|
except Exception as e:
|
|
print(f"STATUS_{tag} unreadable", e); raise SystemExit
|
|
print(f"STATUS_{tag}", "order_status=", d.get("order_status"), "paid=", d.get("paid"),
|
|
"wired=", d.get("wired"), "deposit_total=", d.get("deposit_total"),
|
|
"amount=", (d.get("contract_terms") or {}).get("amount"))
|
|
PY
|
|
}
|
|
|
|
pay_order high "$OID_HIGH" "$TOK_HIGH"
|
|
wcli balance 2>&1 | tee "$SCRATCH/balance-after-high.out"
|
|
|
|
pay_order tiny "$OID_TINY" "$TOK_TINY"
|
|
wcli balance 2>&1 | tee "$SCRATCH/balance-after-tiny.out"
|
|
|
|
if [ -n "$OID_ATOMIC" ] && [ -n "$TOK_ATOMIC" ]; then
|
|
pay_order atomic "$OID_ATOMIC" "$TOK_ATOMIC" || true
|
|
wcli balance 2>&1 | tee "$SCRATCH/balance-after-atomic.out" || true
|
|
fi
|
|
|
|
# template URIs for docs
|
|
{
|
|
echo "taler://pay-template/taler.hacktivism.ch/instances/${INST}/extreme-high/"
|
|
echo "taler://pay-template/taler.hacktivism.ch/instances/${INST}/extreme-tiny/"
|
|
echo "taler://pay-template/taler.hacktivism.ch/instances/${INST}/extreme-atomic/"
|
|
} | tee "$SCRATCH/template-uris.txt"
|
|
|
|
log "=== summary ==="
|
|
python3 - <<PY
|
|
import json,glob,os
|
|
scratch="$SCRATCH"
|
|
print("scratch", scratch)
|
|
for tag in ("high","tiny","atomic"):
|
|
p=f"{scratch}/order-{tag}-status.json"
|
|
if not os.path.isfile(p):
|
|
print(tag, "no status file"); continue
|
|
try:
|
|
d=json.load(open(p))
|
|
print(tag, "paid=", d.get("paid"), "status=", d.get("order_status"),
|
|
"amount=", (d.get("contract_terms") or {}).get("amount"),
|
|
"deposit_total=", d.get("deposit_total"))
|
|
except Exception as e:
|
|
print(tag, "err", e)
|
|
print("template_uris:")
|
|
print(open(f"{scratch}/template-uris.txt").read())
|
|
PY
|
|
|
|
log "done — details in $SCRATCH"
|