Skip to content

Commit 5294806

Browse files
authored
feat: syncing pats grid visualizer (#235)
Grid visualizer initial commit
1 parent e540940 commit 5294806

102 files changed

Lines changed: 8309 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
---
2+
description: Central icon library import conventions
3+
globs: **/*.tsx
4+
alwaysApply: false
5+
---
6+
7+
# Central Icons
8+
9+
Always use the **radius-3, stroke-1.5** variant when importing from the central icon library:
10+
11+
```tsx
12+
// ✅ GOOD
13+
import { IconConsole } from '@central-icons-react/round-outlined-radius-3-stroke-1.5/IconConsole';
14+
15+
// ❌ BAD — wrong radius
16+
import { IconConsole } from '@central-icons-react/round-outlined-radius-0-stroke-1.5/IconConsole';
17+
```
18+
19+
Apply `vector-effect: non-scaling-stroke` to all icon SVG paths via a wrapper class:
20+
21+
```scss
22+
.icon {
23+
display: flex;
24+
25+
svg path {
26+
vector-effect: non-scaling-stroke;
27+
}
28+
}
29+
```
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
node_modules/
2+
.next/
3+
out/
4+
.vercel/
5+
*.tsbuildinfo
6+
.claude/
7+
.vercel
8+
refs/
9+
experiments/
Lines changed: 295 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,295 @@
1+
# Grid Visualizer
2+
3+
## Product Overview
4+
5+
Grid Visualizer is an interactive tool that helps integrators understand and get started with the Lightspark Grid API. It walks users through configuring a payment flow — source, destination, funding model, audience — and generates a visual flow diagram plus API call sequences.
6+
7+
**Core insight**: Composable money-movement APIs like Grid are extremely hard to consume because they must expose everything. Grid Visualizer short-circuits this by asking the right questions and surfacing only what the user cares about. Specify your exact use case, get back a tailored list of API calls.
8+
9+
## Audience
10+
11+
- **Integrators/developers** evaluating Grid or learning the API
12+
- **Sales team** for demo conversations showing how easy integration is
13+
- **Existing customers** exploring new payment flows and capabilities
14+
15+
## Entry Points
16+
17+
- **Docs site**: grid.lightspark.com
18+
- **Marketing site**: lightspark.com/grid
19+
- **Direct links** shared in sales conversations
20+
- Currently deployed at: https://grid-visualizer-opal.vercel.app/
21+
22+
## Tech Stack
23+
24+
- **Next.js** 14 (App Router) / **React** 18 / **TypeScript** 5
25+
- **SCSS** with CSS Modules for component scoping
26+
- **@lightsparkdev/origin** — Lightspark's design system (npm package)
27+
- **@xyflow/react** — Flow diagram visualization
28+
- **motion** — Animations
29+
- **react-syntax-highlighter** — Code display (oneDark theme)
30+
- **match-sorter** — Fuzzy search for currency search
31+
- **@tanstack/react-table**, **@base-ui/react**, **ajv**, **clsx**
32+
- Deployed on **Vercel** with `--ignore-scripts` workaround for icon license issues
33+
34+
## Design System
35+
36+
Uses Lightspark **Origin** (`@lightsparkdev/origin`). Tokens imported via SCSS in `src/app/globals.scss`.
37+
38+
**Tokens in use:**
39+
- Colors: `--text-primary`, `--text-secondary`, `--text-tertiary`, `--surface-primary`, `--surface-secondary`
40+
- Spacing: `--spacing-sm`, `--spacing-md`, `--spacing-lg`, `--spacing-xl`, `--spacing-3xl`
41+
- Border radius: `--corner-radius-md`
42+
- Typography: `--font-family-sans`, `--font-weight-book`
43+
- Mixins: `@include headline`, `@include body`, `@include body-sm`, `@include label`
44+
45+
**Color coding:** Blue for fiat flows, purple for crypto flows.
46+
47+
## Architecture
48+
49+
### State Machine
50+
51+
The wizard uses a **useReducer** state machine in `src/app/page.tsx`. Single source of truth for all wizard state.
52+
53+
**State shape:**
54+
```typescript
55+
interface State {
56+
step: Step;
57+
sourceType: 'fiat' | 'crypto' | null;
58+
sourceCurrency: string | null;
59+
sourceRails: string[] | null;
60+
source: Selection | null;
61+
destType: 'fiat' | 'crypto' | null;
62+
destCurrency: string | null;
63+
destRails: string[] | null;
64+
destination: Selection | null;
65+
destAccount: 'external' | 'internal' | null;
66+
funding: 'pre-funded' | 'jit' | null;
67+
audience: 'human' | 'agent' | null;
68+
}
69+
```
70+
71+
**Actions:** `SET_SOURCE_TYPE`, `SET_SOURCE_CURRENCY`, `SET_SOURCE_RAIL`, `SET_DEST_TYPE`, `SET_DEST_CURRENCY`, `SET_DEST_RAIL`, `SET_DEST_ACCOUNT`, `SET_FUNDING`, `SET_AUDIENCE`, `RESET_SOURCE`, `RESET_DEST`, `RESET_FUNDING`, `RESET_ALL`
72+
73+
### Smart Flow Logic
74+
75+
- Automatically skips rail selection if only one rail/network is available
76+
- `dest-account` step only shown for single-switch scenarios (not fiat-to-fiat cross-currency)
77+
- `funding` step skipped for internal same-currency transfers
78+
- Two-switch logic: fiat-to-fiat cross-currency always requires external account
79+
80+
## Key Directories
81+
82+
```
83+
src/
84+
├── app/
85+
│ ├── page.tsx # Main wizard (useReducer state machine)
86+
│ ├── layout.tsx # Root layout with metadata
87+
│ ├── globals.scss # Global styles, imports Origin tokens
88+
│ └── page.module.scss # Page-specific styles
89+
├── components/
90+
│ ├── TypeSelector/ # Fiat vs Crypto card selection
91+
│ ├── CardSelector/ # Generic card-based option selector
92+
│ ├── CurrencySearch/ # Fiat currency search with fuzzy matching
93+
│ ├── OptionSelector/ # Pill-based option selector
94+
│ ├── SelectionSummary/ # Summary cards showing current selections
95+
│ ├── FlowVisualization/ # Flow diagram (@xyflow/react)
96+
│ │ └── CustomNode.tsx # Custom node styling
97+
│ └── OutputDisplay/ # API code generation and display
98+
├── data/
99+
│ ├── currencies.ts # 12 fiat currencies with payment rails
100+
│ └── crypto.ts # 3 crypto assets (BTC, USDC, USDT) with networks
101+
└── stubs/
102+
└── central-icons.js # Icon package stub (license workaround)
103+
refs/ # Internal reference screenshots (gitignored)
104+
```
105+
106+
## UX Flow
107+
108+
### 9 steps across 4 step groups:
109+
110+
**Group 1 — Set up the source**
111+
1. **source-type**: Fiat or Crypto (`TypeSelector`)
112+
2. **source-detail**: Currency/asset selection (`CurrencySearch` for fiat, `OptionSelector` for crypto)
113+
3. **source-rail**: Rail/network selection — skipped if only one option (`OptionSelector`)
114+
115+
**Group 2 — Set up the destination**
116+
4. **dest-type**: Fiat or Crypto (`TypeSelector`)
117+
5. **dest-detail**: Currency/asset selection (excludes source currency/asset if same type)
118+
6. **dest-account**: External or Internal account — conditional (`CardSelector`)
119+
7. **dest-rail**: Rail/network selection — conditional (`OptionSelector`)
120+
121+
**Group 3 — Choose funding model**
122+
8. **funding**: Pre-funded or Just-in-time — skipped for internal same-currency (`CardSelector`)
123+
124+
**Group 4 — Choose output format**
125+
9. **audience**: Human (curl commands) or AI Agent (structured JSON) (`CardSelector`)
126+
10. **output**: Flow diagram + generated API code sequences
127+
128+
## Code Conventions
129+
130+
- **Components**: PascalCase directories with `Component.tsx` + `Component.module.scss`
131+
- **CSS Modules**: imported as `styles`, used as `styles.className`
132+
- **Actions**: SCREAMING_SNAKE_CASE
133+
- **Step names**: kebab-case (`source-type`, `dest-detail`)
134+
- **Conditional classes**: `clsx` utility
135+
- **Type safety**: Union types for steps, discriminated unions for actions
136+
- **Always use design tokens** for spacing, colors, borders, typography — never hardcode values unless explicitly given a one-off value by the designer
137+
138+
### Icons
139+
140+
**Never hand-draw SVG paths.** Always use the central icon library directly.
141+
142+
Import icons from `@central-icons-react/round-outlined-radius-0-stroke-1.5` (the default variant):
143+
144+
```tsx
145+
import { IconChevronBottom } from '@central-icons-react/round-outlined-radius-0-stroke-1.5/IconChevronBottom';
146+
147+
<IconChevronBottom size={12} />
148+
```
149+
150+
Props: `size` (number, default 24), `color` (string, default `currentColor`).
151+
152+
You can also use Origin's `CentralIcon` wrapper: `<CentralIcon name="IconChevronBottom" size={12} />`.
153+
154+
## Design Principles
155+
156+
These guide every design and implementation decision. When in doubt, refer back here.
157+
158+
1. **Utility first, showcase as a byproduct.** The tool is most impressive when it's most useful. A developer who gets working curl commands in 30 seconds IS the demo. Don't optimize for spectacle at the cost of speed.
159+
160+
2. **Every screen should have one job.** If a screen is doing two things (e.g. choosing AND previewing), it's doing too much. Identify the single job and cut everything that doesn't serve it.
161+
162+
3. **The right panel earns its space.** It starts minimal and gets richer as the user invests choices. Don't front-load it with content the user hasn't committed to yet. The build-up IS the payoff.
163+
164+
4. **Reduce decisions, don't add them.** Before adding any element, ask: does this help the user decide faster, or does it give them another thing to evaluate? Preset flows = fewer decisions (good). Preset previews = more decisions (bad — now they're comparing instead of picking).
165+
166+
5. **The output is the product.** Everything before the output screen is a funnel. Optimize for getting there, not for making the journey scenic.
167+
168+
## Design Direction
169+
170+
Split layout with left panel (wizard controls) and right panel (live preview canvas). Figma-first workflow — mock up in Figma, review, then implement.
171+
172+
**Start screen**: Preset flow cards (fastest path) above manual fiat/crypto builder (escape hatch). Right panel is minimal — a seed node, not a preview. The screen's one job: get the user into a flow.
173+
174+
**Mid-flow**: Left panel shows breadcrumb progress + summary of prior choices (editable) + current step question. Right panel builds up with connected nodes as choices are made. Pending nodes shown as dashed outlines.
175+
176+
**Output screen**: The payoff. Flow summary bar + numbered API steps with syntax-highlighted code blocks on the left. Complete flow diagram on the right. Actions: copy, edit flow, open in dashboard.
177+
178+
**Visual polish** (in progress): Flags for currencies, icons for assets/rails, smooth transitions via motion library.
179+
180+
**Parked ideas** (revisit after core flow is polished):
181+
- Natural language input field backed by LLM — feasible (constrained output space, single API call to parse intent into wizard state), but core flow comes first
182+
- Searchable/filterable presets as a lighter alternative to NL input
183+
184+
## Grid API Source of Truth
185+
186+
The Grid API docs and OpenAPI spec are at `/Users/patcapulong/Development/Projects/Grid Docs/mintlify`. The OpenAPI spec is the definitive source for account types, endpoints, and request/response schemas.
187+
188+
### Key API Facts
189+
190+
- **Base URL**: `https://api.lightspark.com/grid/2025-10-13`
191+
- **Auth**: HTTP Basic Auth (`client_id:client_secret`)
192+
- **Rails are NOT user-selectable** — Grid auto-routes based on currency, country, amount
193+
- **JIT funding only works with instant rails** (RTP, FedNow, SEPA Instant, PIX, SPEI, UPI, Faster Payments, PayNow, FAST, all crypto). ACH, Wire, generic Bank Transfer are NOT JIT-eligible.
194+
195+
### Supported Account Types (ExternalAccountType enum)
196+
197+
Fiat: `US_ACCOUNT`, `CLABE`, `PIX`, `IBAN`, `UPI`, `NGN_ACCOUNT`, `CAD_ACCOUNT`, `GBP_ACCOUNT`, `PHP_ACCOUNT`, `SGD_ACCOUNT`
198+
BTC: `SPARK_WALLET`, `LIGHTNING`
199+
Stablecoins: `SOLANA_WALLET` (USDC), `TRON_WALLET` (USDT), `POLYGON_WALLET` (USDC), `BASE_WALLET` (USDC)
200+
201+
### Key Endpoints
202+
203+
- `POST /customers` — Create customer
204+
- `POST /customers/external-accounts` — Register external account
205+
- `GET /customers/internal-accounts` — List customer internal accounts
206+
- `GET /platform/internal-accounts` — List platform internal accounts
207+
- `POST /quotes` — Create cross-currency transfer quote
208+
- `POST /quotes/{quoteId}/execute` — Execute quote
209+
- `POST /transfer-out` — Same-currency internal → external
210+
- `POST /transfer-in` — Same-currency external → internal
211+
212+
### Quote Request Shape
213+
214+
```json
215+
{
216+
"source": { "sourceType": "ACCOUNT" | "REALTIME_FUNDING", ... },
217+
"destination": { "destinationType": "ACCOUNT" | "EXTERNAL_ACCOUNT_DETAILS" | "UMA_ADDRESS", ... },
218+
"lockedCurrencySide": "SENDING" | "RECEIVING",
219+
"lockedCurrencyAmount": 10000
220+
}
221+
```
222+
223+
### Sync Automation
224+
225+
Grid Docs repo has a nightly GitHub Action (`docs-sync.yml`) that uses `anthropics/claude-code-action@v1` to detect OpenAPI changes and auto-create PRs. We plan to create a similar workflow for this tool.
226+
227+
## Plans
228+
229+
- **UI redesign plan**: `/Users/patcapulong/.claude/plans/validated-wobbling-dragon.md`
230+
- **Make it real plan**: `/Users/patcapulong/.claude/plans/make-it-real.md`
231+
- **Pre-migration checklist**: `TODO-before-migration.md` (OG images, metadata, etc.)
232+
233+
## Open Questions
234+
235+
- **Mobile responsiveness**: Strategy TBD
236+
237+
### TODO: Questions for Victor
238+
239+
These block accuracy of generated code and flow diagrams. Once answered, updates are small (data arrays + enum values).
240+
241+
1. **Crypto source region — why does Grid need it?**
242+
- When crypto is source, we ask "Where's your USDC?" and show a region picker. The region determines which Grid Switch the user is assigned to (e.g., USD Grid Switch vs EUR Grid Switch).
243+
- Is this compliance/KYC, routing optimization, pricing, or all three?
244+
- Does it affect the actual API calls, or just the internal routing?
245+
- UX implication: should we block the flow on this, or default to something sensible?
246+
247+
2. **USDB — external or internal only?**
248+
- USDB is NOT in the `ExternalAccountType` enum in the OpenAPI spec.
249+
- It appears in internal account funding instructions (`assetType: "USDB"` with `SPARK_WALLET`).
250+
- Should we keep it in the picker as a full crypto asset, limit it to internal-only flows, or remove it?
251+
252+
3. **Bank Transfer countries — what are the actual `ExternalAccountType` values?**
253+
- We added 20 currencies from the docs (GHS, KES, ZAR, CNY, IDR, THB, etc.) with best-guess account types (`GHS_ACCOUNT`, `KES_ACCOUNT`, etc.) and generic fields (`accountNumber` + `bankName`).
254+
- What are the real `ExternalAccountType` enum values for these countries?
255+
- Do they all use the same generic fields, or do some have country-specific requirements?
256+
- Are any of these countries on instant rails (would affect JIT eligibility)?
257+
- Countries added: Ghana, Kenya, South Africa, Botswana, Tanzania, Uganda, Malawi, Zambia, China, Hong Kong, Indonesia, South Korea, Malaysia, Thailand, Vietnam, Sri Lanka, Costa Rica, DR Congo, plus XOF (West Africa) and XAF (Central Africa) regions.
258+
259+
## Team Context
260+
261+
- Victor built the initial tool; Pat (design/UX) is leading design polish
262+
- Team sees this as useful for sales conversations, developer onboarding, and potentially automated docs
263+
- Jeremy has insights on JIT funding rules and internal/external account mechanics
264+
- Grid Docs repo has OpenAPI spec as source of truth + automated sync via Claude Code
265+
266+
## Figma Bridge (MCP)
267+
268+
When building UI from Figma designs, use the figma-bridge MCP server. Tool priority:
269+
270+
1. **build_tree / build_ir** — create entire node hierarchies in one call. Prefer `build_ir` for token efficiency.
271+
2. **patch_tree** — update existing nodes. Only specify changed properties.
272+
3. **figma_execute** — batch 2+ atomic operations with ref chaining. Use `summary: true` for compact results.
273+
4. **figma_help** — discover which action to use via `figma_execute`. Primary action discovery tool.
274+
275+
**Token budget tips:**
276+
- Start with `figma_design_system_summary` (~200 tokens) instead of raw `list_variables` (~5000 tokens).
277+
- Use `figma_file_index` (cached 60s) for name-to-ID resolution instead of repeated `find_variable`/`find_style` calls.
278+
- Use `build_ir` over `build_tree` for 3-5x token savings on node creation.
279+
- Use `batch_get_node_properties` instead of multiple individual calls.
280+
- Pass `summary: true` on `figma_execute` for compact receipts.
281+
282+
**Critical gotchas:**
283+
- Auto-layout resets sizing to HUG — the bridge handles this automatically.
284+
- `clone()` drops variable bindings — the bridge's `copyBoundVariables` re-applies them.
285+
- Font loading is mandatory before text mutations.
286+
- `appendChild` transforms coordinates — set `x`/`y` after, not before.
287+
288+
**Ref chaining:** Assign `ref: "myName"` to capture a result, reference later with `nodeRef`, `parentRef`, etc.
289+
290+
## Special Configuration
291+
292+
- **Icon workaround**: `src/stubs/central-icons.js` stubs out `@central-icons-react` to avoid license issues. Webpack config in `next.config.mjs` does module replacement.
293+
- **Vercel**: `vercel.json` uses `--ignore-scripts` flag
294+
- **Origin transpiling**: `next.config.mjs` configures `transpilePackages` for the Origin package
295+
- **Grid Docs path**: `/Users/patcapulong/Development/Projects/Grid Docs/mintlify`

0 commit comments

Comments
 (0)