Modern, responsive web app featuring:
- Infinite scrolling signal feed
- Gamified swipe mechanics (Framer Motion drag gestures)
- Freighter wallet integration
- Real-time dashboard & trade execution
Connects to Soroban contracts for on-chain actions.
- Next.js 15+ (App Router)
- TypeScript
- Tailwind CSS 4 + shadcn/ui
- Framer Motion (swipes/animations)
- TanStack Query (data fetching)
- @stellar/freighter-api + stellar-sdk
- Zustand (state)
- Vercel deployment
- Clone & install:
git clone https://github.com/EndeMathew/StellarSwipe-frontend.git cd StellarSwipe-frontend npm install
Set environment variables (.env.local): NEXT_PUBLIC_SOROBAN_RPC_URL=https://soroban-testnet.stellar.org NEXT_PUBLIC_HORIZON_URL=https://horizon-testnet.stellar.org
Run dev server: npm run dev
Storybook provides an isolated visual catalog for all core UI primitives and components.
npm run storybook
# Opens at http://localhost:6006Use the theme toolbar (sun/moon icon) to toggle between light and dark themes.
npm run build-storybook
# Outputs to storybook-static/- Create
stories/YourComponent.stories.tsxalongside existing stories. - Follow the
Meta/StoryObjpattern used in existing stories. - Tag with
autodocsto auto-generate docs pages.
Stories are also used for Chromatic visual regression snapshots — any story in stories/ is captured on every PR. To exclude a story from snapshots add parameters: { chromatic: { disableSnapshot: true } }.
The CI bundle size check runs ANALYZE=true npm run build and compares output against bundle-budget.json.
To raise a budget intentionally:
- Edit
bundle-budget.json— increasesizeKbfor the affected chunk. - Add a comment in the PR description explaining the accepted regression.
Run locally:
npm run build:analyze # builds with analyzer, opens report in browser
npm run bundle:check # validates current build against budgetPerformance audits run automatically on every PR via Lighthouse CI (lighthouserc.js).
Budget thresholds (defined in lighthouserc.js):
| Metric | Budget |
|---|---|
| Performance score | ≥ 0.70 |
| LCP | ≤ 2500 ms |
| CLS | ≤ 0.10 |
| TBT | ≤ 300 ms |
To adjust a budget: edit the assertions block in lighthouserc.js and document the reason in your PR.
Lighthouse reports are uploaded as CI artifacts (lighthouse-reports/) for debugging failed runs.
Asynchronous worker execution paths are instrumented via src/tracing/worker-tracing.service.ts.
| Worker | Span name |
|---|---|
/api/signals route handler |
worker:signals:fetch |
| Freighter wallet connect | worker:wallet:connect |
| Signal price polling interval | worker:signalPrice:poll |
// Wrap any async function — returns its result, re-throws on error
const data = await traceWorker("worker:my:task", async () => fetchData(), { page: 1 });
// Manual span lifecycle
const finish = startSpan("worker:my:task", { key: "value" });
try {
await doWork();
finish("ok");
} catch (err) {
finish("error", err as Error);
}Each span captures: traceId, spanId, name, startedAt, endedAt, durationMs, status, attributes, and error (if any).
In development (NODE_ENV=development) spans are logged to console.debug. Replace the emit function in the service to forward spans to any observability backend (Datadog, OpenTelemetry, etc.).
- Attributes are caller-controlled — the service never reads or mutates them.
- No secrets are injected or logged by the tracing layer itself.
- Existing authentication and authorization semantics are fully preserved.
npm test