From 606d7d9d7eb472fde06b8085d4aef3c3ec2dd7af Mon Sep 17 00:00:00 2001 From: Peng Ying Date: Mon, 18 May 2026 14:16:31 -0700 Subject: [PATCH] fix: kotlin sample frontend crashes on http://0.0.0.0 and quiets HPKE build warnings - Add a randomUUID() helper with a Math.random fallback for non-secure contexts. crypto.randomUUID() throws on http://0.0.0.0:8080 (which is the host Ktor binds to) in some browsers, leaving the page blank. - Filter the @hpke/common build noise (Node-only `import("crypto")` externalization message and misplaced /* @__PURE__ */ comments) in vite.config.ts so real warnings stay visible. Co-Authored-By: Claude Opus 4.7 (1M context) --- samples/frontend/src/lib/session.ts | 4 ++- samples/frontend/src/lib/uuid.ts | 12 +++++++++ .../embeddedWallet/ExecuteSignedQuote.tsx | 3 ++- samples/frontend/vite.config.ts | 25 ++++++++++++++++++- 4 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 samples/frontend/src/lib/uuid.ts diff --git a/samples/frontend/src/lib/session.ts b/samples/frontend/src/lib/session.ts index ff9acdd9..2a7f14d8 100644 --- a/samples/frontend/src/lib/session.ts +++ b/samples/frontend/src/lib/session.ts @@ -1,9 +1,11 @@ +import { randomUUID } from './uuid' + const KEY = 'grid-sample-session-id' export function getSessionId(): string { let id = sessionStorage.getItem(KEY) if (!id) { - id = crypto.randomUUID() + id = randomUUID() sessionStorage.setItem(KEY, id) } return id diff --git a/samples/frontend/src/lib/uuid.ts b/samples/frontend/src/lib/uuid.ts new file mode 100644 index 00000000..0655977f --- /dev/null +++ b/samples/frontend/src/lib/uuid.ts @@ -0,0 +1,12 @@ +// crypto.randomUUID() requires a secure context (https or localhost). It throws +// on http://0.0.0.0:8080 in some browsers, which is the host Ktor binds to. +export function randomUUID(): string { + if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') { + return crypto.randomUUID() + } + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => { + const r = (Math.random() * 16) | 0 + const v = c === 'x' ? r : (r & 0x3) | 0x8 + return v.toString(16) + }) +} diff --git a/samples/frontend/src/steps/embeddedWallet/ExecuteSignedQuote.tsx b/samples/frontend/src/steps/embeddedWallet/ExecuteSignedQuote.tsx index 135e7d67..647afb83 100644 --- a/samples/frontend/src/steps/embeddedWallet/ExecuteSignedQuote.tsx +++ b/samples/frontend/src/steps/embeddedWallet/ExecuteSignedQuote.tsx @@ -1,6 +1,7 @@ import { useState } from 'react' import ResponsePanel from '../../components/ResponsePanel' import { apiPost } from '../../lib/api' +import { randomUUID } from '../../lib/uuid' interface Props { quoteId: string | null @@ -30,7 +31,7 @@ export default function ExecuteSignedQuote({ const path = `/api/quotes/${encodeURIComponent(quoteId)}/execute` const data = await apiPost>(path, undefined, { 'Grid-Wallet-Signature': signature, - 'Idempotency-Key': crypto.randomUUID(), + 'Idempotency-Key': randomUUID(), }) setResponse(JSON.stringify(data, null, 2)) onComplete(data) diff --git a/samples/frontend/vite.config.ts b/samples/frontend/vite.config.ts index 24c994ed..d35c584d 100644 --- a/samples/frontend/vite.config.ts +++ b/samples/frontend/vite.config.ts @@ -1,12 +1,35 @@ -import { defineConfig } from 'vite' +import { createLogger, defineConfig } from 'vite' import react from '@vitejs/plugin-react' import tailwindcss from '@tailwindcss/vite' +// @hpke/common has a Node <= v18 fallback that does `await import("crypto")`. +// It never executes in browsers (guarded by globalThis.crypto), but Vite logs an +// externalization warning at build time. The same package also ships misplaced +// /* @__PURE__ */ comments that Rollup can't attach. Both are noise; filter them. +const logger = createLogger() +const originalWarn = logger.warn +logger.warn = (msg, opts) => { + if (msg.includes('has been externalized for browser compatibility')) return + originalWarn(msg, opts) +} + export default defineConfig({ plugins: [react(), tailwindcss()], + customLogger: logger, build: { outDir: '../kotlin/src/main/resources/static', emptyOutDir: true, + rollupOptions: { + onwarn(warning, warn) { + if ( + warning.code === 'INVALID_ANNOTATION' && + warning.id?.includes('@hpke/common') + ) { + return + } + warn(warning) + }, + }, }, server: { port: 5173,