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 (29886B)


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