Custom UI demo - #1344
Merged
Merged
Conversation
✅ Deploy Preview for vortex-sandbox ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for vortexfi canceled.
|
✅ Deploy Preview for vrtx-dashboard canceled.
|
# Conflicts: # docs/api/apidog/page-manifest.json # docs/api/pages/12-ai-agent-integration.md # docs/api/wire-contract.snapshot.md # docs/security-spec/01-auth/supabase-otp.md
Contributor
There was a problem hiding this comment.
Pull request overview
Adds browser support to @vortexfi/sdk and a React BRL/PIX-to-BSC demo, including Bearer authentication, recovery storage, CORS configuration, examples, tests, and documentation.
Changes:
- Publishes conditional Node/browser SDK builds with per-request access tokens.
- Adds the browser demo with OTP, wallet, quote, payment, and history flows.
- Updates API CORS, security specifications, integration docs, and tooling.
Reviewed changes
Copilot reviewed 69 out of 71 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
scripts/bootstrap-worktree.sh |
Builds SDK during bootstrap. |
README.md |
Documents the demo workspace. |
packages/sdk/test/vortexSdk.lazyNetworks.test.ts |
Tests registration authentication. |
packages/sdk/test/package-consumer/smoke.ts |
Adds token-provider type coverage. |
packages/sdk/test/package-consumer/node-smoke.mjs |
Verifies Node artifact resolution. |
packages/sdk/test/package-consumer/browser-smoke.mjs |
Verifies browser artifact and storage. |
packages/sdk/test/apiService.credentials.test.ts |
Tests Bearer-token headers. |
packages/sdk/src/VortexSdk.ts |
Adds browser auth and fail-closed storage. |
packages/sdk/src/types.ts |
Exposes token-provider configuration. |
packages/sdk/src/storage.ts |
Makes storage Node-specific. |
packages/sdk/src/storage.browser.ts |
Adds browser localStorage storage. |
packages/sdk/src/services/ApiService.ts |
Resolves credentials per request. |
packages/sdk/scripts/build.ts |
Builds the browser artifact. |
packages/sdk/README.md |
Documents browser SDK usage. |
packages/sdk/package.json |
Defines conditional exports and smoke tests. |
packages/sdk/examples/node-consumer/tsconfig.json |
Configures the Node example. |
packages/sdk/examples/node-consumer/src/index.ts |
Adds SDK consumer commands. |
packages/sdk/examples/node-consumer/src/exampleMxnOnramp.ts |
Migrates the MXN onramp example. |
packages/sdk/examples/node-consumer/src/exampleMxnOfframp.ts |
Migrates the MXN offramp example. |
packages/sdk/examples/node-consumer/src/exampleEurOnramp.ts |
Migrates the EUR onramp example. |
packages/sdk/examples/node-consumer/src/exampleEurOfframp.ts |
Migrates the EUR offramp example. |
packages/sdk/examples/node-consumer/src/exampleBrlOnramp.ts |
Updates the BRL onramp example. |
packages/sdk/examples/node-consumer/src/exampleBrlOfframp.ts |
Migrates the BRL offramp example. |
packages/sdk/examples/node-consumer/README.md |
Documents local Node examples. |
packages/sdk/examples/node-consumer/package.json |
Adds example commands and dependencies. |
packages/sdk/examples/node-consumer/bun.lock |
Locks example dependencies. |
packages/sdk/examples/node-consumer/.env.example |
Lists example configuration. |
packages/sdk/ARCHITECTURE.md |
Documents conditional builds and authentication. |
package.json |
Integrates demo build, test, and typecheck tasks. |
MAP.md |
Adds demo workspace wayfinding. |
docs/security-spec/RISK-REGISTER.md |
Records browser-storage risk. |
docs/security-spec/07-operations/api-surface.md |
Documents browser SDK CORS. |
docs/security-spec/02-signing-keys/ephemeral-accounts.md |
Updates browser key-custody invariants. |
docs/security-spec/01-auth/supabase-otp.md |
Documents demo OTP sessions. |
docs/security-spec/00-system-overview/architecture.md |
Adds browser SDK support. |
docs/api/wire-contract.snapshot.md |
Records the public token-provider type. |
docs/api/pages/15-custom-ui-integration.md |
Adds custom UI guidance. |
docs/api/pages/12-ai-agent-integration.md |
Updates runtime recommendations. |
docs/api/pages/08-widget-integration.md |
Clarifies Widget versus SDK usage. |
docs/api/pages/05-ephemeral-key-custody.md |
Documents browser storage custody. |
docs/api/pages/02-quick-start-with-the-sdk.md |
Adds browser initialization guidance. |
docs/api/pages/01-overview.md |
Updates SDK integration options. |
docs/api/apidog/page-manifest.json |
Publishes the custom UI page. |
CLAUDE.md |
Adds demo commands and workspace guidance. |
bun.lock |
Locks demo workspace dependencies. |
biome.json |
Exempts SDK export key ordering. |
apps/demo/vite.config.ts |
Configures Vite and React. |
apps/demo/tsconfig.json |
Configures demo TypeScript. |
apps/demo/src/wagmi.ts |
Configures AppKit and BSC. |
apps/demo/src/styles.css |
Styles the demo shell. |
apps/demo/src/main.tsx |
Mounts application providers. |
apps/demo/src/index.ts |
Exports demo components. |
apps/demo/src/hooks/useBscWallet.ts |
Encapsulates BSC wallet state. |
apps/demo/src/features/vortex/VortexModal.tsx |
Implements the ramp UI flow. |
apps/demo/src/features/vortex/vortexModal.css |
Styles the ramp modal. |
apps/demo/src/features/vortex/index.ts |
Exports the modal feature. |
apps/demo/src/features/vortex/browserState.ts |
Persists auth and ramp state. |
apps/demo/src/features/vortex/browserState.test.ts |
Tests browser persistence helpers. |
apps/demo/src/components/WalletButton.tsx |
Adds wallet connection controls. |
apps/demo/src/components/CanvasShell.tsx |
Adds the application shell. |
apps/demo/src/App.tsx |
Adds the demo launcher. |
apps/demo/package.json |
Defines the demo workspace. |
apps/demo/index.html |
Adds the demo HTML entrypoint. |
apps/demo/CLAUDE.md |
Documents demo conventions. |
apps/demo/.env.example |
Lists demo environment variables. |
apps/api/src/config/express.cors.test.ts |
Extends CORS preflight assertions. |
apps/api/src/config/corsOrigins.ts |
Generalizes fixed-origin parsing. |
apps/api/src/config/corsOrigins.test.ts |
Tests generalized origin parsing. |
apps/api/src/config/corsConfig.ts |
Allows configured browser SDK origins. |
apps/api/.env.example |
Documents browser SDK origins. |
.agents/skills/vortex-integration/SKILL.md |
Updates browser SDK integration guidance. |
Suppressed comments (2)
apps/demo/src/features/vortex/VortexModal.tsx:218
- If the displayed quote expires before submission, this branch fetches a potentially different output/fee and immediately registers it without user confirmation. A user can therefore approve one price and receive another. Refresh the quote, display it, and require a second confirmation before calling
registerRamp.
const activeQuote = new Date(quote.expiresAt).getTime() > Date.now() ? quote : await createBrlQuote(sdk, amount);
apps/demo/src/features/vortex/VortexModal.tsx:275
- The lost-response reconciliation path is new payment-critical behavior, but the added tests cover only storage helpers and never exercise this branch. Add a regression test where
startRamprejects after the server advances, verify status reconciliation clears the payable state, and also cover the still-initialretry case.
try {
const current = await sdk.getRampStatus(paymentRamp.id);
if (String(current.currentPhase) !== "initial") {
setHistory(
markRampStarted(window.localStorage, paymentRamp.id, String(current.currentPhase), String(current.status))
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+151
to
+152
| const poll = async () => { | ||
| const results = await Promise.allSettled(ids.map(id => sdk.getRampStatus(id))); |
|
|
||
| The flow: | ||
| 1. Frontend calls Supabase directly to send OTP to user's email | ||
| 1. The browser calls the Vortex auth endpoints, which delegate OTP delivery and verification to Supabase |
Comment on lines
+24
to
+25
| const AUTH_STORAGE_KEY = "vortex-demo-auth:v1"; | ||
| const HISTORY_STORAGE_KEY = "vortex-demo-history:v1"; |
Comment on lines
+65
to
+66
| if (typeof window !== "undefined" && config.secretKey) { | ||
| throw new Error("Browser SDK integrations must use accessTokenProvider and must not configure secretKey."); |
…uotes Addresses the Copilot review on #1344: - ramp history and pending PIX payments are stored per JWT subject, so a second user on the same browser can no longer see or resume another user's ramps; the legacy shared key is removed on first load - status polling skips COMPLETE/FAILED ramps, stops when none remain, and backs off exponentially while every request in a round fails, so a full history no longer exceeds the API's per-IP rate limit - an expired quote is refreshed and shown for explicit re-confirmation instead of being silently re-registered at a different price - the lost start-response reconciliation now lives in a tested helper
The secret-key prohibition only checked typeof window, so the browser artifact accepted a secretKey inside Web/Service Workers. The browser bundle already substitutes storage.browser.ts, which now carries an isBrowserBuild marker the constructor checks alongside window. The browser smoke test covers the worker scenario.
build:sdk compiles against shared's built output, so typecheck must rebuild shared first or it can validate against stale declarations.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
About