System-level half of the lamassu → bitspire rebrand the rest of dev already did at the path / service / package layers. Touches user/group declarations, every systemd `User=` block, the udev rules filename, all chown calls in flake.nix + live.nix, the displayManager autoLogin user, the trusted-users nix entry, provision-atm.sh's ATM_USER, plus README + CLAUDE.md doc references. In-place migration for the Sintra dev unit (which auto-pulls dev at 04:00) lives in `system.activationScripts.bitspire-user-migration` and: - copies `/home/lamassu/.ssh/authorized_keys` → `/home/bitspire/` once, so SSH access survives the rename - recursively chowns `/var/lib/bitspire` to the new bitspire UID on every boot — cheap no-op once done, but covers the case where the data dir was written by the now-removed lamassu UID - leaves `/home/lamassu/` in place as evidence; operator can `rm -rf` after confirming bitspire login works Recovery path if the migration breaks SSH access: root key is still in configuration.nix:142-144 (padreug@gizmo), so ssh root@<host> works. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
118 lines
4.5 KiB
Bash
Executable file
118 lines
4.5 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Provision a running bitSpire ATM (live USB, QEMU VM, or installed Sintra)
|
|
# with LNbits nostr-transport credentials. The ATM speaks to LNbits over
|
|
# kind-21000 NIP-44 v2 events on a relay — there is no out-of-band token,
|
|
# the ATM's nostr private key IS the credential. # pragma: allowlist secret
|
|
#
|
|
# Required environment variables (or edit defaults below):
|
|
# LNBITS_SERVER_PUBKEY Hex pubkey published by the LNbits server at startup.
|
|
# From the LNbits compose:
|
|
# docker logs lnbits | grep 'nostr_transport pubkey'
|
|
# LNBITS_HTTP_URL Origin LNbits is reachable at over HTTP, used only
|
|
# to compose the LNURL-withdraw callback URL that
|
|
# customer wallets dereference. Default: http://10.0.2.2:5000
|
|
# RELAY_URL Nostr relay LNbits subscribes on. Default uses host gateway.
|
|
# ATM_PRIVATE_KEY 32-byte hex key, ATM's nostr identity. If unset, a
|
|
# fresh key is generated and saved in the .env.
|
|
#
|
|
# Usage:
|
|
# bash provision-atm.sh # defaults: SSH to localhost:2222 (QEMU)
|
|
# bash provision-atm.sh 192.168.1.50 # SSH to a real ATM on the LAN
|
|
# bash provision-atm.sh 192.168.1.50 22 # custom SSH port
|
|
set -euo pipefail
|
|
|
|
ATM_HOST="${1:-localhost}"
|
|
ATM_SSH_PORT="${2:-2222}"
|
|
ATM_USER="bitspire"
|
|
|
|
# Machine model + fiat. Model is operator-set; fiat defaults per-model to
|
|
# match the flake's fiatCodeForModel table (sintra=EUR, douro/tejo=GTQ,
|
|
# batm3=USD). Operators can override either via env var.
|
|
MODEL="${MODEL:-sintra}"
|
|
case "${FIAT_CODE:-}" in
|
|
"")
|
|
case "$MODEL" in
|
|
sintra) FIAT_CODE=EUR ;;
|
|
douro|tejo) FIAT_CODE=GTQ ;;
|
|
batm3) FIAT_CODE=USD ;;
|
|
*) FIAT_CODE=USD ;;
|
|
esac
|
|
;;
|
|
esac
|
|
|
|
echo "=== Provisioning bitSpire ATM at $ATM_HOST:$ATM_SSH_PORT ==="
|
|
|
|
# Step 1: Discover the host IP as seen from the ATM.
|
|
# QEMU user-mode networking puts the host at 10.0.2.2; on real LAN ATMs
|
|
# use the dev machine's outbound LAN address.
|
|
if [ "$ATM_HOST" = "localhost" ]; then
|
|
HOST_IP="10.0.2.2"
|
|
echo ""
|
|
echo "--- QEMU detected: using $HOST_IP as host gateway ---"
|
|
else
|
|
HOST_IP=$(ip -4 route get 1 | awk '{print $7; exit}')
|
|
echo ""
|
|
echo "--- LAN ATM: using $HOST_IP as dev machine address ---"
|
|
fi
|
|
|
|
# Step 2: Resolve the LNbits server pubkey. Prefer the env override; else
|
|
# fall back to scraping the local docker compose stack.
|
|
if [ -z "${LNBITS_SERVER_PUBKEY:-}" ]; then
|
|
echo ""
|
|
echo "--- Step 1: Extracting LNbits nostr-transport pubkey from docker logs ---"
|
|
LNBITS_SERVER_PUBKEY=$(docker logs lnbits 2>&1 \
|
|
| grep -oP 'nostr_transport pubkey:?\s*\K[a-f0-9]{64}' \
|
|
| tail -1 || true)
|
|
if [ -z "$LNBITS_SERVER_PUBKEY" ]; then
|
|
echo "ERROR: Could not extract LNbits pubkey. Set LNBITS_SERVER_PUBKEY explicitly"
|
|
echo "or start the LNbits stack first (docker compose -f docker/docker-compose.dev.yml up lnbits)."
|
|
exit 1
|
|
fi
|
|
fi
|
|
echo "LNbits server pubkey: ${LNBITS_SERVER_PUBKEY:0:16}..."
|
|
|
|
# Step 3: Pin LNbits HTTP origin.
|
|
LNBITS_HTTP_URL="${LNBITS_HTTP_URL:-http://$HOST_IP:5000}"
|
|
|
|
# Step 4: Relay URL.
|
|
RELAY_URL="${RELAY_URL:-ws://$HOST_IP:7777}"
|
|
|
|
# Step 5: ATM identity. Generate if unset.
|
|
if [ -z "${ATM_PRIVATE_KEY:-}" ]; then
|
|
ATM_PRIVATE_KEY=$(openssl rand -hex 32)
|
|
echo ""
|
|
echo "--- Generated fresh ATM_PRIVATE_KEY (save this if you want it persisted) ---"
|
|
fi
|
|
|
|
# Step 6: Write .env to the ATM via SSH.
|
|
echo ""
|
|
echo "--- Step 2: Writing .env to ATM ---"
|
|
ENV_CONTENT="# bitSpire Configuration
|
|
# Auto-generated by provision-atm.sh on $(date -Iseconds)
|
|
|
|
# LNbits nostr-transport connection
|
|
VITE_RELAY_URL=$RELAY_URL
|
|
VITE_LNBITS_SERVER_PUBKEY=$LNBITS_SERVER_PUBKEY
|
|
VITE_LNBITS_HTTP_URL=$LNBITS_HTTP_URL
|
|
|
|
# ATM identity (signing key IS the credential under nostr-transport)
|
|
VITE_ATM_PRIVATE_KEY=$ATM_PRIVATE_KEY
|
|
|
|
# Machine configuration
|
|
VITE_LAMASSU_MACHINE_MODEL=$MODEL
|
|
VITE_LAMASSU_FIAT_CODE=$FIAT_CODE
|
|
|
|
# Force production mode
|
|
ELECTRON_FORCE_PROD=1
|
|
DISPLAY=:0"
|
|
|
|
ssh -o StrictHostKeyChecking=no -p "$ATM_SSH_PORT" "$ATM_USER@$ATM_HOST" \
|
|
"echo '$ENV_CONTENT' | sudo tee /var/lib/bitspire/.env > /dev/null && sudo systemctl restart bitspire"
|
|
|
|
echo ""
|
|
echo "=== ATM provisioned successfully ==="
|
|
echo ""
|
|
echo "Credentials written to /var/lib/bitspire/.env"
|
|
echo "ATM service restarted. It should connect to LNbits via relay $RELAY_URL."
|
|
echo ""
|
|
echo "To check status: ssh -p $ATM_SSH_PORT $ATM_USER@$ATM_HOST 'sudo journalctl -u bitspire -f'"
|