Testing the API
Two kinds of check: the unit tests, which need no running server, and a smoke test that calls a
running API over HTTP. Both run from apps/api.
Unit tests
cd apps/api
bun test srcChanges to the API also need the member app's tests, because some of them read API source (Setting up → Before you push).
Smoke test
test-api.ts calls the health, price, balance, token-balance and
transaction endpoints, singly and in batches, and reports each as passed or failed. It calls
http://localhost:3001 unless API_BASE_URL is set.
cd apps/api
bun run dev # in one terminal
bun run test # in another: runs bun test-api.tsCalling endpoints by hand
The examples use chain 1 (Ethereum) and well-known mainnet addresses, as the smoke test does. Any
chain the API's RPC provider serves works the same way.
Health
curl http://localhost:3001/health{"status":"ok","timestamp":"…","redis":"connected"}redis is disconnected when Redis is not reachable; the API still answers.
Token price
curl http://localhost:3001/api/prices/1/0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2{"price":…,"cached":false,"timestamp":…}Native balance
curl http://localhost:3001/api/balances/1/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045{"balance":"…","balanceWei":"…","balanceUSD":0,"cached":false,"timestamp":…}balanceUSD is always 0; the client multiplies by the current price.
Token balance
curl http://localhost:3001/api/token-balances/1/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045/0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48Transactions
curl "http://localhost:3001/api/transactions/1/0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045?limit=5"{"transactions":[…],"cached":false,"timestamp":…}Caching
With Redis connected, the second identical request within the cache window returns
"cached": true. The windows are set by CACHE_TTL_PRICE (300 seconds by default),
CACHE_TTL_BALANCE and CACHE_TTL_TRANSACTION (600 seconds each). Without Redis, every response is
"cached": false.
Common problems
curl <api-host>/health), and its logs on the hostCORS_ORIGIN (Going live → Cross-origin)redis: "disconnected"503DATABASE_URL is not set; routes backed by the member store need Postgres