Initial Taler stack with templated configs, db init script, caddy proxy

This commit is contained in:
nocci 2025-12-11 12:22:48 +00:00
commit d0b0722a7b
16 changed files with 723 additions and 0 deletions

59
.env.example Normal file
View file

@ -0,0 +1,59 @@
POSTGRES_HOST=postgres
POSTGRES_PORT=5432
POSTGRES_PASSWORD=taler
POSTGRES_ADMIN_USER=postgres
TALER_EXCHANGE_DB=talerexchange
TALER_EXCHANGE_DB_USER=talerexchange
TALER_EXCHANGE_DB_PASSWORD=taler
TALER_MERCHANT_DB=talermerchant
TALER_MERCHANT_DB_USER=talermerchant
TALER_MERCHANT_DB_PASSWORD=taler
LIBEUFIN_DB_NAME=libeufinbank
LIBEUFIN_DB_USER=libeufinbank
LIBEUFIN_DB_PASSWORD=taler
LIBEUFIN_ADMIN_USER=admin
LIBEUFIN_ADMIN_PASSWORD=
LIBEUFIN_MERCHANT_USER=demogeldbank
LIBEUFIN_MERCHANT_PASSWORD=
LIBEUFIN_MERCHANT_TOKEN=
LIBEUFIN_USER=demogeld
LIBEUFIN_USER_PASSWORD=
LIBEUFIN_DEBIT_THRESHOLD=DEMOGELD:1000000
# Exchange offline account enablement
ENABLE_EXCHANGE_ACCOUNT=0
PAYTO_URI=payto://x-taler-bank/yourbank.domain.tld/demogeld?receiver-name=demogeld
EXCHANGE_KEYS_URL=http://exchange.internal:8081/keys
EXCHANGE_WAIT_RETRIES=60
EXCHANGE_WAIT_INTERVAL=2
# Optional curl flags for HTTPS with custom certs, etc. Example: "-k"
EXCHANGE_CURL_OPTS=
# Caddy reverse proxy
CADDY_ACME_EMAIL=ops@example.com
BANK_HOST=bank.domain.tld
EXCHANGE_HOST=exchange.domain.tld
MERCHANT_HOST=merchant.domain.tld
# Secrets path (host path mounted into /etc/taler/secrets)
EXCHANGE_SECRETS_PATH=./exchange/secrets
# Master key (public) for exchange/merchant configs
MASTER_PUBLIC_KEY=
# Optional token provisioning output path
TOKEN_OUTPUT=bank/token-info.txt
TALER_DOMAIN=localhost
TALER_EXCHANGE_PORT=8081
TALER_MERCHANT_PORT=9966
LIBEUFIN_BANK_PORT=8080
EXCHANGE_BASE_URL=https://exchange.domain.tld/
EXCHANGE_SHOPPING_URL=https://exchange.domain.tld/
OPEN_BANKING_GATEWAY_URL=https://bank.domain.tld
BANK_BASE_URL=https://bank.domain.tld/
TALER_CURRENCY=DEMOGELD

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
.env

33
Dockerfile Normal file
View file

@ -0,0 +1,33 @@
FROM debian:sid
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y \
build-essential git automake libtool pkg-config \
libgnutls28-dev libjansson-dev libsqlite3-dev \
postgresql-client curl gnupg gettext-base \
openjdk-17-jdk maven \
&& rm -rf /var/lib/apt/lists/*
# GNUnet (falls nicht schon systemweit neu genug)
RUN git clone https://git.taler.net/gnunet.git /src/gnunet && \
cd /src/gnunet && ./bootstrap && \
./configure --prefix=/usr && make -j$(nproc) && make install
# Taler Exchange + Merchant
RUN git clone https://git.taler.net/exchange.git /src/exchange && \
cd /src/exchange && ./bootstrap && \
./configure --prefix=/usr && make -j$(nproc) && make install && \
git clone https://git.taler.net/merchant.git /src/merchant && \
cd /src/merchant && ./bootstrap && \
./configure --prefix=/usr && make -j$(nproc) && make install
# LibEuFin (Bank)
RUN git clone https://git.taler.net/libeufin.git /src/libeufin && \
cd /src/libeufin && ./bootstrap && \
./configure --prefix=/usr && make -j$(nproc) && make install
# Shared entrypoint for dbinit + service start
COPY entrypoints/with-dbinit.sh /usr/local/bin/with-dbinit.sh
COPY scripts/enable-exchange-account.sh /usr/local/bin/enable-exchange-account.sh
RUN chmod +x /usr/local/bin/with-dbinit.sh /usr/local/bin/enable-exchange-account.sh

48
bank/conf/bank.conf.tmpl Normal file
View file

@ -0,0 +1,48 @@
[libeufin-bank]
# Internal currency of the libeufin-bank
CURRENCY = DEMOGELD
# Supported payment target type, choose x-taler-bank for this stack
WIRE_TYPE = x-taler-bank
# Base URL as seen by clients; adjust via BANK_BASE_URL
BASE_URL = ${BANK_BASE_URL:-https://${BANK_HOST:-ob.antifa.ltd}/}
# Display name
NAME = "Demogeld Taler Bank"
# Fees and limits for demo operation
WIRE_TRANSFER_FEES = DEMOGELD:0
MIN_WIRE_TRANSFER_AMOUNT = DEMOGELD:0
MAX_WIRE_TRANSFER_AMOUNT = DEMOGELD:200
DEFAULT_DEBT_LIMIT = DEMOGELD:200
REGISTRATION_BONUS = DEMOGELD:50
# Self-service options
ALLOW_REGISTRATION = yes
ALLOW_ACCOUNT_DELETION = no
ALLOW_EDIT_NAME = yes
# Serving parameters
SERVE = tcp
PORT = 8080
BIND_TO = 0.0.0.0
# Suggested exchange for withdrawals
SUGGESTED_WITHDRAWAL_EXCHANGE = ${EXCHANGE_BASE_URL:-https://${EXCHANGE_HOST:-exchange.antifa.ltd}/}
# Password hashing
PWD_HASH_ALGORITHM = bcrypt
PWD_HASH_CONFIG = { "cost": 8 }
PWD_CHECK = yes
PWD_AUTH_COMPAT = no
# GC settings
GC_ABORT_AFTER = 15m
GC_CLEAN_AFTER = 14d
GC_DELETE_AFTER = 10year
[libeufin-bankdb-postgres]
# JDBC URL to the Postgres instance from compose. Keep in sync with postgres/init SQL and compose env.
CONFIG = jdbc:postgresql://postgres:5432/libeufinbank?user=libeufinbank&password=taler&ssl=false&connectTimeout=5
sql_dir = /usr/share/libeufin

15
caddy/Caddyfile Normal file
View file

@ -0,0 +1,15 @@
{
email {$CADDY_ACME_EMAIL}
}
{$BANK_HOST} {
reverse_proxy bank:8080
}
{$EXCHANGE_HOST} {
reverse_proxy exchange:8081
}
{$MERCHANT_HOST} {
reverse_proxy merchant:9966
}

115
compose.yml Normal file
View file

@ -0,0 +1,115 @@
services:
postgres:
image: postgres:16
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-taler}
volumes:
- pgdata:/var/lib/postgresql/data
- ./postgres/init:/docker-entrypoint-initdb.d:ro
exchange:
image: taler-stack:build
entrypoint: ["/usr/local/bin/with-dbinit.sh"]
command: ["taler-exchange-httpd", "-c", "/etc/taler/taler-exchange.conf"]
environment:
DB_NAME: ${TALER_EXCHANGE_DB:-talerexchange}
INIT_CMD: taler-exchange-dbinit -c /etc/taler/taler-exchange.conf
PGHOST: ${POSTGRES_HOST:-postgres}
PGUSER: ${POSTGRES_ADMIN_USER:-postgres}
PGPASSWORD: ${POSTGRES_PASSWORD:-taler}
EXCHANGE_BASE_URL: ${EXCHANGE_BASE_URL:-https://exchange.antifa.ltd/}
EXCHANGE_SHOPPING_URL: ${EXCHANGE_SHOPPING_URL:-https://exchange.antifa.ltd/}
OPEN_BANKING_GATEWAY_URL: ${OPEN_BANKING_GATEWAY_URL:-https://ob.antifa.ltd}
PAYTO_URI: ${PAYTO_URI:-payto://x-taler-bank/ob.antifa.ltd/demogeld?receiver-name=demogeld}
EXCHANGE_HOST: ${EXCHANGE_HOST:-exchange.antifa.ltd}
BANK_HOST: ${BANK_HOST:-ob.antifa.ltd}
depends_on: [postgres]
volumes:
- ./exchange/conf:/etc/taler
- ${EXCHANGE_SECRETS_PATH:-./exchange/secrets}:/etc/taler/secrets
- ./exchange/terms:/etc/taler-exchange/terms
- ./exchange/privacy:/etc/taler-exchange/privacy
ports:
- "8081:8081" # intern, später via Reverse Proxy auf 443
exchange-account-init:
image: taler-stack:build
depends_on: [exchange]
environment:
ENABLE_EXCHANGE_ACCOUNT: ${ENABLE_EXCHANGE_ACCOUNT:-0}
PAYTO_URI: ${PAYTO_URI:-payto://x-taler-bank/ob.antifa.ltd/demogeld?receiver-name=demogeld}
EXCHANGE_CONFIG: /etc/taler/taler-exchange.conf
EXCHANGE_KEYS_URL: ${EXCHANGE_KEYS_URL:-http://exchange:8081/keys}
EXCHANGE_WAIT_RETRIES: ${EXCHANGE_WAIT_RETRIES:-60}
EXCHANGE_WAIT_INTERVAL: ${EXCHANGE_WAIT_INTERVAL:-2}
EXCHANGE_CURL_OPTS: ${EXCHANGE_CURL_OPTS:-}
volumes:
- ./exchange/conf:/etc/taler
- ${EXCHANGE_SECRETS_PATH:-./exchange/secrets}:/etc/taler/secrets
- ./exchange/terms:/etc/taler-exchange/terms
- ./exchange/privacy:/etc/taler-exchange/privacy
command: ["/usr/local/bin/enable-exchange-account.sh"]
restart: "no"
merchant:
image: taler-stack:build
entrypoint: ["/usr/local/bin/with-dbinit.sh"]
command: ["taler-merchant-httpd", "-c", "/etc/taler-merchant/merchant.conf"]
environment:
DB_NAME: ${TALER_MERCHANT_DB:-talermerchant}
INIT_CMD: taler-merchant-dbinit -c /etc/taler-merchant/merchant.conf
PGHOST: ${POSTGRES_HOST:-postgres}
PGUSER: ${POSTGRES_ADMIN_USER:-postgres}
PGPASSWORD: ${POSTGRES_PASSWORD:-taler}
EXCHANGE_BASE_URL: ${EXCHANGE_BASE_URL:-https://exchange.antifa.ltd/}
EXCHANGE_HOST: ${EXCHANGE_HOST:-exchange.antifa.ltd}
depends_on: [postgres, exchange]
volumes:
- ./merchant/conf:/etc/taler-merchant
ports:
- "9966:9966"
bank:
image: taler-stack:build
entrypoint: ["/usr/local/bin/with-dbinit.sh"]
command: ["libeufin-bank", "serve", "-c", "/etc/libeufin/bank.conf"]
environment:
DB_NAME: ${LIBEUFIN_DB_NAME:-libeufinbank}
INIT_CMD: libeufin-bank dbinit -c /etc/libeufin/bank.conf
PGHOST: ${POSTGRES_HOST:-postgres}
PGUSER: ${POSTGRES_ADMIN_USER:-postgres}
PGPASSWORD: ${POSTGRES_PASSWORD:-taler}
BANK_BASE_URL: ${BANK_BASE_URL:-https://ob.antifa.ltd/}
BANK_HOST: ${BANK_HOST:-ob.antifa.ltd}
EXCHANGE_BASE_URL: ${EXCHANGE_BASE_URL:-https://exchange.antifa.ltd/}
EXCHANGE_HOST: ${EXCHANGE_HOST:-exchange.antifa.ltd}
LIBEUFIN_ADMIN_USER: ${LIBEUFIN_ADMIN_USER:-admin}
LIBEUFIN_ADMIN_PASSWORD: ${LIBEUFIN_ADMIN_PASSWORD:-}
LIBEUFIN_USER: ${LIBEUFIN_USER:-demogeld}
LIBEUFIN_USER_PASSWORD: ${LIBEUFIN_USER_PASSWORD:-}
depends_on: [postgres]
volumes:
- ./bank/conf:/etc/libeufin
ports:
- "8080:8080"
caddy:
image: caddy:2
depends_on: [exchange, merchant, bank]
ports:
- "80:80"
- "443:443"
volumes:
- ./caddy/Caddyfile:/etc/caddy/Caddyfile:ro
- caddy_data:/data
- caddy_config:/config
environment:
CADDY_ACME_EMAIL: ${CADDY_ACME_EMAIL:-ops@example.com}
BANK_HOST: ${BANK_HOST:-ob.antifa.ltd}
EXCHANGE_HOST: ${EXCHANGE_HOST:-exchange.antifa.ltd}
MERCHANT_HOST: ${MERCHANT_HOST:-merchant.antifa.ltd}
volumes:
pgdata: {}
caddy_data: {}
caddy_config: {}

119
entrypoints/with-dbinit.sh Normal file
View file

@ -0,0 +1,119 @@
#!/usr/bin/env bash
set -euo pipefail
: "${PGHOST:=postgres}"
: "${PGPORT:=5432}"
: "${PGUSER:=postgres}"
: "${PGPASSWORD:=taler}"
if [[ -z "${DB_NAME:-}" ]]; then
echo "DB_NAME not set; cannot run dbinit" >&2
exit 1
fi
if [[ -z "${INIT_CMD:-}" ]]; then
echo "INIT_CMD not set; cannot run dbinit" >&2
exit 1
fi
SERVICE_CMD=("$@")
render_template() {
local src="$1"
local dst="$2"
if [[ -f "${src}" ]]; then
echo "Rendering template ${src} -> ${dst}"
envsubst < "${src}" > "${dst}"
fi
}
render_templates() {
case "${SERVICE_CMD[0]:-}" in
taler-exchange-httpd|taler-exchange-*)
render_template /etc/taler/taler-exchange.conf.tmpl /etc/taler/taler-exchange.conf
render_template /etc/taler/conf.d/99-exchange.conf.tmpl /etc/taler/conf.d/99-exchange.conf
;;
taler-merchant-httpd|taler-merchant-*)
render_template /etc/taler-merchant/merchant.conf.tmpl /etc/taler-merchant/merchant.conf
;;
libeufin-bank)
render_template /etc/libeufin/bank.conf.tmpl /etc/libeufin/bank.conf
;;
esac
}
render_templates
wait_for_db() {
echo "Waiting for Postgres at ${PGHOST}:${PGPORT}..."
until pg_isready -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" >/dev/null 2>&1; do
sleep 1
done
}
db_has_tables() {
local count
count="$(psql -h "${PGHOST}" -p "${PGPORT}" -U "${PGUSER}" -d "${DB_NAME}" -Atc \
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema='public';")"
[[ "${count}" != "0" ]]
}
run_init() {
if [[ "${SKIP_DBINIT:-}" == "1" ]]; then
echo "SKIP_DBINIT=1 set; skipping dbinit for ${DB_NAME}"
return
fi
echo "Running dbinit for ${DB_NAME}: ${INIT_CMD}"
# shellcheck disable=SC2206
init_arr=(${INIT_CMD})
"${init_arr[@]}"
}
set_libeufin_admin_password() {
# Only relevant for libeufin-bank service and if credentials are provided.
if [[ "${SERVICE_CMD[0]:-}" != "libeufin-bank" ]]; then
return
fi
if [[ -z "${LIBEUFIN_ADMIN_USER:-}" || -z "${LIBEUFIN_ADMIN_PASSWORD:-}" ]]; then
return
fi
echo "Setting LibEuFin admin password for user ${LIBEUFIN_ADMIN_USER}"
if ! printf "%s\n%s\n" "${LIBEUFIN_ADMIN_PASSWORD}" "${LIBEUFIN_ADMIN_PASSWORD}" | \
libeufin-bank passwd "${LIBEUFIN_ADMIN_USER}" -c /etc/libeufin/bank.conf; then
echo "Warning: failed to set LibEuFin admin password" >&2
fi
}
ensure_libeufin_user() {
# Create/update a non-admin bank user if configured.
if [[ "${SERVICE_CMD[0]:-}" != "libeufin-bank" ]]; then
return
fi
if [[ -z "${LIBEUFIN_USER:-}" || -z "${LIBEUFIN_USER_PASSWORD:-}" ]]; then
return
fi
echo "Ensuring LibEuFin user ${LIBEUFIN_USER}"
if ! libeufin-bank users add "${LIBEUFIN_USER}" --password "${LIBEUFIN_USER_PASSWORD}" \
-c /etc/libeufin/bank.conf 2>/tmp/libeufin-add-user.log; then
if grep -qi "already exists" /tmp/libeufin-add-user.log; then
echo "LibEuFin user ${LIBEUFIN_USER} already exists; skipping creation."
else
echo "Warning: failed to ensure LibEuFin user ${LIBEUFIN_USER}" >&2
cat /tmp/libeufin-add-user.log >&2
fi
fi
}
wait_for_db
if db_has_tables; then
echo "Database ${DB_NAME} already initialized; skipping dbinit."
else
run_init
fi
render_templates
set_libeufin_admin_password
ensure_libeufin_user
echo "Starting service command: ${SERVICE_CMD[*]}"
exec "${SERVICE_CMD[@]}"

View file

@ -0,0 +1,59 @@
[exchange]
BASE_URL = ${EXCHANGE_BASE_URL:-https://${EXCHANGE_HOST:-exchange.antifa.ltd}/}
DB = postgres
MASTER_PUBLIC_KEY = ${MASTER_PUBLIC_KEY:-QZEPPYMSPF9RKNDCJ1SYMYY5RCV0Y0827SP2FZ9Z1J8C7PEW6CDG}
SERVE = tcp
PORT = 8081
BIND_TO = 0.0.0.0
IDLE_RESERVE_EXPIRATION_TIME = 4 weeks
RESHARE_RESERVE_EXPIRATION_TIME = 8 weeks
TERMS_DIR = /etc/taler-exchange/terms
PRIVACY_DIR = /etc/taler-exchange/privacy
TINY_AMOUNT = DEMOGELD:0.01
SHOPPING_URL = ${EXCHANGE_SHOPPING_URL:-${EXCHANGE_BASE_URL:-https://${EXCHANGE_HOST:-exchange.antifa.ltd}/}}
OPEN_BANKING_GATEWAY_URL = ${OPEN_BANKING_GATEWAY_URL:-https://${BANK_HOST:-ob.antifa.ltd}}
[exchangedb-postgres]
CONFIG = postgres://talerexchange:taler@postgres:5432/talerexchange
[coin_demogeld_1]
VALUE = DEMOGELD:0.50
CIPHER = RSA
RSA_KEYSIZE = 2048
DURATION_WITHDRAW = 12 weeks
DURATION_SPEND = 52 weeks
DURATION_DEPOSIT = 104 weeks
DURATION_LEGAL = 208 weeks
FEE_WITHDRAW = 0.00 DEMOGELD
FEE_DEPOSIT = 0.00 DEMOGELD
FEE_REFRESH = 0.00 DEMOGELD
FEE_REFUND = 0.00 DEMOGELD
[coin_demogeld_2]
VALUE = DEMOGELD:1.00
CIPHER = RSA
RSA_KEYSIZE = 2048
DURATION_WITHDRAW = 12 weeks
DURATION_SPEND = 52 weeks
DURATION_DEPOSIT = 104 weeks
DURATION_LEGAL = 208 weeks
FEE_WITHDRAW = 0.00 DEMOGELD
FEE_DEPOSIT = 0.00 DEMOGELD
FEE_REFRESH = 0.00 DEMOGELD
FEE_REFUND = 0.00 DEMOGELD
[coin_demogeld_3]
VALUE = DEMOGELD:5.00
CIPHER = RSA
RSA_KEYSIZE = 2048
DURATION_WITHDRAW = 12 weeks
DURATION_SPEND = 52 weeks
DURATION_DEPOSIT = 104 weeks
DURATION_LEGAL = 208 weeks
FEE_WITHDRAW = 0.00 DEMOGELD
FEE_DEPOSIT = 0.00 DEMOGELD
FEE_REFRESH = 0.00 DEMOGELD
FEE_REFUND = 0.00 DEMOGELD
[wire-demogeld]
PAYTO_URI = ${PAYTO_URI:-payto://x-taler-bank/${BANK_HOST:-ob.antifa.ltd}/demogeld?receiver-name=demogeld}

View file

@ -0,0 +1 @@
# Intentionally empty; can be used by tooling to override settings.

View file

@ -0,0 +1,8 @@
[exchange]
currency = DEMOGELD
@inline-matching@ conf.d/*.conf
@inline@ overrides.conf
[wire-exchange-demogeld]
PAYTO_URI = ${PAYTO_URI:-payto://x-taler-bank/${BANK_HOST:-ob.antifa.ltd}/demogeld?receiver-name=demogeld}

View file

@ -0,0 +1,55 @@
Datenschutzerklaerung (Demo)
Stand: 2025-12-10
1. Verantwortlicher
Georg Elser Institut fuer Angewandten Antifaschismus und Antiautoritarismusforschung
Koenig-Lothar-Platz 1, DE-01161 Dresden
Vertreten durch: Mirco da Silva, Amalie-Dietrich-Platz 9, DE-01169 Dresden
E-Mail: gamemaster@antifa.ltd
2. Zweck der Verarbeitung
Bereitstellung und Betrieb von Demogeld-Konten zu Demonstrations- und Spielzwecken (fiktive
Waehrung ohne realen Gegenwert).
3. Kategorien von Daten
- Kontodaten: Benutzername, E-Mail (optional), fiktive oder reale Personenangaben.
- Protokolle: technische Logfiles fuer Betrieb/Sicherheit (z.B. Zeitstempel, IP, Fehlerlogs).
4. Rechtsgrundlage (DSGVO)
- Art. 6 Abs. 1 lit. b DSGVO (vertragliche Anbahnung/Nutzung des Demo-Dienstes)
- Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse am sicheren Betrieb)
- Bei rein fiktiven Angaben sind keine personenbezogenen Daten betroffen.
5. Speicherdauer
- Kontodaten: bis zur Loeschung des Kontos oder Einstellung des Dienstes.
- Logdaten: in der Regel wenige Wochen/Monate, sofern keine laengere Aufbewahrung wegen
Fehlersuche/Sicherheit erforderlich ist.
6. Empfaenger
Keine Weitergabe an Dritte, ausser technische Dienstleister (Hosting/Administration) mit
entsprechender Vereinbarung.
7. Uebermittlungen in Drittlaender
Nicht vorgesehen.
8. Rechte der Betroffenen (DSGVO)
- Auskunft (Art. 15)
- Berichtigung (Art. 16)
- Loeschung (Art. 17)
- Einschraenkung (Art. 18)
- Datenuebertragbarkeit (Art. 20)
- Widerspruch (Art. 21)
- Beschwerde bei einer Aufsichtsbehoerde (Art. 77)
Kontakt fuer Betroffenenrechte: gamemaster@antifa.ltd
9. Erforderlichkeit/Freiwilligkeit
Die Nutzung ist freiwillig; erforderliche Angaben sind auf das Minimum fuer den Betrieb des
Demo-Kontos beschraenkt und duerfen fiktiv sein.
10. Sicherheit
Uebliche technische und organisatorische Massnahmen; keine Garantie fuer Verfuegbarkeit oder
Unversehrtheit der Daten (Demo-Betrieb, Haftungsausschluss siehe Nutzungsbedingungen).
11. Aenderungen
Diese Erklaerung kann angepasst werden. Bitte beachten Sie die jeweils aktuelle Fassung.

44
exchange/terms/terms.txt Normal file
View file

@ -0,0 +1,44 @@
Demogeld Nutzungsbedingungen (Demo)
Stand: 2025-12-10
1. Anbieter und Kontakt
Georg Elser Institut fuer Angewandten Antifaschismus und Antiautoritarismusforschung
Koenig-Lothar-Platz 1, DE-01161 Dresden
Vertreten durch: Mirco da Silva, Amalie-Dietrich-Platz 9, DE-01169 Dresden
E-Mail: gamemaster@antifa.ltd
2. Zweck
Demogeld ist eine rein fiktive Waehrung ohne realen Gegenwert. Sie dient ausschliesslich zu
Demonstrations- und Spielzwecken (u.a. LLARP). Es besteht kein Anspruch auf Einloesung oder
Umtausch in gesetzliche Zahlungsmittel.
3. Registrierung und Nutzung
- Konten koennen mit realen oder fiktiven Daten angelegt werden.
- Die Nutzung erfolgt auf eigenes Risiko. Der Anbieter kann Konten jederzeit sperren oder loeschen.
- Technische Verfuegbarkeiten sind nicht garantiert; Wartungen und Ausfaelle sind jederzeit moeglich.
4. Haftungsausschluss
- Der Anbieter uebernimmt keine Haftung fuer Schaeden oder Verluste, die aus der Nutzung oder
Nichtnutzung von Demogeld entstehen.
- Keine Gewaehr fuer Verfuegbarkeit, Integritaet von Daten oder Funktionsfaehigkeit des Systems.
- Kein Finanzdienstleistungsangebot; keine Aufsicht durch Finanzbehoerden.
5. Datenschutz
Siehe separate Datenschutzerklaerung. Es werden nur Daten erhoben, die fuer den Betrieb des Demo-
Kontos erforderlich sind; diese duerfen fiktiv sein. Es erfolgt keine Weitergabe an Dritte ausser
zur technischen Bereitstellung.
6. Missbrauch und Inhalte
- Keine rechtswidrigen, volksverhetzenden oder diskriminierenden Inhalte.
- Kein Versuch, technische Sicherheitsmechanismen zu umgehen.
7. Aenderungen
Der Anbieter kann diese Bedingungen jederzeit aendern. Fortgesetzte Nutzung nach Aenderungen gilt
als Zustimmung.
8. Gerichtsstand/Recht
Es gilt deutsches Recht. Gerichtsstand (soweit vereinbar) ist Dresden.
9. Salvatorische Klausel
Sollten einzelne Bestimmungen unwirksam sein, bleibt der Rest wirksam; an ihre Stelle tritt die
gesetzliche Regelung.

View file

@ -0,0 +1,12 @@
[merchant]
CURRENCY = DEMOGELD
SERVE = tcp
PORT = 9966
BIND_TO = 0.0.0.0
[merchantdb-postgres]
CONFIG = postgres://talermerchant:taler@postgres:5432/talermerchant
[merchant-exchange-demogeld]
MASTER_KEY = ${MASTER_PUBLIC_KEY:-QZEPPYMSPF9RKNDCJ1SYMYY5RCV0Y0827SP2FZ9Z1J8C7PEW6CDG}
EXCHANGE_BASE_URLS = ${EXCHANGE_BASE_URL:-https://${EXCHANGE_HOST:-exchange.antifa.ltd}/}

View file

@ -0,0 +1,16 @@
#!/usr/bin/env bash
set -euo pipefail
exchange_pw="${TALER_EXCHANGE_DB_PASSWORD:-taler}"
merchant_pw="${TALER_MERCHANT_DB_PASSWORD:-taler}"
bank_pw="${LIBEUFIN_DB_PASSWORD:-taler}"
psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <<-EOSQL
CREATE USER talerexchange PASSWORD '${exchange_pw}';
CREATE USER talermerchant PASSWORD '${merchant_pw}';
CREATE USER libeufinbank PASSWORD '${bank_pw}';
CREATE DATABASE talerexchange OWNER talerexchange;
CREATE DATABASE talermerchant OWNER talermerchant;
CREATE DATABASE libeufinbank OWNER libeufinbank;
EOSQL

View file

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Helper to enable a bank account for the exchange via taler-exchange-offline.
# Run this inside the exchange container (where the master private key lives).
# Requires taler-exchange-offline and a valid master key in the secrets path.
set -euo pipefail
EXCHANGE_CONFIG="${EXCHANGE_CONFIG:-/etc/taler/taler-exchange.conf}"
PAYTO_URI="${PAYTO_URI:-payto://x-taler-bank/ob.antifa.ltd/demogeld?receiver-name=demogeld}"
OUT="${ENABLE_ACCOUNT_JSON:-/tmp/enable-account.json}"
EXCHANGE_KEYS_URL="${EXCHANGE_KEYS_URL:-http://exchange:8081/keys}"
EXCHANGE_WAIT_RETRIES="${EXCHANGE_WAIT_RETRIES:-60}"
EXCHANGE_WAIT_INTERVAL="${EXCHANGE_WAIT_INTERVAL:-2}"
EXCHANGE_CURL_OPTS="${EXCHANGE_CURL_OPTS:-}"
render_template() {
local src="$1"
local dst="$2"
if [[ -f "${src}" ]]; then
echo "Rendering template ${src} -> ${dst}"
envsubst < "${src}" > "${dst}"
fi
}
render_template /etc/taler/taler-exchange.conf.tmpl /etc/taler/taler-exchange.conf
render_template /etc/taler/conf.d/99-exchange.conf.tmpl /etc/taler/conf.d/99-exchange.conf
enabled_flag="${ENABLE_EXCHANGE_ACCOUNT:-0}"
case "${enabled_flag,,}" in
1|true|yes|on) ;;
*)
echo "ENABLE_EXCHANGE_ACCOUNT not set to true; skipping enable-account."
exit 0
;;
esac
echo "Using config: ${EXCHANGE_CONFIG}"
echo "Payto URI: ${PAYTO_URI}"
echo "Output JSON: ${OUT}"
echo "Waiting for exchange at: ${EXCHANGE_KEYS_URL}"
wait_for_exchange() {
local i
for ((i=1; i<=EXCHANGE_WAIT_RETRIES; i++)); do
if curl -fsS ${EXCHANGE_CURL_OPTS} "${EXCHANGE_KEYS_URL}" >/dev/null 2>&1; then
echo "Exchange reachable (attempt ${i})."
return 0
fi
sleep "${EXCHANGE_WAIT_INTERVAL}"
done
echo "Exchange not reachable after ${EXCHANGE_WAIT_RETRIES} attempts." >&2
return 1
}
wait_for_exchange
taler-exchange-offline -c "${EXCHANGE_CONFIG}" enable-account "${PAYTO_URI}" > "${OUT}"
echo "enable-account JSON written to ${OUT}"
taler-exchange-offline -c "${EXCHANGE_CONFIG}" upload < "${OUT}"
echo "Upload complete."

View file

@ -0,0 +1,77 @@
#!/usr/bin/env bash
# Provision LibEuFin bank users, debit limits and tokens via docker compose.
# Reads .env if present, then uses docker compose exec inside the bank container.
set -euo pipefail
if [[ -f ".env" ]]; then
set -a
# shellcheck disable=SC1091
source ".env"
set +a
fi
COMPOSE_CMD="${COMPOSE_CMD:-docker compose}"
BANK_SERVICE="${BANK_SERVICE:-bank}"
BANK_CONFIG="${BANK_CONFIG:-/etc/libeufin/bank.conf}"
USER="${LIBEUFIN_USER:-demogeld}"
USER_PASSWORD="${LIBEUFIN_USER_PASSWORD:-}"
DEBIT_THRESHOLD="${LIBEUFIN_DEBIT_THRESHOLD:-DEMOGELD:1000000}"
TOKEN_USER="${LIBEUFIN_MERCHANT_USER:-demogeldbank}"
TOKEN_PASSWORD="${LIBEUFIN_MERCHANT_PASSWORD:-}"
TOKEN_SCOPE="${LIBEUFIN_MERCHANT_SCOPE:-readwrite}"
TOKEN_DURATION="${LIBEUFIN_MERCHANT_TOKEN_DURATION:-forever}"
TOKEN_OUTPUT="${TOKEN_OUTPUT:-bank/token-info.txt}"
ensure_user() {
echo "Ensuring bank user '${USER}' exists (password will be set if provided)..."
if ! ${COMPOSE_CMD} exec -T "${BANK_SERVICE}" libeufin-bank users add "${USER}" --password "${USER_PASSWORD}" -c "${BANK_CONFIG}" >/tmp/libeufin-users-add.log 2>&1; then
if grep -qi "already exists" /tmp/libeufin-users-add.log; then
echo "User ${USER} already exists; proceeding."
else
echo "Failed to add user ${USER}:"
cat /tmp/libeufin-users-add.log
exit 1
fi
fi
echo "Setting debit threshold ${DEBIT_THRESHOLD} for ${USER}..."
${COMPOSE_CMD} exec -T "${BANK_SERVICE}" libeufin-bank edit-account "${USER}" \
--debit_threshold "${DEBIT_THRESHOLD}" -c "${BANK_CONFIG}"
}
provision_token() {
echo "Creating token for user '${TOKEN_USER}' (scope=${TOKEN_SCOPE}, duration=${TOKEN_DURATION})..."
local token_output
token_output="$(${COMPOSE_CMD} exec -T "${BANK_SERVICE}" libeufin-bank create-token \
-c "${BANK_CONFIG}" \
--user="${TOKEN_USER}" \
--scope="${TOKEN_SCOPE}" \
--duration="${TOKEN_DURATION}")"
echo "Token response:"
echo "${token_output}"
mkdir -p "$(dirname "${TOKEN_OUTPUT}")"
{
echo "# Generated $(date -Is)"
echo "USER=${TOKEN_USER}"
echo "SCOPE=${TOKEN_SCOPE}"
echo "DURATION=${TOKEN_DURATION}"
echo "${token_output}"
} > "${TOKEN_OUTPUT}"
echo "Token saved to ${TOKEN_OUTPUT}"
}
main() {
if [[ -z "${USER_PASSWORD}" || -z "${TOKEN_PASSWORD}" ]]; then
echo "Warning: LIBEUFIN_USER_PASSWORD or LIBEUFIN_MERCHANT_PASSWORD not set; user/token may be created without password enforcement." >&2
fi
ensure_user
provision_token
echo "Done."
}
main "$@"