Configuration
every variable, every setting.
.env starts the process; the Admin console holds everything else. This page lists every variable the code reads, its default and where the same setting lives in the console.
01Two places, one rule
| Where | What goes there | A change needs |
|---|---|---|
.env | The bootstrap: PORT, HOST, DATABASE_PATH, ADMIN_SECRET_KEY. Every other variable is a starting value. | A restart (sudo systemctl restart verified-calls) |
Admin console (/admin) | Brand, site address, Telegram chats, proof wallet, seal interval, method, earning options, integrations | Save. Most settings apply at once; the public address, log level and method apply after a restart. |
- A value in
.envis used until the same setting is saved in the console, which then wins. The start-up log lists the.envvalues in use. - The three secrets are the exception: when
TELEGRAM_BOT_TOKEN,SOLANA_RPC_URLorHELIUS_API_KEYis set in.env, the console field is locked and the.envvalue wins. - Secrets saved in the console are encrypted with
ADMIN_SECRET_KEYinadmin.sqlite(next to the database). Back the key and that file up together. pnpm startreads.envfrom the folder you start it in.ENV_FILE=/path/to/fileuses another file. Variables already set in the real environment win over.env.
02Bootstrap variables
| Variable | Default | Purpose |
|---|---|---|
ADMIN_SECRET_KEY Required | empty = console off | 32 random bytes as 64 hex characters (openssl rand -hex 32). Turns on the console and encrypts its secrets. Empty: /admin answers 503 with instructions; the public site and the bot keep running on .env. |
PORT | 8787 | Port the web server listens on. |
HOST | all interfaces | Interface to bind, e.g. 127.0.0.1 behind Caddy or nginx. |
DATABASE_PATH | data/verified-calls.db | The SQLite file. The folder is created if missing. The console keeps admin.sqlite in the same folder. |
ENV_FILE | .env | Read another configuration file. Set it in the real environment, not in .env. |
03Starting values (also in the console)
| Variable | Default | Purpose | Console |
|---|---|---|---|
TELEGRAM_BOT_TOKEN | empty | Your bot. Empty: the site runs read-only, nothing is recorded, seals are not posted. | Get started, Integrations (locked when set here) |
PUBLIC_BASE_URL | http://localhost:8787 | The public address, no trailing slash. Used in bot links and in the wallet-link message. Use https:// in production. | Site |
SITE_NAME | Verified Calls | Name in the header, the bot's /start text and the badge. | Brand → Product name |
ALLOWED_CHAT_IDS | empty | Comma-separated chat ids recorded without approval. Any other chat waits under Monitor → Chats. | Telegram |
SEAL_POST_CHAT_IDS | empty | Comma-separated chat ids the bot posts each seal to. In a channel the bot must be an admin allowed to post. | Telegram |
SOLANA_RPC_URL | https://api.mainnet-beta.solana.com | Builds the unsigned seal memo and checks it after you signed; reads VIP and listing payments. | Integrations (locked when set here) |
OPERATOR_WALLET | empty | The public address you sign seal memos with. Empty: "Sign with wallet" is disabled. | Proof |
SEAL_INTERVAL_MIN | 10 | Minutes between seals (1–10080). A seal is made only when there are new calls or coverage events. Keep it short: until a call is sealed the server owner could still drop it unseen. | Proof |
GECKOTERMINAL_RPM | 25 | Price requests per minute to GeckoTerminal's keyless API. Stay under their free limit. | Data sources |
HELIUS_API_KEY | empty | Enables exit-liquidity checks. Empty: every call shows "not checked", never "clean". | Integrations (locked when set here) |
EXIT_LIQUIDITY_USE_RPC | empty | true = exit-liquidity checks through your own SOLANA_RPC_URL instead of Helius. The public mainnet endpoint is refused. | Data sources |
BUY_URL_TEMPLATE | empty | A link on every call; {mint} becomes the token address. Must be https://. | Trading links → Custom link |
BUY_LABEL | empty = link host | Shown as "Buy on <label>". | Trading links → Custom link label |
LOG_LEVEL | info | debug, info, warn, error or silent (silent only in .env; the console offers the other four). Secrets are redacted from logs. | Data sources |
Example of a custom link, with a made-up terminal:
# Example only
BUY_URL_TEMPLATE=https://your-terminal.example/swap?out={mint}
BUY_LABEL=Your Terminal
Source: .env.example, src/core/config.ts, src/settings/schema.ts, src/admin/kit.ts.
04Scoring method
These change every number on the site. /methodology always shows the values in use. Decide before you publish and announce any change. The first five are also in the console under Method; all apply after a restart.
| Variable | Default | Meaning |
|---|---|---|
SCORING_ENTRY_DELAY_SEC | 30 | Seconds after the post a follower is modelled to buy. |
SCORING_FEE_BPS | 100 | Fee per side in basis points (100 = 1 %). |
SCORING_SLIPPAGE_BPS | 150 | Minimum slippage per side; thin pools get more (liquidity-aware). |
SCORING_MIN_CALLS | 5 | Scored calls needed to be ranked. |
SCORING_SHRINKAGE_K | 10 | How strongly a small record is pulled toward the group median. |
SCORING_HIT_THRESHOLD | 0.5 | Net result counted as a hit (+50 %). |
SCORING_RUG_THRESHOLD | -0.9 | Net result counted as a rug (−90 %). Must be lower than the hit threshold, or the app refuses to start. |
SCORING_EXIT_LIQUIDITY_WINDOW_MIN | 60 | Minutes after a call in which a linked wallet's sale is flagged. |
SCORING_MAX_ENTRY_GAP_SEC | 300 | No trade within this time after the entry delay: the call is "unpriceable". |
Advanced (not in .env.example; defaults and formulas in SPEC.md): SCORING_MAX_PRICE_SOURCE_RATIO, SCORING_FOLLOWER_SIZE_USD, SCORING_LIQUIDITY_SLIPPAGE_K, SCORING_MAX_SLIPPAGE_BPS, SCORING_LIQUIDITY_FLOOR_USD, SCORING_PRE_RUNUP_THRESHOLD, SCORING_PRE_RUNUP_WINDOW_MIN, SCORING_EXIT_VWAP_MIN, SCORING_ENTRY_VWAP_MIN.
After changing the method, recompute the stored results so every call is scored the same way:
sudo systemctl stop verified-calls
pnpm exec tsx scripts/recompute.ts --dry-run # shows what would change
pnpm exec tsx scripts/recompute.ts
sudo systemctl start verified-calls
The script reads only the database and never calls a price API. Calls, seals and proofs are never touched. Exit 0 = done, 1 = some rows could not be recomputed (listed).
05Console-only settings
These have no .env variable: reply cards, the groups directory, integrity rules, API keys and every earning option (trading-link codes, Jupiter swap, VIP plans, paid listings, sponsored slot). See Admin console and Earnings.