exchange

Base system with REST service to issue digital coins, run by the payment service provider
Log | Files | Refs | Submodules | README | LICENSE

taler-unified-setup.sh (31441B)


      1 #!/usr/bin/env bash
      2 #
      3 # This file is part of TALER
      4 # Copyright (C) 2023, 2024 Taler Systems SA
      5 #
      6 # TALER is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as
      8 # published by the Free Software Foundation; either version 3, or
      9 # (at your option) any later version.
     10 #
     11 # TALER is distributed in the hope that it will be useful, but
     12 # WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public
     17 # License along with TALER; see the file COPYING.  If not, see
     18 # <http://www.gnu.org/licenses/>
     19 #
     20 # Author: Christian Grothoff
     21 #
     22 # This script configures and launches various GNU Taler services. Which ones
     23 # depend on command-line options. Use "-h" to find out. Prints
     24 # "READY:$TEST_ROOT" on a separate line once all requested services are
     25 # running. Close STDIN (or input 'NEWLINE') to stop all started services again.
     26 #
     27 # This script must *only* write output to stderr, as stdout is used to for
     28 # structured communication with the parent process.
     29 #
     30 # shellcheck disable=SC2317
     31 
     32 set -eu
     33 
     34 if [[ ${TALER_TEST_VERBOSE:-0} -ge 1 ]]; then
     35   set -x
     36 fi
     37 
     38 # These break TALER_HOME control via TALER_TEST_HOME...
     39 unset XDG_DATA_HOME
     40 unset XDG_CONFIG_HOME
     41 unset XDG_CACHE_HOME
     42 
     43 EXIT_STATUS=2
     44 
     45 # Exit, with status code "skip" (no 'real' failure)
     46 function exit_skip() {
     47     echo " SKIP: " "$@" >&2
     48     EXIT_STATUS=77
     49     exit "$EXIT_STATUS"
     50 }
     51 
     52 # Exit, with error message (hard failure)
     53 function exit_fail() {
     54     echo " FAIL: " "$@" >&2
     55     EXIT_STATUS=1
     56     exit "$EXIT_STATUS"
     57 }
     58 
     59 # Cleanup to run whenever we exit
     60 function cleanup()
     61 {
     62     echo "Taler unified setup terminating at $STAGE!" >&2
     63 
     64     for n in $(jobs -p)
     65     do
     66         kill "$n" 2> /dev/null || true
     67     done
     68     wait
     69     rm -f libeufin-nexus.pid libeufin-sandbox.pid
     70     exit "$EXIT_STATUS"
     71 }
     72 
     73 STAGE="boot"
     74 
     75 # Install cleanup handler (except for kill -9)
     76 trap cleanup EXIT
     77 
     78 WAIT_FOR_SIGNAL=0
     79 START_AUDITOR=0
     80 START_BACKUP=0
     81 START_EXCHANGE=0
     82 START_FAKEBANK=0
     83 START_DONAU=0
     84 START_CHALLENGER=0
     85 START_AGGREGATOR=0
     86 START_MERCHANT=0
     87 START_MERCHANT_WEBHOOK=1
     88 START_NEXUS=0
     89 START_BANK=0
     90 START_TRANSFER=0
     91 START_WIREWATCH=0
     92 START_DEPOSITCHECK=0
     93 START_MERCHANT_EXCHANGE=0
     94 START_MERCHANT_WIREWATCH=0
     95 START_MERCHANT_DONAUKEYUPDATE=0
     96 USE_ACCOUNT="exchange-account-1"
     97 USE_VALGRIND=""
     98 WIRE_DOMAIN="x-taler-bank"
     99 CONF_ORIG="$HOME/.config/taler.conf"
    100 LOGLEVEL="DEBUG"
    101 DEFAULT_SLEEP="0.5"
    102 
    103 # Parse command-line options
    104 while getopts ':abc:d:DeEfghHkL:mMnr:stu:vwWzZ' OPTION; do
    105     case "$OPTION" in
    106         a)
    107             START_AUDITOR="1"
    108             ;;
    109         b)
    110             START_BANK="1"
    111             ;;
    112         c)
    113             CONF_ORIG="$OPTARG"
    114             ;;
    115         d)
    116             WIRE_DOMAIN="$OPTARG"
    117             ;;
    118         D)
    119             START_DONAU="1"
    120             ;;
    121         e)
    122             START_EXCHANGE="1"
    123             ;;
    124         E)
    125             START_MERCHANT_EXCHANGE="1"
    126             ;;
    127         f)
    128             START_FAKEBANK="1"
    129             ;;
    130         h)
    131             echo 'Supported options:'
    132             echo '  -a           -- start auditor'
    133             echo '  -b           -- start bank'
    134             # shellcheck disable=SC2016
    135             echo '  -c $CONF     -- set configuration'
    136             # shellcheck disable=SC2016
    137             echo '  -d $METHOD   -- use wire method (default: x-taler-bank)'
    138             echo '  -D           -- start donau'
    139             echo '  -e           -- start exchange'
    140             echo '  -E           -- start taler-merchant-exchange'
    141             echo '  -f           -- start fakebank'
    142             echo '  -g           -- start taler-exchange-aggregator'
    143             echo '  -h           -- print this help'
    144             echo '  -H           -- suppress the merchant webhook worker (with -m)'
    145             echo '  -k           -- start challenger (KYC service)'
    146             # shellcheck disable=SC2016
    147             echo '  -L $LOGLEVEL -- set log level'
    148             echo '  -m           -- start taler-merchant'
    149             echo '  -M           -- start taler-merchant-depositcheck'
    150             echo '  -n           -- start nexus'
    151             # shellcheck disable=SC2016
    152             echo '  -r $MEX      -- which exchange to use at the merchant (optional)'
    153             echo '  -s           -- start backup/sync'
    154             echo '  -S $SLEEP    -- set default sleep time between retries'
    155             echo '  -t           -- start taler-exchange-transfer'
    156             # shellcheck disable=SC2016
    157             echo '  -u $SECTION  -- exchange account to use'
    158             echo '  -v           -- use valgrind'
    159             echo '  -w           -- start taler-exchange-wirewatch'
    160             echo '  -W           -- wait for signal'
    161             echo '  -z           -- start taler-merchant-wirewatch'
    162             echo '  -Z           -- start taler-merchant-donaukeyupdate'
    163             exit 0
    164             ;;
    165         H)
    166             START_MERCHANT_WEBHOOK=0
    167             ;;
    168         g)
    169             START_AGGREGATOR="1"
    170             ;;
    171         k)
    172             START_CHALLENGER="1"
    173             ;;
    174         L)
    175             LOGLEVEL="$OPTARG"
    176             ;;
    177         m)
    178             START_MERCHANT="1"
    179             ;;
    180         M)
    181             START_DEPOSITCHECK="1"
    182             ;;
    183         n)
    184             START_NEXUS="1"
    185             ;;
    186         r)
    187             USE_MERCHANT_EXCHANGE="$OPTARG"
    188             ;;
    189         s)
    190             START_BACKUP="1"
    191             ;;
    192         S)
    193             DEFAULT_SLEEP="$OPTARG"
    194             ;;
    195         t)
    196             START_TRANSFER="1"
    197             ;;
    198         u)
    199             USE_ACCOUNT="$OPTARG"
    200             ;;
    201         v)
    202             USE_VALGRIND="valgrind --leak-check=yes"
    203             DEFAULT_SLEEP="2"
    204             ;;
    205         w)
    206             START_WIREWATCH="1"
    207             ;;
    208         W)
    209             WAIT_FOR_SIGNAL="1"
    210             ;;
    211         z)
    212             START_MERCHANT_WIREWATCH="1"
    213             ;;
    214         Z)
    215             START_MERCHANT_DONAUKEYUPDATE="1"
    216             ;;
    217         ?)
    218         exit_fail "Unrecognized command line option"
    219         ;;
    220     esac
    221 done
    222 
    223 STAGE="init"
    224 
    225 
    226 TESTROOT=$(mktemp --tmpdir -d taler-testing-XXXXXX)
    227 
    228 echo "Starting with configuration file at: $CONF_ORIG" >&2
    229 CONF="$CONF_ORIG.edited"
    230 cp "${CONF_ORIG}" "${CONF}"
    231 
    232 STAGE="checks"
    233 
    234 echo -n "Testing for jq" >&2
    235 jq -h > /dev/null || exit_skip " jq required"
    236 echo " FOUND" >&2
    237 
    238 echo -n "Testing for wget" >&2
    239 wget --help > /dev/null || exit_skip " wget required" >&2
    240 echo " FOUND" >&2
    241 
    242 if [ "1" = "$START_EXCHANGE" ]
    243 then
    244     echo -n "Testing for Taler exchange" >&2
    245     taler-exchange-httpd -h > /dev/null || exit_skip " taler-exchange-httpd required"
    246     echo " FOUND" >&2
    247 fi
    248 
    249 if [ "1" = "$START_DONAU" ]
    250 then
    251     echo -n "Testing for Donau" >&2
    252     donau-httpd -h > /dev/null || exit_skip " donau-httpd required"
    253     echo " FOUND" >&2
    254 fi
    255 
    256 if [ "1" = "$START_MERCHANT" ]
    257 then
    258     echo -n "Testing for Taler merchant" >&2
    259     taler-merchant-httpd -h > /dev/null || exit_skip " taler-merchant-httpd required"
    260     echo " FOUND" >&2
    261 fi
    262 
    263 if [ "1" = "$START_CHALLENGER" ]
    264 then
    265     echo -n "Testing for Taler challenger" >&2
    266     challenger-httpd -h > /dev/null || exit_skip " challenger-httpd required"
    267     echo " FOUND" >&2
    268 fi
    269 
    270 if [ "1" = "$START_BACKUP" ]
    271 then
    272     echo -n "Testing for sync-httpd" >&2
    273     sync-httpd -h > /dev/null || exit_skip " sync-httpd required"
    274     echo " FOUND" >&2
    275 fi
    276 
    277 if [ "1" = "$START_NEXUS" ]
    278 then
    279     echo -n "Testing for libeufin-nexus" >&2
    280     libeufin-nexus --help >/dev/null </dev/null || exit_skip " MISSING"
    281     echo " FOUND" >&2
    282 fi
    283 
    284 if [ "1" = "$START_BANK" ]
    285 then
    286     echo -n "Testing for libeufin-bank" >&2
    287     libeufin-bank --help >/dev/null </dev/null || exit_skip " MISSING"
    288     echo " FOUND" >&2
    289 fi
    290 
    291 STAGE="config"
    292 
    293 if [ "1" = "$START_EXCHANGE" ]
    294 then
    295     CURRENCY=$(taler-exchange-config -c "$CONF" -s "EXCHANGE" -o "CURRENCY")
    296 else
    297     if [ "1" = "$START_DONAU" ]
    298     then
    299         CURRENCY=$(donau-config -c "$CONF" -s "DONAU" -o "CURRENCY")
    300     else
    301         if [ "1" = "$START_BANK" ]
    302         then
    303             # Note: would be nice to have libeufin-config in the future...
    304             CURRENCY=$(taler-exchange-config -c "$CONF" -s "libeufin-bank" -o "CURRENCY")
    305         else
    306             CURRENCY="UNKNOWN"
    307         fi
    308     fi
    309 fi
    310 
    311 echo "Setting up for $CURRENCY" >&2
    312 
    313 register_bank_account() {
    314     wget \
    315         --http-user="$AUSER" \
    316         --http-password="$APASS" \
    317         --method=DELETE \
    318         -o /dev/null \
    319         -O /dev/null \
    320         -a wget-delete-account.log \
    321         "http://localhost:${BANK_PORT}/accounts/$1" \
    322         || true # deletion may fail, that's OK!
    323     if [ "$1" = "exchange" ] || [ "$1" = "Exchange" ]
    324     then
    325         IS_EXCHANGE="true"
    326     else
    327         IS_EXCHANGE="false"
    328     fi
    329     MAYBE_IBAN="${4:-}"
    330     if [ -n "$MAYBE_IBAN" ]
    331     then
    332         # shellcheck disable=SC2001
    333         ENAME=$(echo "$3" | sed -e "s/ /+/g")
    334         if [ "$WIRE_DOMAIN" = "x-taler-bank" ]
    335         then
    336             # hostname
    337             OPERATOR="localhost"
    338             MAYBE_IBAN="$1"
    339             PAYTO="payto://${WIRE_DOMAIN}/${OPERATOR}/${MAYBE_IBAN}?receiver-name=$ENAME"
    340         else
    341             PAYTO="payto://${WIRE_DOMAIN}/${MAYBE_IBAN}?receiver-name=$ENAME"
    342         fi
    343         BODY='{"username":"'"$1"'","password":"'"$2"'","is_taler_exchange":'"$IS_EXCHANGE"',"name":"'"$3"'","payto_uri":"'"$PAYTO"'"}'
    344     else
    345         BODY='{"username":"'"$1"'","password":"'"$2"'","is_taler_exchange":'"$IS_EXCHANGE"',"name":"'"$3"'"}'
    346     fi
    347     wget \
    348         --http-user="$AUSER" \
    349         --http-password="$APASS" \
    350         --method=POST \
    351         --header='Content-type: application/json' \
    352         --body-data="${BODY}" \
    353         -o /dev/null \
    354         -O /dev/null \
    355         -a wget-register-account.log \
    356         "http://localhost:${BANK_PORT}/accounts"
    357 }
    358 
    359 register_fakebank_account() {
    360     if [ "$1" = "exchange" ] || [ "$1" = "Exchange" ]
    361     then
    362         IS_EXCHANGE="true"
    363     else
    364         IS_EXCHANGE="false"
    365     fi
    366     BODY='{"username":"'"$1"'","password":"'"$2"'","name":"'"$1"'","is_taler_exchange":'"$IS_EXCHANGE"'}'
    367     wget \
    368         --post-data="$BODY" \
    369         --header='Content-type: application/json' \
    370         --tries=3 \
    371         --waitretry=1 \
    372         --timeout=30 \
    373         "http://localhost:$BANK_PORT/accounts" \
    374         -a wget-register-account.log \
    375         -o /dev/null \
    376         -O /dev/null \
    377         >/dev/null
    378 }
    379 
    380 
    381 if [[ "1" = "$START_BANK" ]]
    382 then
    383     BANK_PORT=$(taler-exchange-config -c "$CONF" -s "libeufin-bank" -o "PORT")
    384     BANK_URL="http://localhost:${BANK_PORT}/"
    385 fi
    386 
    387 if [[ "1" = "$START_FAKEBANK" ]]
    388 then
    389     BANK_PORT=$(taler-exchange-config -c "$CONF" -s "BANK" -o "HTTP_PORT")
    390     BANK_URL="http://localhost:${BANK_PORT}/"
    391 fi
    392 
    393 STAGE="bank"
    394 
    395 if [ "1" = "$START_BANK" ]
    396 then
    397     echo -n "Setting up bank database ... " >&2
    398     libeufin-bank dbinit \
    399         -r \
    400         -c "$CONF" \
    401         -L "$LOGLEVEL" \
    402         &> libeufin-bank-reset.log
    403     echo "DONE" >&2
    404     echo -n "Launching bank ... " >&2
    405     libeufin-bank serve \
    406       -c "$CONF" \
    407       -L "$LOGLEVEL" \
    408       > libeufin-bank-stdout.log \
    409       2> libeufin-bank-stderr.log &
    410     echo $! > libeufin-bank.pid
    411     echo "DONE" >&2
    412     echo -n "Waiting for Bank ..." >&2
    413     OK="0"
    414     for n in $(seq 1 100); do
    415         echo -n "." >&2
    416         sleep "$DEFAULT_SLEEP"
    417         wget --timeout=1 \
    418              --tries=3 \
    419              --waitretry=0 \
    420              -a wget-bank-check.log \
    421              -o /dev/null \
    422              -O /dev/null \
    423              "${BANK_URL}config" || continue
    424         OK="1"
    425         break
    426     done
    427     if [ "1" != "$OK" ]
    428     then
    429         exit_skip "Failed to launch services (bank)" >&2
    430     fi
    431     echo "OK" >&2
    432     echo -n "Set admin password..." >&2
    433     AUSER="admin"
    434     APASS="secret-password"
    435     libeufin-bank \
    436       passwd \
    437       -c "$CONF" \
    438       -L "$LOGLEVEL" \
    439       "$AUSER" "$APASS" \
    440       &> libeufin-bank-passwd.log
    441     libeufin-bank \
    442       edit-account \
    443       -c "$CONF" \
    444       -L "$LOGLEVEL" \
    445       --debit_threshold="$CURRENCY:1000000" \
    446       "$AUSER" \
    447       &> libeufin-bank-debit-threshold.log
    448     echo " OK" >&2
    449 fi
    450 
    451 if [ "1" = "$START_NEXUS" ]
    452 then
    453     echo "Nexus currently not supported ..." >&2
    454 fi
    455 
    456 if [ "1" = "$START_FAKEBANK" ]
    457 then
    458     echo -n "Setting up fakebank ..." >&2
    459     $USE_VALGRIND taler-fakebank-run \
    460                   -c "$CONF" \
    461                   -L "$LOGLEVEL" \
    462                   -n 4 \
    463                   2> taler-fakebank-run.log &
    464     echo " OK" >&2
    465 fi
    466 
    467 if [[ "1" = "$START_BANK" || "1" = "$START_FAKEBANK" ]]
    468 then
    469     echo -n "Waiting for the bank" >&2
    470     # Wait for bank to be available (usually the slowest)
    471     OK="0"
    472     for n in $(seq 1 300)
    473     do
    474         echo -n "." >&2
    475         sleep "$DEFAULT_SLEEP"
    476         # bank
    477         wget --tries=1 \
    478              --waitretry=0 \
    479              --timeout=1 \
    480              --user admin \
    481              --password secret \
    482              -a wget-bank-check.log \
    483              -o /dev/null \
    484              -O /dev/null \
    485              "http://localhost:${BANK_PORT}/" || continue
    486         OK="1"
    487         break
    488     done
    489     if [ "1" != "$OK" ]
    490     then
    491         exit_skip "Failed to launch services (bank)"
    492     fi
    493     echo " OK" >&2
    494 fi
    495 
    496 STAGE="accounts"
    497 
    498 if [ "1" = "$START_FAKEBANK" ]
    499 then
    500     echo -n "Register Fakebank users ..." >&2
    501     register_fakebank_account fortytwo password
    502     register_fakebank_account fortythree password
    503     register_fakebank_account exchange password
    504     register_fakebank_account tor password
    505     register_fakebank_account gnunet password
    506     register_fakebank_account tutorial password
    507     register_fakebank_account survey password
    508     echo " DONE" >&2
    509 fi
    510 
    511 if [ "1" = "$START_BANK" ]
    512 then
    513     echo -n "Register bank users ..." >&2
    514     # The specified IBAN and name must match the ones hard-coded into
    515     # the C helper for the add-incoming call.  Without this value,
    516     # libeufin-bank  won't find the target account to debit along a /add-incoming
    517     # call.
    518     register_bank_account fortytwo password "User42" FR7630006000011234567890189
    519     register_bank_account fortythree password "Forty Three"
    520     register_bank_account exchange password "Exchange Company" DE89370400440532013000
    521     register_bank_account tor password "Tor Project"
    522     register_bank_account gnunet password "GNUnet"
    523     register_bank_account tutorial password "Tutorial"
    524     register_bank_account survey password "Survey"
    525     echo " DONE" >&2
    526 fi
    527 
    528 STAGE="exchange"
    529 
    530 if [ "1" = "$START_EXCHANGE" ]
    531 then
    532     echo -n "Starting exchange ..." >&2
    533     EXCHANGE_PORT=$(taler-exchange-config -c "$CONF" -s EXCHANGE -o PORT)
    534     SERVE=$(taler-exchange-config -c "$CONF" -s EXCHANGE -o SERVE)
    535     if [ "${SERVE}" = "unix" ]
    536     then
    537         EXCHANGE_URL=$(taler-exchange-config -c "$CONF" -s EXCHANGE -o BASE_URL)
    538     else
    539         EXCHANGE_URL="http://localhost:${EXCHANGE_PORT}/"
    540     fi
    541     MASTER_PRIV_FILE=$(taler-exchange-config -f -c "${CONF}" -s "EXCHANGE-OFFLINE" -o "MASTER_PRIV_FILE")
    542     MASTER_PRIV_DIR=$(dirname "$MASTER_PRIV_FILE")
    543     mkdir -p "${MASTER_PRIV_DIR}"
    544     if [ ! -e "$MASTER_PRIV_FILE" ]
    545     then
    546         gnunet-ecc -g1 "$MASTER_PRIV_FILE" > /dev/null 2> /dev/null
    547         echo -n "." >&2
    548     fi
    549     MASTER_PUB=$(gnunet-ecc -p "${MASTER_PRIV_FILE}")
    550     MPUB=$(taler-exchange-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY)
    551     if [ "$MPUB" != "$MASTER_PUB" ]
    552     then
    553         echo -n " patching master_pub ($MASTER_PUB from ${MASTER_PRIV_FILE})..." >&2
    554         taler-exchange-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY -V "$MASTER_PUB"
    555     fi
    556     taler-exchange-dbinit \
    557         -c "$CONF" \
    558         --reset
    559     $USE_VALGRIND taler-exchange-secmod-eddsa \
    560                   -c "$CONF" \
    561                   -L "$LOGLEVEL" \
    562                   2> taler-exchange-secmod-eddsa.log &
    563     $USE_VALGRIND taler-exchange-secmod-rsa \
    564                   -c "$CONF" \
    565                   -L "$LOGLEVEL" \
    566                   2> taler-exchange-secmod-rsa.log &
    567     $USE_VALGRIND taler-exchange-secmod-cs \
    568                   -c "$CONF" \
    569                   -L "$LOGLEVEL" \
    570                   2> taler-exchange-secmod-cs.log &
    571     $USE_VALGRIND taler-exchange-httpd \
    572                   -c "$CONF" \
    573                   -L "$LOGLEVEL" 2> taler-exchange-httpd.log &
    574     echo " DONE" >&2
    575 fi
    576 
    577 STAGE="donau"
    578 
    579 if [ "1" = "$START_DONAU" ]
    580 then
    581     echo -n "Starting Donau ..." >&2
    582     DONAU_PORT=$(donau-config -c "$CONF" -s DONAU -o PORT)
    583     SERVE=$(donau-config -c "$CONF" -s DONAU -o SERVE)
    584     if [ "${SERVE}" = "unix" ]
    585     then
    586         DONAU_URL=$(donau-config -c "$CONF" -s DONAU -o BASE_URL)
    587     else
    588         DONAU_URL="http://localhost:${DONAU_PORT}/"
    589     fi
    590     donau-dbinit -c "$CONF" --reset
    591     $USE_VALGRIND donau-secmod-eddsa -c "$CONF" -L "$LOGLEVEL" 2> donau-secmod-eddsa.log &
    592     $USE_VALGRIND donau-secmod-rsa -c "$CONF" -L "$LOGLEVEL" 2> donau-secmod-rsa.log &
    593     $USE_VALGRIND donau-secmod-cs -c "$CONF" -L "$LOGLEVEL" 2> donau-secmod-cs.log &
    594     $USE_VALGRIND donau-httpd -c "$CONF" -L "$LOGLEVEL" 2> donau-httpd.log &
    595     echo " DONE" >&2
    596 fi
    597 
    598 STAGE="wirewatch"
    599 
    600 if [ "1" = "$START_WIREWATCH" ]
    601 then
    602     echo -n "Starting wirewatch ..." >&2
    603     $USE_VALGRIND taler-exchange-wirewatch \
    604                   --account="$USE_ACCOUNT" \
    605                   -c "$CONF" \
    606                   -L "$LOGLEVEL" \
    607                   --longpoll-timeout="60 s" \
    608                   2> taler-exchange-wirewatch.log &
    609     echo " DONE" >&2
    610 fi
    611 
    612 STAGE="aggregator"
    613 
    614 if [ "1" = "$START_AGGREGATOR" ]
    615 then
    616     echo -n "Starting aggregator ..." >&2
    617     $USE_VALGRIND taler-exchange-aggregator \
    618                   -c "$CONF" \
    619                   -L "$LOGLEVEL" \
    620                   2> taler-exchange-aggregator.log &
    621     echo " DONE" >&2
    622 fi
    623 
    624 STAGE="transfer"
    625 
    626 if [ "1" = "$START_TRANSFER" ]
    627 then
    628     echo -n "Starting transfer ..." >&2
    629     $USE_VALGRIND taler-exchange-transfer \
    630                   -c "$CONF" \
    631                   -L "$LOGLEVEL" \
    632                   2> taler-exchange-transfer.log &
    633     echo " DONE" >&2
    634 fi
    635 
    636 STAGE="merchant"
    637 
    638 if [ -n "${USE_MERCHANT_EXCHANGE+x}" ]
    639 then
    640     MEPUB=$(taler-merchant-config -c "$CONF" -s "${USE_MERCHANT_EXCHANGE}" -o MASTER_KEY)
    641     MXPUB=${MASTER_PUB:-$(taler-exchange-config -c "$CONF" -s exchange -o MASTER_PUBLIC_KEY)}
    642     if [ "$MEPUB" != "$MXPUB" ]
    643     then
    644         echo -n " patching master_pub ($MXPUB)..." >&2
    645         taler-merchant-config -c "$CONF" -s "${USE_MERCHANT_EXCHANGE}" -o MASTER_KEY -V "$MXPUB"
    646     else
    647         echo -n " with exchange $MXPUB ..." >&2
    648     fi
    649 fi
    650 
    651 if [ "1" = "$START_MERCHANT" ]
    652 then
    653     echo -n "Starting merchant ..." >&2
    654     MERCHANT_TYPE=$(taler-merchant-config -c "$CONF" -s MERCHANT -o SERVE)
    655     if [ "unix" = "$MERCHANT_TYPE" ]
    656     then
    657         MERCHANT_URL="$(taler-merchant-config -c "$CONF" -s MERCHANT -o BASE_URL)"
    658     else
    659         MERCHANT_PORT="$(taler-merchant-config -c "$CONF" -s MERCHANT -o PORT)"
    660         MERCHANT_URL="http://localhost:${MERCHANT_PORT}/"
    661     fi
    662     taler-merchant-dbinit \
    663         -c "$CONF" \
    664         --reset &> taler-merchant-dbinit.log
    665     $USE_VALGRIND taler-merchant-exchangekeyupdate \
    666                   -c "$CONF" \
    667                   -L "$LOGLEVEL" 2> taler-merchant-exchangekeyupdate.log &
    668     $USE_VALGRIND taler-merchant-kyccheck \
    669                   -c "$CONF" \
    670                   -L "$LOGLEVEL" 2> taler-merchant-kyccheck.log &
    671     $USE_VALGRIND taler-merchant-httpd \
    672                   -c "$CONF" \
    673                   -L "$LOGLEVEL" 2> taler-merchant-httpd.log &
    674     if [ "1" = "$START_MERCHANT_WEBHOOK" ]
    675     then
    676         $USE_VALGRIND taler-merchant-webhook \
    677                       -c "$CONF" \
    678                       -L "$LOGLEVEL" 2> taler-merchant-webhook.log &
    679     fi
    680     echo " DONE" >&2
    681     if [ "1" = "$START_MERCHANT_WIREWATCH" ]
    682     then
    683        echo -n "Starting taler-merchant-wirewatch ..." >&2
    684        $USE_VALGRIND taler-merchant-wirewatch \
    685                      -c "$CONF" \
    686                      -L "$LOGLEVEL" \
    687                      --persist \
    688                      2> taler-merchant-wirewatch.log &
    689        echo " DONE" >&2
    690     fi
    691     if [ "1" = "$START_MERCHANT_EXCHANGE" ]
    692     then
    693         echo -n "Starting taler-merchant-exchange ..." >&2
    694         $USE_VALGRIND taler-merchant-exchange \
    695                   -c "$CONF" \
    696                   -L "$LOGLEVEL" 2> taler-merchant-exchange.log &
    697         echo " DONE" >&2
    698     fi
    699     if [ "1" = "$START_DEPOSITCHECK" ]
    700     then
    701         echo -n "Starting taler-merchant-depositcheck ..." >&2
    702         $USE_VALGRIND taler-merchant-depositcheck \
    703                       -c "$CONF" \
    704                       -L "$LOGLEVEL" 2> taler-merchant-depositcheck.log &
    705         echo " DONE" >&2
    706     fi
    707     if [ "1" = "$START_MERCHANT_DONAUKEYUPDATE" ]
    708     then
    709         echo -n "Starting taler-merchant-donaukeyupdate..." >&2
    710         $USE_VALGRIND taler-merchant-donaukeyupdate \
    711                       -c "$CONF" \
    712                       -L "$LOGLEVEL" 2> taler-merchant-donaukeyupdate.log &
    713         echo " DONE" >&2
    714     fi
    715 fi
    716 
    717 STAGE="sync"
    718 
    719 if [ "1" = "$START_BACKUP" ]
    720 then
    721     echo -n "Starting sync ..." >&2
    722     SYNC_PORT=$(sync-config -c "$CONF" -s SYNC -o PORT)
    723     SERVE=$(sync-config -c "$CONF" -s SYNC -o SERVE)
    724     if [ "${SERVE}" = "unix" ]
    725     then
    726         SYNC_URL=$(sync-config -c "$CONF" -s SYNC -o BASE_URL)
    727     else
    728         SYNC_URL="http://localhost:${SYNC_PORT}/"
    729     fi
    730     sync-dbinit -c "$CONF" --reset
    731     $USE_VALGRIND sync-httpd \
    732                   -c "$CONF" \
    733                   -L "$LOGLEVEL" \
    734                   2> sync-httpd.log &
    735     echo " DONE" >&2
    736 fi
    737 
    738 STAGE="challenger"
    739 
    740 if [ "1" = "$START_CHALLENGER" ]
    741 then
    742     echo -n "Starting challenger ..." >&2
    743     CHALLENGER_PORT=$(challenger-config -c "$CONF" -s CHALLENGER -o PORT)
    744     SERVE=$(challenger-config -c "$CONF" -s CHALLENGER -o SERVE)
    745     if [ "${SERVE}" = "unix" ]
    746     then
    747         CHALLENGER_URL=$(challenger-config -c "$CONF" -s CHALLENGER -o BASE_URL)
    748     else
    749         CHALLENGER_URL="http://localhost:${CHALLENGER_PORT}/"
    750     fi
    751     challenger-dbinit \
    752         -c "$CONF" \
    753         --reset
    754     $USE_VALGRIND challenger-httpd \
    755                   -c "$CONF" \
    756                   -L "$LOGLEVEL" \
    757                   2> challenger-httpd.log &
    758     echo " DONE" >&2
    759     for SECTION in $(taler-exchange-config -c "$CONF" -S | grep kyc-provider)
    760     do
    761         LOGIC=$(taler-exchange-config -c "$CONF" -s "$SECTION" -o "LOGIC")
    762         if [ "${LOGIC}" = "oauth2" ]
    763         then
    764             INFO=$(taler-exchange-config -c "$CONF" -s "$SECTION" -o "KYC_OAUTH2_INFO_URL")
    765             if [ "${CHALLENGER_URL}info" = "$INFO" ]
    766             then
    767                 echo -n "Enabling Challenger client for $SECTION" >&2
    768                 CLIENT_SECRET=$(taler-exchange-config -c "$CONF" -s "$SECTION" -o "KYC_OAUTH2_CLIENT_SECRET")
    769                 RFC_8959_PREFIX="secret-token:"
    770                 if ! echo "${CLIENT_SECRET}" | grep ^${RFC_8959_PREFIX} > /dev/null
    771                 then
    772                     exit_fail "Client secret does not begin with '${RFC_8959_PREFIX}'"
    773                 fi
    774                 REDIRECT_URI="${EXCHANGE_URL}kyc-proof/kyc-provider-example-challeger"
    775                 CLIENT_ID=$(challenger-admin --add="${CLIENT_SECRET}" --quiet "${REDIRECT_URI}")
    776                 taler-exchange-config -c "$CONF" -s "$SECTION" -o KYC_OAUTH2_CLIENT_ID -V "$CLIENT_ID"
    777                 echo " DONE" >&2
    778             fi
    779         fi
    780     done
    781 fi
    782 
    783 STAGE="auditor"
    784 
    785 if [ "1" = "$START_AUDITOR" ]
    786 then
    787     echo -n "Starting auditor ..." >&2
    788 
    789     export TALER_AUDITOR_SALT=$(taler-auditor-config -c "$CONF" -s AUDITOR -o TALER_AUDITOR_SALT)
    790 
    791     AUDITOR_URL=$(taler-auditor-config -c "$CONF" -s AUDITOR -o BASE_URL)
    792     AUDITOR_PRIV_FILE=$(taler-auditor-config -f -c "$CONF" -s AUDITOR -o AUDITOR_PRIV_FILE)
    793     AUDITOR_PRIV_DIR=$(dirname "$AUDITOR_PRIV_FILE")
    794     mkdir -p "$AUDITOR_PRIV_DIR"
    795     if [ ! -e "$AUDITOR_PRIV_FILE" ]
    796     then
    797         gnunet-ecc -g1 "$AUDITOR_PRIV_FILE" > /dev/null 2> /dev/null
    798         echo -n "." >&2
    799     fi
    800     AUDITOR_PUB=$(gnunet-ecc -p "${AUDITOR_PRIV_FILE}")
    801     APUB=$(taler-exchange-config -c "$CONF" -s auditor -o PUBLIC_KEY)
    802     if [ "$APUB" != "$AUDITOR_PUB" ]
    803     then
    804         echo -n " patching auditor public key ..." >&2
    805         # Using taler-exchange-config is correct here, we don't want to
    806         # suddenly use the auditor-defaults while editing...
    807         taler-exchange-config -c "$CONF" -s auditor -o PUBLIC_KEY -V "$AUDITOR_PUB"
    808     fi
    809 
    810     taler-auditor-dbinit \
    811         -c "$CONF" \
    812         --reset
    813     echo "Launching auditor using $CONF" > taler-auditor-httpd.log >&2
    814     echo "Launching auditor using $AUDITOR_PUB from $AUDITOR_PRIV_FILE" \
    815          >> taler-auditor-httpd.log
    816     $USE_VALGRIND taler-auditor-httpd \
    817                   -L "$LOGLEVEL" \
    818                   -c "$CONF" 2>> taler-auditor-httpd.log &
    819     echo " DONE" >&2
    820 fi
    821 
    822 STAGE="wait"
    823 
    824 echo -n "Waiting for Taler services ..." >&2
    825 # Wait for all other taler services to be available
    826 E_DONE=0
    827 D_DONE=0
    828 M_DONE=0
    829 S_DONE=0
    830 K_DONE=0
    831 A_DONE=0
    832 for n in $(seq 1 30)
    833 do
    834     sleep "$DEFAULT_SLEEP"
    835     OK="0"
    836     if [ "0" = "$E_DONE" ] && [ "1" = "$START_EXCHANGE" ]
    837     then
    838         echo -n "E" >&2
    839         wget \
    840             --tries=1 \
    841             --timeout=1 \
    842             "${EXCHANGE_URL}config" \
    843             -o /dev/null \
    844             -O /dev/null >/dev/null || continue
    845         E_DONE=1
    846     fi
    847    if [ "0" = "$D_DONE" ] && [ "1" = "$START_DONAU" ]
    848     then
    849         echo -n "D" >&2
    850         wget \
    851             --tries=1 \
    852             --timeout=1 \
    853             "${DONAU_URL}config" \
    854             -o /dev/null \
    855             -O /dev/null >/dev/null || continue
    856         D_DONE=1
    857     fi
    858     if [ "0" = "$M_DONE" ] && [ "1" = "$START_MERCHANT" ]
    859     then
    860         echo -n "M" >&2
    861         wget \
    862             --tries=1 \
    863             --timeout=1 \
    864             "${MERCHANT_URL}config" \
    865             -o /dev/null \
    866             -O /dev/null >/dev/null || continue
    867         M_DONE=1
    868     fi
    869     if [ "0" = "$S_DONE" ] && [ "1" = "$START_BACKUP" ]
    870     then
    871         echo -n "S" >&2
    872         wget \
    873             --tries=1 \
    874             --timeout=1 \
    875             "${SYNC_URL}config" \
    876             -o /dev/null \
    877             -O /dev/null >/dev/null || continue
    878         S_DONE=1
    879     fi
    880     if [ "0" = "$K_DONE" ] && [ "1" = "$START_CHALLENGER" ]
    881     then
    882         echo -n "K" >&2
    883         wget \
    884             --tries=1 \
    885             --timeout=1 \
    886             "${CHALLENGER_URL}config" \
    887             -o /dev/null \
    888             -O /dev/null >/dev/null || continue
    889         K_DONE=1
    890     fi
    891     if [ "0" = "$A_DONE" ] && [ "1" = "$START_AUDITOR" ]
    892     then
    893         echo -n "A" >&2
    894         wget \
    895             --tries=1 \
    896             --timeout=1 \
    897             "${AUDITOR_URL}config" \
    898             -o /dev/null \
    899             -O /dev/null >/dev/null || continue
    900         A_DONE=1
    901     fi
    902     OK="1"
    903     break
    904 done
    905 if [ 1 != "$OK" ]
    906 then
    907     exit_skip "Failed to launch (some) Taler services (E: $E_DONE, M: $M_DONE, S: $S_DONE, K: $K_DONE, A: $A_DONE, D: $D_DONE)"
    908 fi
    909 echo " OK" >&2
    910 
    911 if [ "1" = "$START_EXCHANGE" ]
    912 then
    913     echo -n "Wait for exchange /management/keys to be ready " >&2
    914     OK="0"
    915     LAST_RESPONSE=$(mktemp tmp-last-response.XXXXXXXX)
    916     for n in $(seq 1 10)
    917     do
    918         echo -n "." >&2
    919         sleep "$DEFAULT_SLEEP"
    920         # exchange
    921         wget \
    922             --tries=3 \
    923             --waitretry=0 \
    924             --timeout=30 \
    925             "${EXCHANGE_URL}management/keys"\
    926             -o /dev/null \
    927             -O "$LAST_RESPONSE" \
    928             >/dev/null || continue
    929         OK="1"
    930         break;
    931     done
    932     if [ "1" != "$OK" ]
    933     then
    934         cat "$LAST_RESPONSE"
    935         exit_fail "Failed to setup exchange keys, check secmod logs"
    936     fi
    937     rm "$LAST_RESPONSE"
    938     echo " OK" >&2
    939 
    940     echo -n "Setting up exchange keys ..." >&2
    941     rm -f test_exchange_api_home/.local/share/taler-exchange/offline/secm_tofus.pub
    942     NEXT_YEAR=$(expr 1 + $(date +%Y))
    943     taler-exchange-offline -c "$CONF" \
    944       download \
    945       sign \
    946       wire-fee now "$WIRE_DOMAIN" "$CURRENCY:0.01" "$CURRENCY:0.01" \
    947       wire-fee "$NEXT_YEAR" "$WIRE_DOMAIN" "$CURRENCY:0.01" "$CURRENCY:0.01" \
    948       global-fee now "$CURRENCY:0.01" "$CURRENCY:0.01" "$CURRENCY:0.0" 1h 1year 5 \
    949       global-fee "$NEXT_YEAR" "$CURRENCY:0.01" "$CURRENCY:0.01" "$CURRENCY:0.0" 1h 1year 5 \
    950       upload &> taler-exchange-offline.log
    951     echo "OK" >&2
    952     ENABLED=$(taler-exchange-config -c "$CONF" -s "$USE_ACCOUNT" -o "ENABLE_CREDIT")
    953     if [ "YES" = "$ENABLED" ]
    954     then
    955         echo -n "Configuring bank account $USE_ACCOUNT ..." >&2
    956         EXCHANGE_PAYTO_URI=$(taler-exchange-config -c "$CONF" -s "$USE_ACCOUNT" -o "PAYTO_URI")
    957         taler-exchange-offline -c "$CONF" \
    958           enable-account "$EXCHANGE_PAYTO_URI" \
    959           upload &> "taler-exchange-offline-account.log"
    960         echo " OK" >&2
    961     else
    962         echo "WARNING: Account ${USE_ACCOUNT} not enabled (set to: '$ENABLED')" >&2
    963     fi
    964     if [ "1" = "$START_AUDITOR" ]
    965     then
    966         echo -n "Enabling auditor ..." >&2
    967         taler-exchange-offline -c "$CONF" \
    968           enable-auditor "$AUDITOR_PUB" "$AUDITOR_URL" "$CURRENCY Auditor" \
    969           upload &> taler-exchange-offline-auditor.log
    970         echo "OK" >&2
    971     fi
    972 
    973     echo -n "Checking /keys " >&2
    974     OK="0"
    975     LAST_RESPONSE=$(mktemp tmp-last-response.XXXXXXXX)
    976     for n in $(seq 1 10)
    977     do
    978         echo -n "." >&2
    979         sleep "$DEFAULT_SLEEP"
    980         wget \
    981             --tries=1 \
    982             --timeout=5 \
    983             "${EXCHANGE_URL}keys" \
    984             -a wget-keys-check.log \
    985             -o /dev/null \
    986             -O "$LAST_RESPONSE" \
    987             >/dev/null || continue
    988         OK="1"
    989         break
    990     done
    991     if [ "1" != "$OK" ]
    992     then
    993         cat "$LAST_RESPONSE"
    994         exit_fail " Failed to fetch ${EXCHANGE_URL}keys"
    995     fi
    996     rm "$LAST_RESPONSE"
    997     echo " OK" >&2
    998 fi
    999 
   1000 if [ "1" = "$START_AUDITOR" ]
   1001 then
   1002     echo -n "Setting up auditor signatures ..." >&2
   1003     timeout 15 taler-auditor-offline -c "$CONF" \
   1004       download \
   1005       sign \
   1006       upload &> taler-auditor-offline.log
   1007     echo " OK" >&2
   1008 
   1009     echo -n "Starting helpers " >&2
   1010 
   1011     $USE_VALGRIND taler-helper-auditor-coins \
   1012                         -L "$LOGLEVEL" \
   1013                         -c "$CONF" 2> taler-helper-auditor.log &
   1014     echo -n "." >&2
   1015 
   1016     $USE_VALGRIND taler-helper-auditor-reserves \
   1017                         -L "$LOGLEVEL" \
   1018                         -c "$CONF" 2> taler-helper-auditor.log &
   1019     echo -n "." >&2
   1020 
   1021     $USE_VALGRIND taler-helper-auditor-purses \
   1022                         -L "$LOGLEVEL" \
   1023                         -c "$CONF" 2> taler-helper-auditor.log &
   1024     echo -n "." >&2
   1025 
   1026     $USE_VALGRIND taler-helper-auditor-aggregation \
   1027                         -L "$LOGLEVEL" \
   1028                         -c "$CONF" 2> taler-helper-auditor.log &
   1029     echo -n "." >&2
   1030 
   1031     $USE_VALGRIND taler-helper-auditor-deposits \
   1032                             -L "$LOGLEVEL" \
   1033                             -c "$CONF" 2> taler-helper-auditor.log &
   1034     echo -n "." >&2
   1035 
   1036     echo " OK" >&2
   1037 
   1038 fi
   1039 
   1040 STAGE="ready"
   1041 
   1042 # Signal caller that we are ready.
   1043 echo "READY:$TESTROOT"
   1044 
   1045 if [ "1" = "$WAIT_FOR_SIGNAL" ]
   1046 then
   1047     while true
   1048     do
   1049         sleep 0.1
   1050     done
   1051 else
   1052     # Wait until caller stops us.
   1053     # shellcheck disable=SC2162
   1054     read
   1055 fi
   1056 
   1057 STAGE="exiting"
   1058 
   1059 echo "Taler unified setup terminating!" >&2
   1060 EXIT_STATUS=0
   1061 exit "$EXIT_STATUS"