// Settings come from the environment, or from a .env file next to package.json (see .env.example). // Every setting has a default: OScope runs with no .env at all. import fs from 'node:fs'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; export const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); // .env: KEY=value lines; a value already set in the environment wins try { for (const line of fs.readFileSync(path.join(ROOT, '.env'), 'utf8').split(/\r?\n/)) { const m = line.match(/^\s*([A-Z_][A-Z0-9_]*)\s*=\s*(.*?)\s*$/i); if (m && process.env[m[1]] == null) process.env[m[1]] = m[2].replace(/^(['"])(.*)\1$/, '$2'); } } catch {} const env = process.env; const num = (v, d) => (v != null && v !== '' && Number.isFinite(+v) ? +v : d); export const config = { port: num(env.PORT, 3000), portFixed: env.PORT != null && env.PORT !== '', // a port you chose is never swapped for a free one host: env.HOST || '127.0.0.1', // Live pump.fun + PumpSwap trade stream (JSON, one message per transaction). Free, no key, no sign-up. feedUrl: env.FEED_URL || 'wss://stream.pumpapi.io/', // OScope shares its one stream connection at ws://localhost:/firehose for your own tools. "off" turns it off. firehose: (env.FIREHOSE || 'on').toLowerCase() !== 'off', dataDir: path.resolve(ROOT, env.DATA_DIR || 'data'), // Public IPFS gateways asked for coin pictures and metadata, in this order (comma separated, each ending in /ipfs/). ipfsGateways: (env.IPFS_GATEWAYS || 'https://ipfs.filebase.io/ipfs/,https://4everland.io/ipfs/,https://pump.mypinata.cloud/ipfs/').split(',').map(s => s.trim()).filter(s => /^https:\/\/[^\s]+\/ipfs\/$/.test(s)), // A curve coin moves from New Pairs to Final Stretch at this bonding-curve progress (percent). stretchAt: num(env.STRETCH_AT, 60), // New Pairs keeps coins younger than this (minutes). newMaxAgeMin: num(env.NEW_MAX_AGE_MIN, 60), // Coins kept per Pulse column (the page filters further). columnCap: num(env.COLUMN_CAP, 80), // Trades kept in memory per coin that is on screen, open or young (the coin page's trade list reads these). tradeCap: num(env.TRADE_CAP, 1000), // Quiet coins are dropped from memory after this many minutes without a trade. idleDropMin: num(env.IDLE_DROP_MIN, 120), // Coins kept in memory at most; the ones traded least recently go first. maxCoins: num(env.MAX_COINS, 6000), // A line in the terminal every N seconds saying how many trades came in (0 = off). logEvery: num(env.LOG_EVERY, 15), };