Adds cvm-server/ directory with complete ContextVM server implementation: - server.ts: Full MCP server with 5 tools (find_spots, find_events, find_coaches, find_gear, get_community_stats) using @contextvm/sdk - bootstrap.sh: One-command VPS setup script (Bun, PM2, firewall, keygen) - skatespots-cvm.service: systemd unit for production deployment - .env.example: Environment variable template - DEPLOY.md: Step-by-step deploy guide for LNVPS VPS - package.cvm.json: Dependencies manifest The server aggregates data from goskatespots.nostr1.com and other relays, deduplicates addressable events, and exposes structured JSON tools that AI agents can discover and call via the ContextVM/Nostr protocol (CEP-6). Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
119 lines
6.3 KiB
Bash
119 lines
6.3 KiB
Bash
#!/bin/bash
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
# SkateSpots CVM Server — Bootstrap Script
|
||
# Run this ONCE on a fresh LNVPS Ubuntu 22.04 VPS as root:
|
||
# curl -fsSL https://raw.githubusercontent.com/YOUR_REPO/bootstrap.sh | bash
|
||
# OR copy-paste the whole file into your SSH session.
|
||
# ─────────────────────────────────────────────────────────────────────────────
|
||
|
||
set -e # Exit on any error
|
||
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo " 🛹 SkateSpots CVM Server Bootstrap"
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
||
# ── 1. System update ─────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [1/8] Updating system packages..."
|
||
apt-get update -qq
|
||
apt-get upgrade -y -qq
|
||
apt-get install -y -qq curl git ufw fail2ban htop nano
|
||
|
||
# ── 2. Firewall ──────────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [2/8] Configuring firewall..."
|
||
ufw --force reset
|
||
ufw default deny incoming
|
||
ufw default allow outgoing
|
||
ufw allow 22/tcp comment 'SSH'
|
||
# NOTE: CVM server needs NO open inbound ports — it connects OUT to Nostr relays
|
||
ufw --force enable
|
||
echo " ✅ Firewall: only SSH allowed inbound"
|
||
|
||
# ── 3. fail2ban ──────────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [3/8] Enabling fail2ban..."
|
||
systemctl enable fail2ban --quiet
|
||
systemctl start fail2ban
|
||
echo " ✅ fail2ban active"
|
||
|
||
# ── 4. Create skate user ─────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [4/8] Creating 'skate' system user..."
|
||
if id "skate" &>/dev/null; then
|
||
echo " ℹ User 'skate' already exists, skipping"
|
||
else
|
||
useradd -m -s /bin/bash skate
|
||
echo " ✅ User 'skate' created"
|
||
fi
|
||
|
||
# ── 5. Install Bun ───────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [5/8] Installing Bun runtime..."
|
||
export BUN_INSTALL="/home/skate/.bun"
|
||
su - skate -c 'curl -fsSL https://bun.sh/install | bash' 2>/dev/null
|
||
# Make bun available system-wide
|
||
ln -sf /home/skate/.bun/bin/bun /usr/local/bin/bun 2>/dev/null || true
|
||
echo " ✅ Bun installed: $(bun --version 2>/dev/null || echo 'check /home/skate/.bun/bin/bun')"
|
||
|
||
# ── 6. Create project directory ──────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [6/8] Setting up project directory..."
|
||
mkdir -p /home/skate/skatespots-cvm
|
||
chown -R skate:skate /home/skate/skatespots-cvm
|
||
|
||
# ── 7. Install PM2 ───────────────────────────────────────────────────────────
|
||
echo ""
|
||
echo "▶ [7/8] Installing PM2 process manager..."
|
||
# Install Node.js LTS first (needed for PM2)
|
||
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - 2>/dev/null
|
||
apt-get install -y -qq nodejs
|
||
npm install -g pm2 --silent
|
||
echo " ✅ PM2 installed: $(pm2 --version)"
|
||
|
||
# ── 8. Generate Nostr keypair for the CVM server ─────────────────────────────
|
||
echo ""
|
||
echo "▶ [8/8] Generating Nostr keypair for CVM server..."
|
||
cat > /tmp/gen-keys.ts << 'GENKEYS'
|
||
import { generateSecretKey, getPublicKey, nip19 } from "nostr-tools";
|
||
import { bytesToHex } from "@noble/hashes/utils";
|
||
|
||
const sk = generateSecretKey();
|
||
const pkHex = getPublicKey(sk);
|
||
const nsec = nip19.nsecEncode(sk);
|
||
const npub = nip19.npubEncode(pkHex);
|
||
|
||
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
||
console.log(" 🔑 CVM Server Nostr Keys — SAVE THESE NOW");
|
||
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
||
console.log("");
|
||
console.log(" PRIVATE KEY (hex) — goes in .env as CVM_SERVER_NSEC_HEX");
|
||
console.log(" ", bytesToHex(sk));
|
||
console.log("");
|
||
console.log(" NSEC (bech32) — backup this too");
|
||
console.log(" ", nsec);
|
||
console.log("");
|
||
console.log(" PUBLIC KEY (hex) — your server's identity on Nostr");
|
||
console.log(" ", pkHex);
|
||
console.log("");
|
||
console.log(" NPUB (bech32) — share this so agents can find you");
|
||
console.log(" ", npub);
|
||
console.log("");
|
||
console.log(" ⚠️ NEVER share the private key / nsec with anyone!");
|
||
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
||
GENKEYS
|
||
|
||
# Run key generation using bun with a temp nostr-tools install
|
||
cd /tmp
|
||
su - skate -c "cd /tmp && /home/skate/.bun/bin/bun add nostr-tools @noble/hashes 2>/dev/null && /home/skate/.bun/bin/bun run /tmp/gen-keys.ts"
|
||
|
||
echo ""
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
echo " ✅ Bootstrap complete!"
|
||
echo ""
|
||
echo " Next steps:"
|
||
echo " 1. Copy the PRIVATE KEY (hex) printed above"
|
||
echo " 2. cd /home/skate/skatespots-cvm"
|
||
echo " 3. Run: nano .env (paste your key there)"
|
||
echo " 4. Run: bun run setup.sh (installs the server)"
|
||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|