Welcome! This guide takes a new contributor from a fresh clone to a running local development environment for the Invoice Liquidity Network frontend.
Verified against the current repository setup: Next.js 16.2.4, React 19.2.4, Node 20.9.0, pnpm 9, Husky 9, Supabase-gated reminders, Resend-gated email delivery, and Freighter on Stellar Testnet.
The repo pins Node in .nvmrc and package.json requires Node >=20.9.0 <21.
node --versionRecommended install with nvm:
nvm install 20.9.0
nvm useThis project uses pnpm in CI and commits pnpm-lock.yaml.
corepack enable
corepack prepare pnpm@9.0.0 --activate
pnpm --versionInstall Freighter, create or import a wallet, and switch the wallet network to Testnet before trying to submit, fund, pay, or dispute invoices.
- Chrome/Brave: Chrome Web Store
- Firefox: Firefox Add-ons
- Wallet docs: freighter.app
The app can run without Stellar CLI, but it is useful for advanced testnet checks.
brew install stellar-cligit clone https://github.com/Invoice-Liquidity-Network/ILN-Frontend.git
cd ILN-Frontendpnpm installThe prepare script runs Husky during install. After a successful install, .husky/pre-commit runs lint-staged and .husky/pre-push runs tsc --noEmit.
cp .env.local.example .env.localThe checked-in example contains safe defaults for Stellar Testnet and placeholders for env-gated integrations. Local UI development works with the testnet defaults, but these integrations require real credentials:
| Integration | Variables | Required when |
|---|---|---|
| Supabase browser/client reads | NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY |
Testing notification/reminder persistence against Supabase |
| Supabase server writes | SUPABASE_SERVICE_ROLE_KEY |
Running reminder cron behavior that bypasses RLS |
| Resend email delivery | RESEND_API_KEY |
Sending payer reminder emails |
| Protected reminder cron | CRON_SECRET |
Calling GET /api/reminders outside local experiments |
| GitHub feedback API | GITHUB_TOKEN, GITHUB_OWNER, GITHUB_REPO |
Creating GitHub issues from feedback submissions |
| WalletConnect | NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID |
Testing WalletConnect flows |
| SEP-10 auth | SEP10_SERVER_SECRET_KEY, JWT_SECRET_KEY |
Testing challenge/verify auth routes with non-default secrets |
Use placeholder values only for routes you are not exercising. Never commit .env.local.
For local Supabase-backed reminder flows, create the tables described in docs/supabase-setup.md and apply supabase/migrations/001_init_reminders.sql.
pnpm run env:checkThis checks direct process.env.* references in app/ and src/ against .env.local.example. Runtime-provided keys live in .env.local.example.allowlist.
pnpm devOpen http://localhost:3000.
- Open Freighter and switch to Testnet.
- Copy your public key.
- Visit Stellar Testnet Friendbot, replacing
YOUR_PUBLIC_KEYwith your account. - Return to the app, connect Freighter, and confirm the navbar shows the connected address.
| Command | Purpose |
|---|---|
pnpm dev |
Start the local Next.js dev server |
pnpm run lint |
Run ESLint |
pnpm run env:check |
Verify .env.local.example covers env references |
pnpm run format:check |
Check Prettier formatting |
pnpm test |
Run Vitest |
pnpm run test:a11y |
Run accessibility tests |
pnpm run test:e2e |
Run Playwright tests |
pnpm run build |
Create a production build |
pnpm start |
Serve the production build |
pnpm run storybook |
Start Storybook on port 6006 |
pnpm run build-storybook |
Build static Storybook output |
Run:
pnpm exec huskyThen confirm .husky/pre-commit and .husky/pre-push are executable in your Git client.
Use pnpm for this repo. Remove any generated npm lockfile and reinstall:
rm package-lock.json
pnpm installConfirm .env.local exists at the repo root, uses KEY=value lines, and restart the dev server after changes.
pnpm devReminder and notification routes are env-gated. Add the relevant Supabase and Resend keys to .env.local, or avoid those routes during basic UI work.
Set CRON_SECRET in .env.local and call the route with:
Authorization: Bearer <CRON_SECRET>Unlock Freighter, switch it to Testnet, refresh the page, and reconnect. If the app reports a network mismatch, the configured NEXT_PUBLIC_NETWORK_NAME and the Freighter network are different.
Use Friendbot with your Freighter public key. Testnet balances are separate from public network balances.
pnpm dev -- -p 3001Then open http://localhost:3001.
The pre-push hook runs npx tsc --noEmit. Reproduce it directly with:
pnpm exec tsc --noEmitReview the diff, then update snapshots intentionally:
pnpm test -- --update-snapshotsILN-Frontend/
├── app/ # Next.js App Router pages and API routes
├── src/components/ # Reusable UI, charts, forms, dashboards, stories
├── src/context/ # Wallet, notification, and toast providers
├── src/hooks/ # Custom hooks and React Query hooks
├── src/lib/ # Environment, Supabase, Horizon, events, wallet helpers
├── src/utils/ # Soroban, analytics, exports, risk, pagination helpers
├── __tests__/ # Vitest test suites
├── e2e/ # Playwright journeys
├── docs/ # Contributor documentation
├── public/ # Static assets, screenshots, manifest, service worker
├── scripts/ # Repo maintenance scripts
└── .github/workflows/ # GitHub Actions workflows
Start with app/page.tsx, skim docs/architecture.md, and read CONTRIBUTING.md before opening a PR. For deeper context on local integrations and contributor workflows, also see docs/supabase-setup.md, docs/feature-flags.md, docs/api-routes.md, and docs/testing.md.