StreamPay dashboard — Next.js app for Stellar wallet integration and payment stream management.
Next.js 15 (React, TypeScript) frontend for the StreamPay protocol. Users will connect Stellar wallets and create/manage payment streams from this dashboard.
This application implements strict environment profiles for Stellar testnet and mainnet to prevent dangerous configuration mistakes. See docs/network-security.md for complete security documentation.
The application will fail to boot without these required variables:
STELLAR_NETWORK- Network selection:testnetormainnetJWT_SECRET- JWT signing secret (minimum 32 characters)
-
Copy the example environment file:
cp .env.example .env.local
-
Configure for testnet (development):
STELLAR_NETWORK=testnet JWT_SECRET=dev-secret-key-at-least-32-chars NODE_ENV=development
-
Start the application:
npm run dev
- Fail-fast validation: Application refuses to start with invalid configuration
- No silent defaults: Never falls back to mainnet automatically
- CI guardrails: CI is enforced to use testnet only
- Secret redaction: All secrets are automatically redacted from logs
- UI safety labels: Testnet assets are clearly labeled to prevent confusion
- Centralized config: All network configuration in one module
See docs/network-security.md for the complete security guide.
- Calendar-month schedules use UTC day boundaries for proration.
- Mid-month starts and last-day pauses are prorated using inclusive UTC days.
- Short months use actual day counts (no 30/32-day months).
- Local time display may shift with DST; calculations remain UTC.
- Node.js 18+
- npm (or yarn/pnpm)
-
Clone and enter the repo
git clone <repo-url> cd streampay-frontend
-
Install dependencies
npm install
-
Verify setup
npm run build npm test -
Run locally
npm run dev
App will be at http://localhost:3000.
| Command | Description |
|---|---|
npm run dev |
Start dev server |
npm run build |
Production build |
npm start |
Run production build |
npm test |
Run Jest tests |
npm run test:e2e |
Run HTTP lifecycle E2E tests |
npm run lint |
Next.js ESLint |
npm run reconcile |
Run nightly reconciliation job |
On every push/PR to main, GitHub Actions runs:
- Install:
npm ci - Build:
npm run build - Tests:
npm test
Security gates run on every PR, push to main, and nightly at 2 AM UTC:
-
CodeQL SAST - Static Application Security Testing for JavaScript/TypeScript
- Analyzes source code for security vulnerabilities
- Results appear in GitHub Security tab
- Blocks merge on critical findings
-
Dependency Audit - npm vulnerability scanning
- Scans
package-lock.jsonfor known vulnerabilities - Blocks on CRITICAL severity unless exempted
- Exemptions tracked in
.github/security-exemptions.jsonwith expiry dates - Advisory links provided in PR comments
- Scans
-
Container Scan (conditional - only if Dockerfile exists)
- Trivy scanner checks Docker images for OS/library vulnerabilities
- Same exemption policy as dependency scan
- Scans both CRITICAL and HIGH severity
Vulnerabilities can be exempted temporarily with:
- Valid justification and expiry date (max 90 days)
- No auto-renewal - requires manual review
- 14-day advance notification before expiry
- Tracked in
.github/security-exemptions.json
Mirror CI security checks locally:
# Check for dependency vulnerabilities
npm audit
# View audit in JSON format
npm audit --json
# Run linting (part of security hygiene)
npm run lintEnsure the workflow passes before merging.
The repository includes a black-box HTTP E2E test for stream lifecycle actions:
create -> start -> pause -> settle- idempotent retries for
create,pause, andsettle - DB state assertions after each transition
- mocked Stellar/Soroban settlement at adapter boundary (not business logic)
Run locally:
npm run test:e2eNotes for contributors:
- The test boots a local Next server on a random localhost port to stay parallel-safe in CI.
- Test isolation uses
resetDb()before each case. - Settlement is mocked via
globalThis.__STREAMPAY_STELLAR_SETTLEMENT_CLIENT__so no real chain keys or network calls are needed.
- No private keys, secrets, or wallet credentials are used by the E2E harness.
- Settlement calls are mocked and never submit on-chain transactions.
- Test fixtures avoid PII and keep recipient names synthetic.
- Auth enforcement is currently out of scope for these routes; tests focus on lifecycle correctness and idempotency behavior.
streampay-frontend/
├── app/
│ ├── layout.tsx
│ ├── page.tsx
│ ├── page.test.tsx
│ └── globals.css
├── next.config.ts
├── tsconfig.json
├── jest.config.js
├── jest.setup.ts
├── .github/workflows/ci.yml
└── README.md
The app now includes a self-serve export flow for stream and activity history under /api/exports.
POST /api/exportscreates an async export jobGET /api/exports/:idreturns export statusGET /api/exports/:id?download=truereturns a short-lived signed URL for the resulting CSV- Export artifacts are retained for 7 days and signed URLs are short-lived
- Download requests are audited when the signed URL is requested
app/lib/amount.ts centralizes amount parsing and stream escrow math used by the frontend stream list.
- Supported assets are intentionally allow-listed:
XLM,USDC. - Amount inputs must be plain decimal strings with at most 7 fractional digits (Stellar stroop precision).
- Negative values are rejected.
- Values above signed int64 bounds are rejected.
- Escrow derivation rejects sub-stroop outcomes (no implicit rounding).
- Validation returns explicit 4xx-style error metadata (
httpStatus+ errorcode) so invalid user input does not bubble into 500-class failures.
app/lib/amount.test.tsincludes deterministic fuzz-style checks (seeded RNG) with bounded runtime.- Bounded fuzz runs in normal CI because it is fast; if runtime grows in the future, keep deterministic unit coverage in CI and move larger fuzz campaigns to nightly workflows.
MIT
This repository includes a CI smoke suite that validates app health and a synthetic stream write/read path.
npm run smokerunsGET /readyz,GET /api/streams, and a syntheticPOST /api/streams+POST /api/streams/{id}/settle.- Use
SMOKE_TARGET_URLto point at a deployed staging endpoint. - Use
SMOKE_AUTH_TOKENfor synthetic credentials in CI secrets.
A runtime feature flag is also available for incident mode: set NEXT_PUBLIC_DISABLE_ONCHAIN_OPERATIONS=true to pause new on-chain operations in the UI.