You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
API and monitoring services for Swipely, a cross-chain bridge and DEX
liquidity monitoring platform for the Stellar network. This service ingests
on-chain and off-chain data, computes bridge-health and liquidity metrics,
exposes a REST + WebSocket API, and dispatches alerts.
Tech stack
Node.js + TypeScript
Fastify 5 (REST, WebSockets, Swagger/OpenAPI)
PostgreSQL via Knex (migrations + seeds)
Redis + BullMQ for queues and background jobs
@stellar/stellar-sdk and ethers for chain access
Prometheus (prom-client) metrics, pino logging
Alerting via Discord, Telegram, and email (nodemailer)
Zod for validation, Vitest for tests
Getting started
npm install
cp .env.example .env # then fill in the values
npm run migrate # apply database migrations
npm run dev # start the API in watch mode
Useful scripts
Script
Description
npm run dev
Start the API with hot reload
npm run build
Compile TypeScript to dist/
npm start
Run the compiled server
npm run migrate
Apply migrations
npm run seed
Seed the database
npm run test
Run the test suite
npm run docs:generate
Generate the OpenAPI spec
Observability
Prometheus scrape config, alert rules, and a Grafana dashboard live alongside the
service (prometheus.yml, prometheus-alerts.yml, grafana/). See
METRICS_QUICKSTART.md for a fast local setup.
Environment variables
All variables are validated at startup by a Zod schema in
src/config/index.ts. The process exits immediately with a clear error if any
required variable is missing or malformed. Secret values are never included
in error output — only the variable name appears.
Copy .env.example to .env and fill in the values. The table below lists
every variable the app reads.
Legend — Required ★ means the app will not start without it in production.
Variables with a default are optional everywhere.
Application
Variable
Purpose
Default
Required
NODE_ENV
Runtime environment
development
—
PORT
HTTP server port
3001
—
WS_PORT
WebSocket server port
3002
—
CORS_ALLOWED_ORIGINS
Comma-separated allowed CORS origins (production)
—
—
Security
Variable
Purpose
Default
Required
JWT_SECRET
Signs export download tokens (min 32 chars)
—
★ production
CONFIG_ENCRYPTION_KEY
Encrypts sensitive config values at rest (min 32 chars)
—
★ production
API_KEY_BOOTSTRAP_TOKEN
Seeds the first admin API key on first run
—
—
PostgreSQL / TimescaleDB
Variable
Purpose
Default
Required
POSTGRES_HOST
Database host
localhost
—
POSTGRES_PORT
Database port
5432
—
POSTGRES_DB
Database name
bridge_watch
—
POSTGRES_USER
Database user
bridge_watch
—
POSTGRES_PASSWORD
Database password
bridge_watch_dev
★ production
Redis
Variable
Purpose
Default
Required
REDIS_HOST
Redis host
localhost
—
REDIS_PORT
Redis port
6379
—
REDIS_PASSWORD
Redis auth password
""
—
REDIS_CLUSTER
Set "true" to enable Cluster mode in production
—
—
Stellar
Variable
Purpose
Default
Required
STELLAR_NETWORK
testnet or mainnet
testnet
—
STELLAR_HORIZON_URL
Horizon endpoint
https://horizon-testnet.stellar.org
—
SOROBAN_RPC_URL
Soroban RPC endpoint
https://soroban-testnet.stellar.org
—
SOROBAN_MAINNET_RPC_URL
Mainnet Soroban RPC endpoint
—
—
CIRCUIT_BREAKER_CONTRACT_ID
Soroban circuit-breaker contract
—
—
LIQUIDITY_CONTRACT_ADDRESS
Soroban liquidity contract
—
—
Ethereum / EVM
Variable
Purpose
Default
Required
ETHEREUM_RPC_URL
Ethereum JSON-RPC endpoint
—
—
ETHEREUM_RPC_WS_URL
Ethereum WebSocket RPC endpoint
—
—
ETHEREUM_RPC_FALLBACK_URL
Fallback Ethereum RPC
—
—
RPC_PROVIDER_TYPE
http or ws
http
—
USDC_BRIDGE_ADDRESS
USDC bridge contract address
—
—
EURC_BRIDGE_ADDRESS
EURC bridge contract address
—
—
USDC_TOKEN_ADDRESS
USDC ERC-20 token address
—
—
EURC_TOKEN_ADDRESS
EURC ERC-20 token address
—
—
POLYGON_RPC_URL
Polygon RPC endpoint
—
—
POLYGON_RPC_FALLBACK_URL
Fallback Polygon RPC
—
—
BASE_RPC_URL
Base chain RPC endpoint
—
—
BASE_RPC_FALLBACK_URL
Fallback Base chain RPC
—
—
External APIs
Variable
Purpose
Default
Required
CIRCLE_API_KEY
Circle API key for USDC/EURC data
—
—
CIRCLE_API_URL
Circle API base URL
https://api.circle.com
—
CIRCLE_API_TIMEOUT_MS
Circle request timeout (ms)
5000
—
CIRCLE_CACHE_TTL_SEC
Redis TTL for Circle responses (s)
60
—
CIRCLE_RATE_LIMIT_MAX
Circle rate-limit max requests per window
30
—
CIRCLE_RATE_LIMIT_WINDOW_MS
Circle rate-limit window (ms)
60000
—
COINBASE_API_KEY
Coinbase Advanced Trade API key
—
—
COINBASE_API_SECRET
Coinbase Advanced Trade API secret
—
—
ONEINCH_API_KEY
1inch EVM DEX aggregator API key
—
—
COINMARKETCAP_API_KEY
CoinMarketCap API key
—
—
COINGECKO_API_KEY
CoinGecko demo API key (higher rate limits)
—
—
Logging
Variable
Purpose
Default
Required
LOG_LEVEL
Minimum log level (fatal…trace)
info
—
LOG_FILE
Write logs to file path (production)
—
—
LOG_MAX_FILE_SIZE
Max log file size in bytes
104857600
—
LOG_MAX_FILES
Max number of rotated log files
10
—
LOG_RETENTION_DAYS
Days to retain log files
30
—
LOG_REQUEST_BODY
Log incoming request bodies
false
—
LOG_RESPONSE_BODY
Log outgoing response bodies
false
—
LOG_SENSITIVE_DATA
Allow sensitive data in logs (must be false in prod)