#!/bin/bash # Greenfield bootstrap for exchange.hacktivism.ch (GOA exploration currency). # Run as root inside container. Not for daily ops — use start_base + start_exchange. # # Writes: # /etc/taler-exchange/exchange-overrides.conf # /etc/taler-exchange/conf.d/exchange-coins.conf # Ensures main conf inlines exchange-overrides.conf (merchant pattern). # Does NOT use conf.d/zz-*. # # After this: offline denom sign + wire still required for /keys withdraw. set -euo pipefail CONF=/etc/taler-exchange/taler-exchange.conf OV=/etc/taler-exchange/exchange-overrides.conf COINS=/etc/taler-exchange/conf.d/exchange-coins.conf export DEBIAN_FRONTEND=noninteractive if [ "$(id -u)" -ne 0 ]; then echo "Run as root" >&2 exit 1 fi echo "=== 1. postgres ===" /etc/init.d/postgresql start sleep 2 pg_isready || true echo "=== 2. master key (offline user) ===" mkdir -p /var/lib/taler-exchange/offline chown -R taler-exchange-offline:taler-exchange-offline /var/lib/taler-exchange/offline chown taler-exchange-offline:taler-exchange-offline /var/lib/taler-exchange 2>/dev/null || true OUT=$(runuser -u taler-exchange-offline -- taler-exchange-offline -c "$CONF" setup 2>&1) || true echo "$OUT" MASTER_PUB=$(echo "$OUT" | grep -oE '[A-Z0-9]{40,}' | tail -1) if [ -z "${MASTER_PUB:-}" ]; then echo "ERROR: no master public key from offline setup" >&2 exit 1 fi echo "MASTER_PUBLIC_KEY=$MASTER_PUB" ATTR_KEY=$(openssl rand -hex 32) SECRETS_DIR=/etc/taler-exchange/secrets mkdir -p "$SECRETS_DIR" cat >"$SECRETS_DIR/exchange-attribute-encryption.secret.conf" </dev/null || true echo "=== 3. exchange-overrides.conf (site; not zz-*) ===" # Ensure main conf inlines overrides (merchant pattern) if ! grep -q 'exchange-overrides.conf' "$CONF" 2>/dev/null; then printf '\n# Manual site overrides (merchant pattern)\n@inline@ exchange-overrides.conf\n' >>"$CONF" fi # Remove legacy zz drop-ins if present rm -f /etc/taler-exchange/conf.d/zz-hacktivism.conf \ /etc/taler-exchange/conf.d/zz-hacktivism-coins.conf 2>/dev/null || true cat >"$OV" </dev/null; then mv "$COINS" "${COINS}.package-kudos" echo "Moved package coins -> ${COINS}.package-kudos" fi cat >"$COINS" << 'COINS_EOF' # GOA denominations for exchange.hacktivism.ch # Units: 1 GOA = 1000 mGOA = 1_000_000 uGOA # VALUE uses base currency; coin sections cover 1–2–5 ladders at u/m/whole scale. # --- uGOA (10^-6 GOA) --- [coin_goa_0_000001] VALUE = GOA:0.000001 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_000002] VALUE = GOA:0.000002 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_000005] VALUE = GOA:0.000005 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_00001] VALUE = GOA:0.00001 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_00002] VALUE = GOA:0.00002 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_00005] VALUE = GOA:0.00005 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_0001] VALUE = GOA:0.0001 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_0002] VALUE = GOA:0.0002 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_0005] VALUE = GOA:0.0005 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA # --- mGOA (10^-3 GOA) --- [coin_goa_0_001] VALUE = GOA:0.001 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_002] VALUE = GOA:0.002 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_005] VALUE = GOA:0.005 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_01] VALUE = GOA:0.01 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_02] VALUE = GOA:0.02 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_05] VALUE = GOA:0.05 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_1] VALUE = GOA:0.1 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_2] VALUE = GOA:0.2 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_0_5] VALUE = GOA:0.5 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA # --- whole GOA --- [coin_goa_1_0] VALUE = GOA:1 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_2_0] VALUE = GOA:2 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_5_0] VALUE = GOA:5 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_10_0] VALUE = GOA:10 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_20_0] VALUE = GOA:20 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_50_0] VALUE = GOA:50 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_100_0] VALUE = GOA:100 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_200_0] VALUE = GOA:200 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA [coin_goa_1000_0] VALUE = GOA:1000 DURATION_WITHDRAW = 7 days DURATION_SPEND = 2 years DURATION_LEGAL = 3 years FEE_WITHDRAW = GOA:0 FEE_DEPOSIT = GOA:0 FEE_REFRESH = GOA:0 FEE_REFUND = GOA:0 RSA_KEYSIZE = 2048 CIPHER = RSA COINS_EOF echo "Wrote $COINS ($(grep -c '^\[coin_' "$COINS") coin sections)" echo "=== 5. database ===" taler-exchange-dbconfig 2>&1 || true runuser -u taler-exchange-httpd -- taler-exchange-dbinit -c "$CONF" 2>&1 || true echo "=== 6. next steps (manual) ===" echo " - /root/start_base_services_for_taler_exchange.sh # root: secmods + shell as httpd" echo " - ./start_exchange.sh # as taler-exchange-httpd" echo " - offline: sign denominations + wire accounts for /keys" echo " - MASTER_PUBLIC_KEY=$MASTER_PUB" echo "DONE bootstrap"