diff --git a/scripts/taler-monitoring/check_e2e.sh b/scripts/taler-monitoring/check_e2e.sh index 905e85d..05cb5f7 100755 --- a/scripts/taler-monitoring/check_e2e.sh +++ b/scripts/taler-monitoring/check_e2e.sh @@ -237,12 +237,13 @@ except Exception: print("")' 2>/dev/null || true) : "${E2E_VARIABLE:=1}" : "${E2E_ATM_MAX:=5}" if [ "$E2E_REMOTE" = "1" ]; then - # remote: still ATM-shaped but smaller notes; keep cheap - : "${E2E_WITHDRAW_VALUES:=10 20 50}" + # remote: still ATM-shaped; TESTPAYSAN needs larger notes for shop pays if [ "$CUR" = "TESTPAYSAN" ]; then - # match fixed public templates e2e-001 / e2e-005 / e2e-1 - : "${E2E_PAY_VALUES:=0.01 0.05 1}" + : "${E2E_WITHDRAW_VALUES:=20 50}" + # farmer shop template face values (oeufs-6=5, fromage=8.5, jus=6) + : "${E2E_PAY_VALUES:=5 8.5 6}" else + : "${E2E_WITHDRAW_VALUES:=10 20 50}" : "${E2E_PAY_VALUES:=0.01 0.05 0.1 1}" fi else @@ -430,11 +431,58 @@ set_group load section "e2e · load snapshot (before withdraw/pay)" metrics_report_load "${METRICS_DIR}/load-before.json" "e2e-start" || true -# Local stack: koopa secrets. Remote: only explicit env (never leak local passwords to foreign banks). +# Local stack: koopa secrets. Remote: env first; TESTPAYSAN stage may load francpaysan host secrets. set_group prereq if [ "$E2E_REMOTE" = "1" ]; then - ADMIN_PASS="${E2E_BANK_ADMIN_PASS:-}" + ADMIN_PASS="${E2E_BANK_ADMIN_PASS:-${BANK_ADMIN_PASS:-}}" MPW="${E2E_MERCHANT_TOKEN:-${MERCHANT_TOKEN:-}}" + # Stage FrancPaysan: allow admin credit without committing passwords. + # Order: already-set env → local secrets tree → SSH francpaysan-host (ops laptop). + if [ -z "$ADMIN_PASS" ] && [ "${CUR:-${EXPECT_CURRENCY:-}}" = "TESTPAYSAN" ]; then + _fp_try="" + for _fp_try in \ + "${FRANCPAYSAN_SECRETS:-}/stage/bank-admin-password.txt" \ + "${HOME}/francpaysan-secrets/stage/bank-admin-password.txt" \ + "${HOME}/src/francpaysan-secrets/stage/bank-admin-password.txt" \ + "${HOME}/taler/src/francpaysan-secrets/stage/bank-admin-password.txt" + do + if [ -n "$_fp_try" ] && [ -f "$_fp_try" ]; then + ADMIN_PASS=$(tr -d '\n\r' <"$_fp_try") + info "bank admin secret" "from $_fp_try" + break + fi + done + if [ -z "$ADMIN_PASS" ] && command -v ssh >/dev/null 2>&1; then + for _fp_host in "${FRANCPAYSAN_SSH:-francpaysan-host}" francpaysan-host; do + ADMIN_PASS=$(ssh -o BatchMode=yes -o ConnectTimeout=8 "$_fp_host" \ + 'sudo cat /mnt/data/stagepaysan/bank/secrets/bank-admin-password.txt 2>/dev/null' \ + 2>/dev/null | tr -d '\n\r' || true) + if [ -n "$ADMIN_PASS" ]; then + info "bank admin secret" "from ${_fp_host}:/mnt/data/stagepaysan/bank/secrets/" + break + fi + done + fi + unset _fp_try _fp_host + fi + # Stage merchant: public templates need no token; optional default-instance token + if [ -z "$MPW" ] && [ "${CUR:-${EXPECT_CURRENCY:-}}" = "TESTPAYSAN" ]; then + for _fp_try in \ + "${FRANCPAYSAN_SECRETS:-}/stage/default-instance-token.txt" \ + "${HOME}/francpaysan-secrets/stage/default-instance-token.txt" + do + if [ -n "$_fp_try" ] && [ -f "$_fp_try" ]; then + MPW=$(tr -d '\n\r' <"$_fp_try") + break + fi + done + if [ -z "$MPW" ] && command -v ssh >/dev/null 2>&1; then + MPW=$(ssh -o BatchMode=yes -o ConnectTimeout=8 "${FRANCPAYSAN_SSH:-francpaysan-host}" \ + 'sudo cat /mnt/data/stagepaysan/merchant/secrets/default-instance-token.txt 2>/dev/null' \ + 2>/dev/null | tr -d '\n\r' || true) + fi + unset _fp_try + fi else ADMIN_PASS="${E2E_BANK_ADMIN_PASS:-$(read_secret "taler-bank/bank-admin-password.txt" || true)}" MPW="${E2E_MERCHANT_TOKEN:-${MERCHANT_TOKEN:-$(read_secret "taler-merchant/merchant-goa-demo-cp4zqk-password.txt" || true)}}" @@ -977,13 +1025,20 @@ else: return 1 } -# Map CUR:amount → public template id (TESTPAYSAN stage e2e-* templates). -# Override with E2E_TEMPLATE_MAP="0.01=e2e-001 0.05=e2e-005 1=e2e-1" +# Map CUR:amount → public template id. +# GOA default: e2e-* on goa-demo. TESTPAYSAN: farmer shop templates (set in apply_taler_domain). +# Override with E2E_TEMPLATE_MAP="5=oeufs-6 8.5=fromage-chevre" e2e_template_id_for_amount() { local amt="$1" local val map_entry k v val=$(printf '%s' "$amt" | awk -F: '{print $NF}') - : "${E2E_TEMPLATE_MAP:=0.01=e2e-001 0.05=e2e-005 1=e2e-1 1.0=e2e-1}" + if [ -z "${E2E_TEMPLATE_MAP:-}" ]; then + if [ "${CUR:-}" = "TESTPAYSAN" ]; then + E2E_TEMPLATE_MAP="5=oeufs-6 4.5=pain-seigle 6=jus-pomme 8.5=fromage-chevre 12=miel-printemps 25=panier-legumes" + else + E2E_TEMPLATE_MAP="0.01=e2e-001 0.05=e2e-005 1=e2e-1 1.0=e2e-1" + fi + fi for map_entry in $E2E_TEMPLATE_MAP; do k="${map_entry%%=*}" v="${map_entry#*=}" @@ -995,6 +1050,19 @@ e2e_template_id_for_amount() { return 1 } +# Template id → merchant instance (stage farmer shops / GOA goa-shop) +e2e_template_instance_for_id() { + local pid="$1" + case "$pid" in + oeufs-6|pain-seigle|jus-pomme) printf '%s' "jardin-du-creux" ;; + panier-legumes|fromage-chevre|miel-printemps) printf '%s' "fermes-des-collines" ;; + e2e-001|e2e-005|e2e-1|orbit-sticker|nebula-coffee|voidwave-playlist|comet-cap|shuttle-pass|beacon-badge|relay-pin|eclipse-shades|star-chart|rainbow-pill|blue-or-red-pill) + printf '%s' "${E2E_SHOP_INSTANCE:-goa-shop}" + ;; + *) printf '%s' "${MERCHANT_INSTANCE:-default}" ;; + esac +} + # One payment: e2e_one_pay AMOUNT [SUMMARY] [TAG] # SUMMARY defaults to "monitoring pay $AMOUNT"; TAG defaults from amount. # When E2E_USE_TEMPLATES=1 and amount maps to a public template, uses @@ -1155,19 +1223,31 @@ e2e_one_pay_public_template() { local pid="$1" local pname="${2:-$1}" local pamt="$3" + local inst="${4:-}" local tag tag=$(printf 'shop_%s' "$pid" | tr -c 'A-Za-z0-9._-' '_') section "e2e · shop product · $pname ($pid) · $pamt · $(format_amount_alt "$pamt")" e2e_over && { warn "shop $pname" "budget exhausted — skip"; return 1; } metrics_report_coins "before-shop-${tag}" || true + # Resolve instance: explicit arg → template map → global INST + if [ -z "$inst" ]; then + inst=$(e2e_template_instance_for_id "$pid") + fi + [ -n "$inst" ] || inst="${INST:-${MERCHANT_INSTANCE:-default}}" + local MH MH=$(python3 -c 'from urllib.parse import urlparse; print(urlparse("'"$MERCHANT_PUBLIC"'").hostname or "taler.hacktivism.ch")' 2>/dev/null || echo "taler.hacktivism.ch") - local TPL_URI="taler://pay-template/${MH}/instances/${INST}/${pid}" - local TPL_HTTPS="${MERCHANT_PUBLIC}/instances/${INST}/templates/$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$pid")" - info "shop $pname" "pay-template URI $TPL_URI" + local TPL_URI="taler://pay-template/${MH}/instances/${inst}/${pid}" + local TPL_HTTPS="${MERCHANT_PUBLIC}/instances/${inst}/templates/$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=""))' "$pid")" + info "shop $pname" "instance $inst · pay-template URI $TPL_URI" info "shop $pname" "public template POST $TPL_HTTPS" - info "shop $pname" "settlement payto $E2E_SHOP_PAYTO" + # Stage settlement payto: instance bank account; GOA uses E2E_SHOP_PAYTO + local payto_show="${E2E_SHOP_PAYTO:-}" + if [ "${CUR:-}" = "TESTPAYSAN" ]; then + payto_show="payto://x-taler-bank/stage.bank.lefrancpaysan.ch/${inst}" + fi + info "shop $pname" "settlement payto ${payto_show:-(none)}" # Public create (no merchant secret) — same as shop-pay.js curl -skS -m 15 -o "$SCRATCH/tpl-$tag.json" -X POST \ diff --git a/scripts/taler-monitoring/lib.sh b/scripts/taler-monitoring/lib.sh index d0d9bce..3f060a2 100755 --- a/scripts/taler-monitoring/lib.sh +++ b/scripts/taler-monitoring/lib.sh @@ -195,11 +195,22 @@ apply_taler_domain() { CREDIT_AMT="${CREDIT_AMT:-${EXPECT_CURRENCY}:100}" ;; TESTPAYSAN) - # Stage FrancPaysan: default instance + public templates (e2e-001/005/1) - MERCHANT_INSTANCE="${MERCHANT_INSTANCE:-default}" - WITHDRAW_AMT="${WITHDRAW_AMT:-TESTPAYSAN:20}" - PAY_AMT="${PAY_AMT:-TESTPAYSAN:0.01}" - CREDIT_AMT="${CREDIT_AMT:-TESTPAYSAN:100}" + # Stage FrancPaysan: farmer shops (override GOA default goa-demo-cp4zqk) + case "${MERCHANT_INSTANCE:-}" in + ""|goa-demo*|goa-shop) + MERCHANT_INSTANCE=fermes-des-collines + ;; + esac + WITHDRAW_AMT="${WITHDRAW_AMT:-TESTPAYSAN:50}" + PAY_AMT="${PAY_AMT:-TESTPAYSAN:5}" + # Cover oeufs(5)+fromage(8.5)+jus(6)+shop pick(~5–12) + fees + CREDIT_AMT="${CREDIT_AMT:-TESTPAYSAN:200}" + # Public template pays on by default (shops landings) + : "${E2E_USE_TEMPLATES:=1}" + # Map pay-ladder amounts → public shop templates (instance set in e2e) + : "${E2E_TEMPLATE_MAP:=5=oeufs-6 4.5=pain-seigle 6=jus-pomme 8.5=fromage-chevre 12=miel-printemps 25=panier-legumes}" + : "${E2E_PAY_VALUES:=5 8.5 6}" + : "${E2E_WITHDRAW_VALUES:=20 50}" ;; CHF) WITHDRAW_AMT="${WITHDRAW_AMT:-CHF:20}"