#!/usr/bin/env sh # Toknx CLI installer. curl -fsSL https://toknx.ai/cli/install.sh | sh # Installs into ~/.tokenbarter (its own venv) and links `tb` into ~/.local/bin. # Needs python3 (3.9+). Re-run to update. Nothing runs as root. # # What this checks: every file it downloads (tb.py, runner.py, policy.py and the # dependency list) must match the SHA-256 written below, or nothing is installed; # every Python package is pinned to one version and its published hashes # (pip --require-hashes), so a changed package is refused. What it cannot check: # this script itself, which you fetch over HTTPS from toknx.ai; read it first if # you like (curl -fsSL https://toknx.ai/cli/install.sh | less). tb never updates # itself: re-running this script is the only update path, with the same checks. set -eu BASE="${BARTER_URL:-https://toknx.ai}" DIR="$HOME/.tokenbarter" BIN="$HOME/.local/bin" command -v python3 >/dev/null 2>&1 || { echo "python3 is required (3.9+)"; exit 1; } # BEGIN HASHES (written by scripts/cli_hashes.py; tests/test_answerer_safety.py checks them) SHA_TB=b2a1354a36b64e6dd7c89693bb6d7adf5d90d5a391d38eab8822490dd131ebfa SHA_RUNNER=e738fe8fd130662b91fcbab2918c72c435100799b8773ea7979d27b36598c688 SHA_POLICY=46ec78f87a2a2759fd8edb6a0f0ea8d3f63817720a903cf4bd1e18ff134edf21 SHA_LOCK=b2d882a858108ea23b8fb1a6333accdcaf9efe460d8f92ad5bee29e74cb0bedf # END HASHES TMP="$(mktemp -d)" trap 'rm -rf "$TMP"' EXIT INT TERM fetch() { # fetch NAME EXPECTED_SHA256: download to a temporary file, refuse it unless the hash matches curl -fsSL "$BASE/cli/$1" -o "$TMP/$1" got="$(python3 -c 'import hashlib, sys; print(hashlib.sha256(open(sys.argv[1], "rb").read()).hexdigest())' "$TMP/$1")" if [ "$got" != "$2" ]; then echo "refusing to install: $1 does not match its published SHA-256 (got $got, expected $2)." >&2 echo "Nothing was changed. If this persists, write to support@toknx.ai." >&2 exit 1 fi } fetch tb.py "$SHA_TB" fetch runner.py "$SHA_RUNNER" fetch policy.py "$SHA_POLICY" fetch requirements.lock "$SHA_LOCK" # Every download checked: only now is anything put in place. mkdir -p "$DIR/app" "$BIN" if [ ! -x "$DIR/venv/bin/python" ]; then python3 -m venv "$DIR/venv"; fi # Prebuilt, hash-checked packages only: building from source would fetch build tools that no hash covers. if ! "$DIR/venv/bin/python" -m pip install -q --require-hashes --only-binary=:all: -r "$TMP/requirements.lock"; then echo "refusing to install: no prebuilt, hash-checked package for this computer and Python version." >&2 echo "Use Python 3.9-3.13 on macOS, Windows or 64-bit Linux, or write to support@toknx.ai." >&2 exit 1 fi cp "$TMP/tb.py" "$DIR/tb.py" cp "$TMP/runner.py" "$DIR/runner.py" cp "$TMP/policy.py" "$DIR/app/policy.py" : > "$DIR/app/__init__.py" cat > "$BIN/tb" <