Skip to content

Custom UI demo - #1344

Merged
gianfra-t merged 18 commits into
stagingfrom
custom-ui-demo
Aug 21, 2026
Merged

Custom UI demo#1344
gianfra-t merged 18 commits into
stagingfrom
custom-ui-demo

Conversation

@gianfra-t

@gianfra-t gianfra-t commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

About

  • Add browser support to @vortexfi/sdk with Supabase session authentication, conditional Node/browser builds, and fail-closed ephemeral-key storage.
  • Introduce a standalone React demo for BRL/PIX to BSC USDC, including wallet connection, OTP auth, resilient quoting, payment recovery, and ramp history.
  • Update API CORS configuration and public/security documentation for browser SDK and custom UI integrations.
  • Re-arrange SDK ramp examples.

@netlify

netlify Bot commented Aug 19, 2026

Copy link
Copy Markdown

Deploy Preview for vortex-sandbox ready!

Name Link
🔨 Latest commit fe3155d
🔍 Latest deploy log https://app.netlify.com/projects/vortex-sandbox/deploys/6a8871752a4cce00a25342e1
😎 Deploy Preview https://deploy-preview-1344--vortex-sandbox.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
🤖 Make changes Run an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

@gianfra-t gianfra-t changed the title Custom UI demo [wip] Custom UI demo Aug 19, 2026
@netlify

netlify Bot commented Aug 19, 2026

Copy link
Copy Markdown

Deploy Preview for vortexfi canceled.

Name Link
🔨 Latest commit fe3155d
🔍 Latest deploy log https://app.netlify.com/projects/vortexfi/deploys/6a886ef728983c00087e310d

@netlify

netlify Bot commented Aug 19, 2026

Copy link
Copy Markdown

Deploy Preview for vrtx-dashboard canceled.

Name Link
🔨 Latest commit fe3155d
🔍 Latest deploy log https://app.netlify.com/projects/vrtx-dashboard/deploys/6a886ef72bb5dc0008231c33

@gianfra-t gianfra-t changed the title [wip] Custom UI demo Custom UI demo Aug 20, 2026
# 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
@gianfra-t
gianfra-t requested a balanced review from Copilot August 20, 2026 18:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 startRamp rejects after the server advances, verify status reconciliation clears the payable state, and also cover the still-initial retry 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 thread packages/sdk/src/VortexSdk.ts Outdated
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.");
Comment thread package.json Outdated
ebma and others added 9 commits August 21, 2026 11:09
…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.
@gianfra-t
gianfra-t merged commit 6c9350d into staging Aug 21, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants