Verified Calls docs
v1.1.0
Live demo Get help
● Start · Production

Installation
your own server, with HTTPS.

A complete production install on an Ubuntu VPS: a system user, the app as a systemd service and Caddy in front for automatic HTTPS. Any Linux host with a persistent disk works the same way.

01What you will set up

  1. Node.js 22, pnpm and build tools.
  2. The app in /opt/verified-calls, run by its own user.
  3. .env with the console key and your public address.
  4. A systemd service that restarts on failure.
  5. Caddy as a reverse proxy with an automatic certificate.
  6. The console owner, the bot and your first chat.
Standard Ubuntu steps

These are the usual Ubuntu, systemd and Caddy procedures. The app commands themselves (pnpm install, pnpm build, pnpm start) are the same as in the Quick start.

02Which computer runs the commands

The commands on this page are typed in a terminal on the server, which is a Linux machine (Ubuntu in the examples). You connect to it from your own computer with ssh.

  • macOS or Linux: open the Terminal app and run ssh root@your-server-ip; everything else is the same as shown here.
  • Windows: use the built-in Windows Terminal / PowerShell only for ssh. To run the app or the shell commands on your own PC (for a local trial), install WSL 2 with Ubuntu (wsl --install in an administrator PowerShell, then restart) and run every command inside the Ubuntu window. Git Bash works for ssh and openssl, but not for building better-sqlite3; use WSL 2 for that.
  • Lines that start with # are comments: you do not type them.

03Prepare the server

# Node.js 22 (NodeSource), pnpm and build tools
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -
sudo apt install -y nodejs build-essential python3 sqlite3
sudo npm install -g pnpm
# a user for the service
sudo useradd --system --create-home --home-dir /opt/verified-calls --shell /usr/sbin/nologin verified-calls

04Install the app

# upload the package, then:
sudo unzip verified-calls.zip -d /opt/verified-calls
sudo chown -R verified-calls:verified-calls /opt/verified-calls
cd /opt/verified-calls
sudo -u verified-calls pnpm install --frozen-lockfile
sudo -u verified-calls pnpm build      # compiles to dist/ (plain JavaScript)
sudo -u verified-calls cp .env.example .env

Adjust the unzip path so that package.json ends up directly in /opt/verified-calls.

05Fill in .env

Open /opt/verified-calls/.env and set at least:

ADMIN_SECRET_KEY=output of: openssl rand -hex 32
PUBLIC_BASE_URL=https://calls.example.com
HOST=127.0.0.1
PORT=8787
  • HOST=127.0.0.1 keeps the app reachable only through Caddy.
  • Everything else (bot token, name, chats, wallet, RPC, method) is set in the console. See Configuration.
  • Keep .env readable only by the service: sudo chmod 600 .env.

06Run it as a service

# /etc/systemd/system/verified-calls.service
[Unit]
Description=Verified Calls
After=network-online.target

[Service]
WorkingDirectory=/opt/verified-calls
ExecStart=/usr/bin/node dist/src/index.js
Restart=always
User=verified-calls
Environment=NODE_ENV=production

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now verified-calls
journalctl -u verified-calls -f      # follow the log

The service runs the compiled JavaScript with plain node; no TypeScript loader is involved. If which node prints another path than /usr/bin/node (for example with nvm), use that path in ExecStart.

On SIGINT or SIGTERM the process stops the bot, finishes the running job, closes the web server and closes the database cleanly. A second signal exits at once.

07HTTPS with Caddy

# /etc/caddy/Caddyfile
calls.example.com {
    reverse_proxy 127.0.0.1:8787
}
sudo systemctl reload caddy

Point the domain's DNS A record at the server first; Caddy then gets the certificate by itself. nginx works too: forward to 127.0.0.1:8787.

08Create the console owner

  1. Find the setup codejournalctl -u verified-calls | grep setupCode. It is printed on every start until an owner exists; a restart prints a new code.
  2. Open the consolehttps://calls.example.com/admin. Enter the code, your email and a password of 12 or more characters.
  3. Turn on two-factorConsole → Security & alerts.
  4. Set the basicsConsole → Get started: product name, accent colour, support email, public address and the bot token (with Test). See Admin console.

09Bot and first chat

Follow Telegram bot → Setup: privacy mode off, add the bot, approve the chat under Monitor → Chats, then switch off "allow groups" in @BotFather so strangers cannot add your bot.

10Go-live checklist

  • Console → Monitor → Status: every check green, "A chat is recording" and "Public address is https" included.
  • A test call appears on the site within about a minute.
  • Seal chats set (Telegram → Chats the seals are posted to) and the first seal posted.
  • Operator wallet set (Proof) and the first seal anchored from Monitor → Seals.
  • Scoring method decided before you publish (Method); /methodology shows it.
  • Daily backups running (how), ADMIN_SECRET_KEY stored safely.