@rhinestone/1auth 0.7.4 → 0.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-IHBVEU33.mjs → chunk-6AHEN3FA.mjs} +1 -1
- package/dist/chunk-6AHEN3FA.mjs.map +1 -0
- package/dist/{chunk-UXBBB7AV.mjs → chunk-E4YZS7FZ.mjs} +68 -32
- package/dist/chunk-E4YZS7FZ.mjs.map +1 -0
- package/dist/{client-D4HVy1KF.d.mts → client-C8QSA1th.d.mts} +22 -17
- package/dist/{client-CuASptX3.d.ts → client-Dn6mL7BZ.d.ts} +22 -17
- package/dist/headless.d.mts +2 -2
- package/dist/headless.d.ts +2 -2
- package/dist/headless.js +4 -6
- package/dist/headless.js.map +1 -1
- package/dist/headless.mjs +4 -6
- package/dist/headless.mjs.map +1 -1
- package/dist/index.d.mts +163 -22
- package/dist/index.d.ts +163 -22
- package/dist/index.js +210 -116
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +143 -86
- package/dist/index.mjs.map +1 -1
- package/dist/{provider-6JoziYDq.d.ts → provider-BsVmPgkQ.d.ts} +22 -3
- package/dist/{provider-CAQT7Gqx.d.mts → provider-CJv38fIK.d.mts} +22 -3
- package/dist/react.d.mts +9 -4
- package/dist/react.d.ts +9 -4
- package/dist/react.js +4 -7
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +4 -7
- package/dist/react.mjs.map +1 -1
- package/dist/server.d.mts +2 -2
- package/dist/server.d.ts +2 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +1 -1
- package/dist/{types-C0jKNT_t.d.mts → types-Dzm5lZK-.d.mts} +33 -51
- package/dist/{types-C0jKNT_t.d.ts → types-Dzm5lZK-.d.ts} +33 -51
- package/dist/{verify-CnOwPq78.d.ts → verify-0VXQpQBJ.d.mts} +4 -6
- package/dist/{verify-aWdi5O2z.d.mts → verify-9UgxLSdo.d.ts} +4 -6
- package/dist/wagmi.d.mts +3 -3
- package/dist/wagmi.d.ts +3 -3
- package/dist/wagmi.js +67 -31
- package/dist/wagmi.js.map +1 -1
- package/dist/wagmi.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-IHBVEU33.mjs.map +0 -1
- package/dist/chunk-UXBBB7AV.mjs.map +0 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/assets.ts","../../loading-tokens/src/index.ts","../src/permissions.ts","../src/crossChainPermissions.ts","../src/account.ts","../src/walletClient/index.ts","../src/batch/BatchQueueContext.tsx","../src/batch/BatchQueueWidget.tsx"],"sourcesContent":["/**\n * OneAuthClient — the primary entry point for the @rhinestone/1auth SDK.\n *\n * Manages all communication between an integrating app and the 1auth passkey\n * service (apps/passkey). Interactions happen in two ways:\n *\n * 1. HTTP — direct REST calls to the passkey service API for non-interactive\n * operations such as intent preparation, status polling, and consent checks.\n *\n * 2. PostMessage — iframe/popup dialogs hosted at the passkey domain handle\n * WebAuthn ceremonies and return results to the parent page.\n *\n * Supported flows:\n * - Authentication (sign in / sign up) via modal, popup, or redirect\n * - Passkey challenge signing for off-chain login\n * - EIP-712 typed data signing\n * - Cross-chain intents via the Rhinestone orchestrator\n * - Batch intents (multiple chains, single passkey tap)\n * - Data consent management\n */\nimport { hashTypedData, type TypedDataDefinition } from \"viem\";\nimport { fetchAssetsResponse } from \"./assets\";\nimport { tokenFetchError } from \"./sponsorship-fetch\";\nimport type {\n AssetsResponse,\n PasskeyProviderConfig,\n SigningRequestOptions,\n SigningResult,\n CreateSigningRequestResponse,\n SigningRequestStatus,\n SigningErrorCode,\n EmbedOptions,\n UserPasskeysResponse,\n PasskeyCredential,\n AuthResult,\n AuthFlow,\n AuthWithModalOptions,\n LoginWithModalOptions,\n CreateAccountWithModalOptions,\n ConnectResult,\n AuthenticateOptions,\n AuthenticateResult,\n IntentCall,\n SendIntentOptions,\n SendIntentResult,\n PrepareIntentResponse,\n ExecuteIntentResponse,\n WebAuthnSignature,\n ThemeConfig,\n SignMessageOptions,\n SignMessageResult,\n SignTypedDataOptions,\n SignTypedDataResult,\n IntentHistoryOptions,\n IntentHistoryResult,\n GetAssetsOptions,\n SendBatchIntentOptions,\n SendBatchIntentResult,\n PrepareBatchIntentResponse,\n BatchIntentItemResult,\n CheckConsentOptions,\n CheckConsentResult,\n RequestConsentOptions,\n RequestConsentResult,\n GrantPermissionsOptions,\n GrantPermissionsResult,\n ListSessionGrantsOptions,\n ListSessionGrantsResult,\n SponsorshipConfig,\n SponsorshipCallbackConfig,\n OneAuthTelemetryAttributes,\n OneAuthTelemetryEvent,\n OneAuthTelemetryEventName,\n OneAuthTelemetryFlow,\n OneAuthTelemetryTraceContext,\n} from \"./types\";\nimport {\n BRAND_PURPLE,\n DARK_TOKENS,\n LIGHT_TOKENS,\n LOADING_BODY_GAP,\n LOADING_FONT_FAMILY,\n LOADING_ICON_PADDING,\n LOADING_LINE_HEIGHT,\n LOADING_MODAL_PADDING,\n LOADING_MODAL_RADIUS,\n LOADING_MODAL_WIDTH,\n LOADING_SUBTITLE,\n LOADING_SUBTITLE_FONT_SIZE,\n LOADING_SUBTITLE_FONT_WEIGHT,\n LOADING_TITLE,\n LOADING_TITLE_BLOCK_GAP,\n LOADING_TITLE_FONT_SIZE,\n LOADING_TITLE_FONT_WEIGHT,\n SPINNER_ARC,\n SPINNER_CIRCUMFERENCE,\n SPINNER_RADIUS,\n SPINNER_SIZE,\n SPINNER_SPIN_DURATION_MS,\n SPINNER_STROKE,\n} from \"@1auth/loading-tokens\";\n\n// Modal width is derived from LOADING_MODAL_WIDTH (single source of truth,\n// owned by `@1auth/loading-tokens`). Changing the width here in isolation\n// would let popup/iframe drift from the Figma spec; keep them tied.\nconst POPUP_WIDTH = LOADING_MODAL_WIDTH;\nconst POPUP_HEIGHT = 600;\nconst DEFAULT_EMBED_WIDTH = `${LOADING_MODAL_WIDTH}px`;\nconst DEFAULT_EMBED_HEIGHT = \"500px\";\nconst DEFAULT_PROVIDER_URL = \"https://passkey.1auth.app\";\n\n/**\n * Return the embedding page origin when the SDK is running in a browser.\n * The dialog uses this only for first-paint attribution and postMessage\n * targeting; authenticated server-side origin decisions still use browser\n * provided referrer/event.origin values inside the passkey app.\n */\nfunction currentWindowOrigin(): string | null {\n if (typeof window === \"undefined\") return null;\n const origin = window.location?.origin;\n return typeof origin === \"string\" && origin.length > 0 ? origin : null;\n}\n\n/**\n * Add the host origin to a dialog URL so the iframe can render the origin pill\n * on its first client render instead of waiting for PASSKEY_INIT or\n * document.referrer effects. Kept as a URL hint, not an authorization signal.\n */\nfunction appendParentOriginParam(params: URLSearchParams): void {\n const origin = currentWindowOrigin();\n if (origin) params.set(\"parentOrigin\", origin);\n}\n\n// Max characters for IntentCall.label / .sublabel before the SDK truncates\n// with an ellipsis. The sign dialog renders these in a ~200–260px column at\n// text-[16px] bold (see SignDialogBody.tsx TokenMovementCard). At that font\n// you fit ~17 typical chars; 20 is a forgiving cap that still avoids wrapping\n// for most strings while letting CSS `truncate` handle the worst-case fonts\n// as a safety net.\nconst MAX_LABEL_LEN = 20;\n\n// Default scrim appearance — preserved verbatim from the pre-`backdrop`-option\n// behavior so apps that never set `theme.backdrop` see no change. The dialog\n// (apps/passkey) uses the identical defaults for its in-iframe scrim.\nconst DEFAULT_BACKDROP_COLOR = \"#000000\";\nconst DEFAULT_BACKDROP_OPACITY = 0.4;\nconst DEFAULT_BACKDROP_BLUR = 8;\n// Only `#rrggbb` is allowed — same hard restriction the dialog applies to the\n// accent color (apps/passkey/src/lib/dialog-messages.ts ACCENT_RE). The value\n// is interpolated into a stylesheet string below, so anything looser (named\n// colors, `rgb()`, escapes) could become a CSS-injection vector.\nconst HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;\n\n/**\n * Resolve the scrim tint (as an `rgba(...)` string) and blur radius (px) for\n * the SDK loading overlay from the dialog URL's `backdrop*` query params.\n *\n * The overlay is painted by the SDK on the host page before the iframe renders\n * (see {@link OneAuthClient.createModalDialog}); it must match the in-iframe\n * scrim the passkey app paints afterward so the host→iframe handoff is\n * seamless. Both sides read the same params and clamp identically.\n *\n * Every field falls back to its default independently and invalid/out-of-range\n * values are coerced back to the default, so a malformed param can never\n * produce a broken `background`/`backdrop-filter` declaration.\n */\nexport function resolveBackdropStyle(params: URLSearchParams): {\n background: string;\n blur: number;\n} {\n const rawColor = params.get(\"backdropColor\");\n const hex = (rawColor && HEX_COLOR_RE.test(rawColor) ? rawColor : DEFAULT_BACKDROP_COLOR).slice(1);\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n\n // Parse a numeric param back to its default when the field is absent.\n // `URLSearchParams.get` returns null for omitted params and \"\" for empty\n // ones, and `Number(null) === Number(\"\") === 0` — which passes\n // `Number.isFinite`. Guarding on the raw value first keeps an omitted\n // `backdropOpacity`/`backdropBlur` on its historical default (0.4 / 8px)\n // instead of collapsing to a fully-transparent, unblurred overlay. An\n // explicit \"0\" is still a real, finite value and is honored.\n const clampNumber = (key: string, min: number, max: number, fallback: number): number => {\n const raw = params.get(key);\n if (!raw) return fallback;\n const n = Number(raw);\n return Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : fallback;\n };\n\n const opacity = clampNumber(\"backdropOpacity\", 0, 1, DEFAULT_BACKDROP_OPACITY);\n const blur = clampNumber(\"backdropBlur\", 0, 40, DEFAULT_BACKDROP_BLUR);\n\n return { background: `rgba(${r}, ${g}, ${b}, ${opacity})`, blur };\n}\n\n/**\n * Generate a unique nonce for a single modal session. Used by\n * `waitForModalAuthResponse` (and any other per-modal message listener)\n * to reject stale CLOSE / RESULT messages that a previous, already\n * cleaned-up iframe queued before its teardown — without the nonce the\n * new modal's listener would process the stale event and silently cancel\n * the fresh auth attempt. `crypto.randomUUID` is available in every\n * browser this SDK targets; fall back to a Math.random pair so non-\n * conformant environments don't throw at construction time.\n */\nfunction generateModalNonce(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n}\n\ntype TelemetryOperation = {\n operationId: string;\n flow: OneAuthTelemetryFlow;\n startedAt: number;\n trace?: OneAuthTelemetryTraceContext;\n attributes?: OneAuthTelemetryAttributes;\n};\n\ntype TelemetryEventPatch = Partial<\n Omit<OneAuthTelemetryEvent, \"name\" | \"operationId\" | \"flow\" | \"timestamp\">\n>;\n\n/**\n * Generate a stable correlation id for one SDK operation. It is intentionally\n * opaque and random so it can be logged safely without leaking user data.\n */\nfunction generateTelemetryOperationId(): string {\n return `1auth-${generateModalNonce()}`;\n}\n\n/**\n * Keep telemetry attributes JSON/log friendly. Undefined values are dropped so\n * callbacks and headers do not need to normalize SDK-produced objects.\n */\nfunction cleanTelemetryAttributes(\n attributes: OneAuthTelemetryAttributes | undefined,\n): OneAuthTelemetryAttributes | undefined {\n if (!attributes) return undefined;\n const clean: OneAuthTelemetryAttributes = {};\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== undefined) clean[key] = value;\n }\n return Object.keys(clean).length > 0 ? clean : undefined;\n}\n\n/**\n * Extract a consistent code/message pair from SDK result errors or thrown\n * exceptions without assuming a specific error class.\n */\nfunction describeTelemetryError(error: unknown): {\n errorCode?: string;\n errorMessage?: string;\n} {\n if (!error) return {};\n if (error instanceof Error) {\n return { errorCode: error.name, errorMessage: error.message };\n }\n if (typeof error === \"object\") {\n const err = error as { code?: unknown; message?: unknown };\n return {\n errorCode: typeof err.code === \"string\" ? err.code : undefined,\n errorMessage: typeof err.message === \"string\" ? err.message : String(error),\n };\n }\n return { errorMessage: String(error) };\n}\n\n/**\n * Truncate an IntentCall's `label` / `sublabel` to fit the sign dialog's\n * single-line label column. Returns the same call shape with capped strings;\n * leaves all other fields (to, data, value, icon) untouched. Returns the\n * input unchanged when `calls` is undefined or empty.\n *\n * The dialog also applies `truncate` CSS as a defense-in-depth measure — this\n * SDK cap exists so the request on the wire matches what the user sees, and\n * so apps can tell their label was too long (the truncated form ships).\n */\nfunction capCallLabels(calls: IntentCall[] | undefined): IntentCall[] | undefined {\n if (!calls) return calls;\n return calls.map((c) => {\n const cappedLabel =\n c.label && c.label.length > MAX_LABEL_LEN\n ? c.label.slice(0, MAX_LABEL_LEN - 1) + \"…\"\n : c.label;\n const cappedSublabel =\n c.sublabel && c.sublabel.length > MAX_LABEL_LEN\n ? c.sublabel.slice(0, MAX_LABEL_LEN - 1) + \"…\"\n : c.sublabel;\n if (cappedLabel === c.label && cappedSublabel === c.sublabel) return c;\n return { ...c, label: cappedLabel, sublabel: cappedSublabel };\n });\n}\n\n/**\n * Reads the `signerType` from the stored session in localStorage. Absent or\n * malformed storage falls back to `\"passkey\"` so existing installs remain\n * backwards compatible.\n */\nfunction getStoredSignerType(): \"passkey\" | \"eoa\" {\n if (typeof window === \"undefined\") return \"passkey\";\n try {\n const raw = window.localStorage.getItem(\"1auth-user\");\n if (!raw) return \"passkey\";\n const parsed = JSON.parse(raw) as { signerType?: \"passkey\" | \"eoa\" };\n return parsed?.signerType === \"eoa\" ? \"eoa\" : \"passkey\";\n } catch {\n return \"passkey\";\n }\n}\n\ntype NormalizedPasskeyProviderConfig = PasskeyProviderConfig & {\n providerUrl: string;\n dialogUrl: string;\n};\n\ntype BlindSigningOption = { blind_signing?: boolean };\n\n/**\n * Global default for blind signing, used when neither the per-call option nor\n * the client config expresses a preference.\n *\n * `true` means apps get blind signing out of the box and must *opt in* to\n * 1auth's visible review UI (clear signing) by passing `blind_signing: false`\n * on the client or per call. This is the single switch for the rollout: when\n * we're ready to change the platform-wide default, flip this one constant —\n * every app that hasn't set its own preference follows it.\n */\nconst DEFAULT_BLIND_SIGNING = true;\n\ntype SponsorshipTokens = { accessToken: string; extensionTokens: string[] };\n\ntype AccessTokenFetchResult =\n | { ok: true; accessToken: string }\n | { ok: false; code?: \"MISSING_APP_CREDENTIALS\"; message: string };\n\ntype ExtensionTokensFetchResult =\n | { ok: true; extensionTokens: string[] }\n | { ok: false; message: string };\n\nconst MISSING_APP_CREDENTIALS_MESSAGE =\n \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — pass `sponsorship: { accessToken, getExtensionToken }` (or URL form) to the constructor.\";\n\n/**\n * Normalize any `SponsorshipConfig` shape to the internal callback form.\n *\n * The URL form is a thin convenience — it gets wrapped into callbacks that\n * hit the app's own endpoints. Using same-origin URLs is recommended so the\n * browser forwards session cookies and the app can authenticate the user\n * server-side before minting a sponsorship grant.\n *\n * The access-token endpoint is GET and returns `{ token }`. The extension-\n * token endpoint is POST `{ intentOp }` and returns `{ token }`.\n */\nfunction normalizeSponsorship(\n config: SponsorshipConfig | undefined,\n): SponsorshipCallbackConfig | null {\n if (!config) return null;\n if (\"accessToken\" in config && \"getExtensionToken\" in config) {\n return config;\n }\n const { accessTokenUrl, extensionTokenUrl } = config;\n return {\n accessToken: async () => {\n const response = await fetch(accessTokenUrl, { credentials: \"include\" });\n if (!response.ok) {\n throw await tokenFetchError(\"access token\", response);\n }\n const data = (await response.json()) as { token?: string };\n if (!data.token) {\n throw new Error(\"Access token response missing `token` field\");\n }\n return data.token;\n },\n getExtensionToken: async (intentOp: string) => {\n const response = await fetch(extensionTokenUrl, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ intentOp }),\n });\n if (!response.ok) {\n throw await tokenFetchError(\"extension token\", response);\n }\n const data = (await response.json()) as { token?: string };\n if (!data.token) {\n throw new Error(\"Extension token response missing `token` field\");\n }\n return data.token;\n },\n };\n}\n\n/**\n * JSON.stringify replacer for grant-permission payloads. Session policy\n * helpers naturally use bigint values, but postMessage payloads must be\n * structured-clone friendly across browsers and JSON-safe for server calls.\n */\nfunction grantPermissionReplacer(_key: string, value: unknown): unknown {\n return typeof value === \"bigint\" ? value.toString() : value;\n}\n\nfunction cloneGrantPayload<T>(value: T): T {\n return JSON.parse(JSON.stringify(value, grantPermissionReplacer)) as T;\n}\n\nfunction normalizeGrantTargetChains(options: GrantPermissionsOptions): number[] {\n const chainCandidates = options.targetChains ?? (\n options.targetChain !== undefined ? [options.targetChain] : []\n );\n return Array.from(new Set(chainCandidates));\n}\n\nfunction normalizeGrantSourceChains(options: GrantPermissionsOptions): number[] {\n return Array.from(new Set(options.sourceChains ?? []));\n}\n\nexport class OneAuthClient {\n private config: NormalizedPasskeyProviderConfig;\n private theme: ThemeConfig;\n private sponsorship: SponsorshipCallbackConfig | null;\n // Persistent state for EOA forwarding via `/dialog/sign-eoa`. The iframe\n // is created lazily on the first `requestWithWallet` call and reused for\n // every subsequent call so its WalletConnect SignClient survives between\n // transactions — otherwise each call would spin up a fresh SignClient\n // that restores stale relay state from localStorage, producing\n // \"Restore will override\" warnings and \"emitting session_request:N\n // without any listeners\" errors on the second and later txs.\n private eoaDialogState: {\n dialog: HTMLDialogElement;\n iframe: HTMLIFrameElement;\n } | null = null;\n // Hidden iframe that warms the dialog ahead of the first real open (see\n // `prewarm()`). The passkey app runs on a long-lived server (not serverless),\n // so there is no backend cold-start to hide — what stays expensive is the\n // *browser-side* cost of a freshly created cross-origin iframe: downloading\n // the dialog HTML + JS bundle, parsing it, hydrating React, and loading the\n // font. Loading that bundle once into a parked hidden iframe lets the real\n // open hit the HTTP cache (Next.js chunks/fonts are immutable-cached) over an\n // already-warm connection, so the SDK preload overlay is shown only briefly.\n private prewarmState: {\n iframe: HTMLIFrameElement;\n ready: Promise<boolean>;\n } | null = null;\n // Serialises concurrent `requestWithWallet` calls — they would otherwise\n // both try to drive the same iframe and cross-resolve each other.\n private eoaSerialQueue: Promise<unknown> = Promise.resolve();\n\n /**\n * Create a new OneAuthClient.\n *\n * Normalizes the config (filling in default URLs), then immediately injects\n * `<link rel=\"preconnect\">` tags for the passkey domain so that DNS lookup\n * and TLS handshake start before the first dialog is opened, shaving\n * noticeable latency from the first user interaction.\n *\n * @param config - Client configuration including optional providerUrl, dialogUrl,\n * clientId, theme, and redirect settings.\n */\n constructor(config: PasskeyProviderConfig) {\n const providerUrl = config.providerUrl || DEFAULT_PROVIDER_URL;\n const dialogUrl = config.dialogUrl || providerUrl;\n this.config = { ...config, providerUrl, dialogUrl };\n this.theme = this.config.theme || {};\n this.sponsorship = normalizeSponsorship(config.sponsorship);\n\n // Pre-warm DNS + TLS connections to passkey domain\n if (typeof document !== \"undefined\") {\n this.injectPreconnect(providerUrl);\n if (dialogUrl !== providerUrl) {\n this.injectPreconnect(dialogUrl);\n }\n // Opt-in deeper warming: load the dialog bundle into a hidden iframe once\n // the main thread is idle so it never competes with the host app's own\n // first paint. Errors are swallowed — prewarm is best-effort.\n if (this.config.prewarm) {\n const warm = () => void this.prewarm();\n const ric = (window as Window & {\n requestIdleCallback?: (cb: () => void, opts?: { timeout: number }) => void;\n }).requestIdleCallback;\n if (typeof ric === \"function\") {\n ric(warm, { timeout: 2000 });\n } else {\n setTimeout(warm, 200);\n }\n }\n }\n\n const initOperation = this.createTelemetryOperation(\"client\", {\n hasClientId: !!this.config.clientId,\n hasDialogUrlOverride: dialogUrl !== providerUrl,\n });\n this.emitTelemetry(\"client.init\", initOperation, { outcome: \"started\" });\n }\n\n /**\n * Update the sponsorship configuration at runtime. Pass `undefined` to\n * disable sponsorship.\n */\n setSponsorship(sponsorship: SponsorshipConfig | undefined): void {\n this.sponsorship = normalizeSponsorship(sponsorship);\n }\n\n /**\n * Whether the caller opted into SDK telemetry propagation or callbacks.\n */\n private shouldUseTelemetry(): boolean {\n return !!this.config.telemetry && this.config.telemetry.enabled !== false;\n }\n\n /**\n * Resolve the host app's current trace context. Callback failures are\n * ignored because observability can never be allowed to break signing.\n */\n private getTelemetryTraceContext(): OneAuthTelemetryTraceContext | undefined {\n const traceContext = this.config.telemetry?.traceContext;\n if (!traceContext || !this.shouldUseTelemetry()) return undefined;\n try {\n return typeof traceContext === \"function\" ? traceContext() : traceContext;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Resolve host-provided SDK event attributes and remove undefined fields.\n */\n private getTelemetryAttributes(): OneAuthTelemetryAttributes | undefined {\n const attributes = this.config.telemetry?.attributes;\n if (!attributes || !this.shouldUseTelemetry()) return undefined;\n try {\n const resolved = typeof attributes === \"function\" ? attributes() : attributes;\n return cleanTelemetryAttributes(resolved);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Create per-operation telemetry context shared by callbacks, HTTP headers,\n * dialog URL params, and PASSKEY_INIT messages.\n */\n private createTelemetryOperation(\n flow: OneAuthTelemetryFlow,\n attributes?: OneAuthTelemetryAttributes,\n ): TelemetryOperation {\n return {\n operationId: generateTelemetryOperationId(),\n flow,\n startedAt: Date.now(),\n trace: this.getTelemetryTraceContext(),\n attributes: cleanTelemetryAttributes({\n ...this.getTelemetryAttributes(),\n ...attributes,\n }),\n };\n }\n\n /**\n * Emit a telemetry event to the host app. The callback is intentionally\n * fire-and-forget and exception-safe so app telemetry cannot affect users.\n */\n private emitTelemetry(\n name: OneAuthTelemetryEventName,\n operation: TelemetryOperation,\n patch: TelemetryEventPatch = {},\n ): void {\n const onEvent = this.config.telemetry?.onEvent;\n if (!onEvent || !this.shouldUseTelemetry()) return;\n\n const attributes = cleanTelemetryAttributes({\n ...operation.attributes,\n ...patch.attributes,\n });\n const event: OneAuthTelemetryEvent = {\n name,\n operationId: operation.operationId,\n flow: operation.flow,\n timestamp: new Date().toISOString(),\n durationMs: patch.durationMs ?? Date.now() - operation.startedAt,\n clientId: this.config.clientId,\n providerUrl: this.config.providerUrl,\n dialogUrl: this.getDialogUrl(),\n trace: operation.trace,\n ...patch,\n attributes,\n };\n\n try {\n onEvent(event);\n } catch {\n // Telemetry callbacks are intentionally isolated from SDK behavior.\n }\n }\n\n /**\n * Attach SDK correlation and optional W3C trace context to dialog URLs.\n */\n private appendTelemetryParams(\n params: URLSearchParams,\n operation: TelemetryOperation,\n ): void {\n if (!this.shouldUseTelemetry()) return;\n params.set(\"sdkOperationId\", operation.operationId);\n params.set(\"sdkTelemetryFlow\", operation.flow);\n if (operation.trace?.traceparent) {\n params.set(\"traceparent\", operation.trace.traceparent);\n }\n if (operation.trace?.tracestate) {\n params.set(\"tracestate\", operation.trace.tracestate);\n }\n if (operation.trace?.traceId) {\n params.set(\"sdkTraceId\", operation.trace.traceId);\n }\n if (operation.trace?.spanId) {\n params.set(\"sdkSpanId\", operation.trace.spanId);\n }\n }\n\n /**\n * Add SDK correlation headers to passkey API calls. These headers are also\n * valid W3C trace propagation inputs when the host app supplies traceparent.\n */\n private telemetryHeaders(operation?: TelemetryOperation): Record<string, string> {\n if (!operation || !this.shouldUseTelemetry()) return {};\n return {\n \"x-1auth-sdk-operation-id\": operation.operationId,\n \"x-1auth-sdk-flow\": operation.flow,\n ...(operation.trace?.traceparent ? { traceparent: operation.trace.traceparent } : {}),\n ...(operation.trace?.tracestate ? { tracestate: operation.trace.tracestate } : {}),\n };\n }\n\n /**\n * Embed telemetry context in PASSKEY_INIT payloads for dialog-side API calls.\n */\n private telemetryPayload(\n operation: TelemetryOperation,\n ): Record<string, string> | undefined {\n if (!this.shouldUseTelemetry()) return undefined;\n return {\n operationId: operation.operationId,\n flow: operation.flow,\n ...(operation.trace?.traceparent ? { traceparent: operation.trace.traceparent } : {}),\n ...(operation.trace?.tracestate ? { tracestate: operation.trace.tracestate } : {}),\n ...(operation.trace?.traceId ? { traceId: operation.trace.traceId } : {}),\n ...(operation.trace?.spanId ? { spanId: operation.trace.spanId } : {}),\n };\n }\n\n /**\n * Determine whether this signing call should request invisible dialog mode.\n * Resolution order: per-call option wins over the constructor config, which\n * wins over the platform-wide {@link DEFAULT_BLIND_SIGNING}. This lets an app\n * flip the global default for itself while still overriding individual\n * high-risk calls — e.g. default-blind but force the review UI for a large\n * transfer, or default-visible but blind-sign selected low-risk signatures.\n */\n private shouldRequestBlindSigning(options?: BlindSigningOption): boolean {\n return options?.blind_signing ?? this.config.blind_signing ?? DEFAULT_BLIND_SIGNING;\n }\n\n /**\n * Fetch the app's access token (JWT). Called up front, before\n * `/api/intent/prepare`, so the passkey server can authenticate the\n * orchestrator quote call with the app's JWT instead of a service-level\n * API key.\n *\n * Does not depend on `intentOp` — can run in parallel with anything that\n * also doesn't depend on the quote.\n */\n private async fetchAccessToken(): Promise<AccessTokenFetchResult> {\n if (!this.sponsorship) {\n return {\n ok: false,\n code: \"MISSING_APP_CREDENTIALS\",\n message: MISSING_APP_CREDENTIALS_MESSAGE,\n };\n }\n try {\n const accessToken = await this.sponsorship.accessToken();\n return { ok: true, accessToken };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /**\n * Fetch one extension token per intent, aligned with `sponsorFlags`.\n * Returns an empty array when no intent is sponsored. Fired after\n * `/prepare` so each token can be bound to its quote's `intentOp`, and\n * overlaps the dialog / WebAuthn ceremony for no added serial latency.\n */\n private async fetchExtensionTokens(\n intentOps: string[],\n sponsorFlags: boolean[],\n ): Promise<ExtensionTokensFetchResult> {\n if (!this.sponsorship) {\n return { ok: false, message: MISSING_APP_CREDENTIALS_MESSAGE };\n }\n const anySponsored = sponsorFlags.some(Boolean);\n if (!anySponsored) return { ok: true, extensionTokens: [] };\n try {\n const sponsorship = this.sponsorship;\n const tokens = await Promise.all(\n intentOps.map((op, i) =>\n sponsorFlags[i] ? sponsorship.getExtensionToken(op) : Promise.resolve(\"\"),\n ),\n );\n return { ok: true, extensionTokens: tokens };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /**\n * Update the theme configuration at runtime\n */\n setTheme(theme: ThemeConfig): void {\n this.theme = theme;\n }\n\n /**\n * Serialize the active theme into URL query parameters for the dialog.\n *\n * Merges the instance-level theme (set via constructor or `setTheme`) with any\n * per-call override, so callers can temporarily change the appearance for a\n * single dialog invocation without mutating shared state.\n *\n * @param overrideTheme - One-shot theme values that take precedence over the\n * instance theme for this call only.\n * @returns A URL-encoded query string (e.g. `\"theme=dark&accent=%230090ff\"`),\n * or an empty string if no theme properties are set.\n */\n private getThemeParams(overrideTheme?: ThemeConfig): string {\n const theme = { ...this.theme, ...overrideTheme };\n const params = new URLSearchParams();\n\n if (theme.mode) {\n params.set('theme', theme.mode);\n }\n // `primaryColor` is the documented name; `accent` is the legacy alias.\n // Resolve each layer independently before merging so that a per-call\n // override (either field) wins over the instance value (either field) —\n // a plain spread merge would let an instance `primaryColor` shadow a\n // per-call `accent`, breaking the documented \"overrides take precedence\"\n // contract while `accent` remains a back-compat alias.\n const instancePrimary = this.theme.primaryColor ?? this.theme.accent;\n const overridePrimary = overrideTheme?.primaryColor ?? overrideTheme?.accent;\n const primary = overridePrimary ?? instancePrimary;\n if (primary) {\n params.set('accent', primary);\n }\n\n // Backdrop (scrim) tint/blur. Each field is emitted only when present so\n // the dialog keeps its per-field defaults (black / 0.4 / 8px) for the\n // common case where the app sets none. The dialog re-validates and clamps\n // each value, so we pass them through verbatim here.\n const backdrop = theme.backdrop;\n if (backdrop) {\n if (backdrop.color) {\n params.set('backdropColor', backdrop.color);\n }\n if (backdrop.opacity !== undefined) {\n params.set('backdropOpacity', String(backdrop.opacity));\n }\n if (backdrop.blur !== undefined) {\n params.set('backdropBlur', String(backdrop.blur));\n }\n }\n\n return params.toString();\n }\n\n /**\n * Resolve the URL of the dialog app (the Vite/Next.js frontend that renders\n * the WebAuthn UI inside the iframe).\n *\n * `dialogUrl` is a separate config option to support split deployments where\n * the API server and the dialog frontend run at different origins. Falls back\n * to `providerUrl` when not explicitly configured — the common case.\n *\n * @returns The base URL used when constructing all dialog endpoint paths.\n */\n private getDialogUrl(): string {\n return this.config.dialogUrl || this.config.providerUrl;\n }\n\n /**\n * Extract the trusted origin used to validate incoming postMessage events.\n *\n * All `window.addEventListener(\"message\", ...)` handlers in this class check\n * `event.origin` against this value to prevent cross-origin spoofing. Wraps\n * `getDialogUrl()` in a `new URL()` parse so that paths and query strings are\n * stripped — only the scheme + host + port are compared.\n *\n * Falls back to the raw dialog URL string if URL parsing fails (e.g. during\n * unit tests with non-standard URL formats).\n *\n * @returns The scheme + host + optional port of the dialog app (e.g. `\"https://passkey.1auth.app\"`).\n */\n private getDialogOrigin(): string {\n const dialogUrl = this.getDialogUrl();\n try {\n return new URL(dialogUrl).origin;\n } catch {\n return dialogUrl;\n }\n }\n\n /**\n * Get the base provider URL\n */\n getProviderUrl(): string {\n return this.config.providerUrl;\n }\n\n /**\n * Get the configured client ID\n */\n getClientId(): string | undefined {\n return this.config.clientId;\n }\n\n /**\n * Whether this client operates on testnet chains only.\n */\n getTestnets(): boolean {\n return this.config.testnets ?? false;\n }\n\n /**\n * Get a unified token portfolio for a 1auth account across mainnets and\n * testnets.\n *\n * @example\n * ```typescript\n * const assets = await client.getAssets({\n * accountAddress: \"0x1111111111111111111111111111111111111111\",\n * });\n * console.log(assets.mainnets.balances, assets.testnets.balances);\n * ```\n */\n async getAssets(options: GetAssetsOptions): Promise<AssetsResponse> {\n if (!options.accountAddress) {\n throw new Error(\"getAssets requires accountAddress\");\n }\n\n const telemetry = this.createTelemetryOperation(\"assets\", {\n hasAccountAddress: !!options.accountAddress,\n });\n\n try {\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n throw new Error(accessTokenResult.message);\n }\n\n const result = await fetchAssetsResponse({\n providerUrl: this.config.providerUrl,\n identifier: options.accountAddress,\n clientId: this.config.clientId,\n accessToken: accessTokenResult.accessToken,\n headers: this.telemetryHeaders(telemetry),\n });\n this.emitTelemetry(\"assets.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n balanceCount: result.balances.length,\n mainnetBalanceCount: result.mainnets.balances.length,\n testnetBalanceCount: result.testnets.balances.length,\n },\n });\n return result;\n } catch (error) {\n this.emitTelemetry(\"assets.failed\", telemetry, {\n outcome: \"failure\",\n ...describeTelemetryError(error),\n });\n throw error;\n }\n }\n\n /**\n * Poll the intent status endpoint until a transaction hash appears or the\n * intent reaches a terminal failure state.\n *\n * This is used after `sendIntent` resolves (with `waitForHash: true`) to\n * continue waiting for the on-chain hash even after the dialog has been\n * dismissed. It is intentionally separate from the in-dialog polling loop so\n * callers that don't need the hash can skip it entirely.\n *\n * Errors during individual poll attempts are swallowed so that transient\n * network issues don't abort the wait prematurely.\n *\n * @param intentId - The Rhinestone intent ID returned by the execute endpoint.\n * @param options.timeoutMs - Maximum wait time in milliseconds (default 120 000).\n * @param options.intervalMs - Time between polls in milliseconds (default 2 000).\n * @returns The transaction hash string, or `undefined` if the deadline was\n * reached or the intent failed/expired before a hash was produced.\n */\n private async waitForTransactionHash(\n intentId: string,\n options: { timeoutMs?: number; intervalMs?: number } = {},\n telemetry?: TelemetryOperation,\n ): Promise<string | undefined> {\n const timeoutMs = options.timeoutMs ?? 120_000;\n const intervalMs = options.intervalMs ?? 2_000;\n const deadline = Date.now() + timeoutMs;\n\n while (Date.now() < deadline) {\n try {\n const response = await fetch(\n `${this.config.providerUrl}/api/intent/status/${intentId}`,\n {\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n }\n );\n if (response.ok) {\n const data = await response.json();\n if (data.transactionHash) {\n return data.transactionHash as string;\n }\n if (data.status === \"failed\" || data.status === \"expired\") {\n return undefined;\n }\n }\n } catch {\n // Keep polling until timeout.\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n return undefined;\n }\n\n /**\n * Open the authentication modal (sign in + sign up).\n *\n * Handles both new user registration and returning user login in a single\n * call — the modal shows the appropriate flow based on whether the user\n * has a passkey registered.\n *\n * @param options.username - Pre-fill the username field\n * @param options.theme - Override the theme for this modal invocation\n * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons\n * @param options.flow - Force the login or account-creation route instead\n * of the default auto-detect entry route\n * @returns {@link AuthResult} with user details and typed address\n *\n * @example\n * ```typescript\n * const result = await client.authWithModal();\n *\n * if (result.success) {\n * console.log('Signed in as:', result.user?.username);\n * console.log('Address:', result.user?.address); // typed `0x${string}`\n * } else if (result.error?.code === 'USER_CANCELLED') {\n * // User closed the modal\n * }\n * ```\n */\n async authWithModal(options?: AuthWithModalOptions): Promise<AuthResult> {\n return this.openAuthModal(options);\n }\n\n /**\n * Open the sign-in modal directly.\n *\n * This bypasses the `/dialog/auth` auto-router and targets the dedicated\n * returning-user flow. Use it when the embedding app already knows the user\n * is creating a login session, for example after an app-level \"Log in\"\n * button. The result intentionally matches {@link authWithModal}.\n *\n * @param options.username - Optional account hint for the sign-in ceremony\n * @param options.theme - Override the theme for this modal invocation\n * @returns {@link AuthResult} with user details and typed address\n */\n async loginWithModal(options?: LoginWithModalOptions): Promise<AuthResult> {\n return this.openAuthModal({ ...options, flow: \"login\" });\n }\n\n /**\n * Open the account-creation modal directly.\n *\n * This bypasses the `/dialog/auth` auto-router and targets the dedicated\n * sign-up flow. Account creation still happens server-side in the passkey\n * service; the SDK only opens the dialog and receives the postMessage result.\n *\n * @param options.theme - Override the theme for this modal invocation\n * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons\n * @returns {@link AuthResult} with the newly authenticated account details\n */\n async createAccountWithModal(options?: CreateAccountWithModalOptions): Promise<AuthResult> {\n return this.openAuthModal({ ...options, flow: \"create-account\" });\n }\n\n /**\n * Open one of the passkey authentication modal routes and wait for the\n * login-result message.\n *\n * Keeping URL construction in one helper prevents the explicit login/signup\n * methods from drifting away from the legacy `authWithModal` behavior.\n */\n private async openAuthModal(options?: AuthWithModalOptions): Promise<AuthResult> {\n const telemetry = this.createTelemetryOperation(\"auth\", {\n flow: options?.flow ?? \"auto\",\n hasUsernameHint: !!options?.username,\n });\n const dialogUrl = this.getDialogUrl();\n const requestId = this.createDialogRequestId();\n const params = new URLSearchParams({\n mode: 'iframe',\n requestId,\n });\n if (this.config.clientId) {\n params.set('clientId', this.config.clientId);\n }\n if (options?.username) {\n params.set('username', options.username);\n }\n if (options?.oauthEnabled === false) {\n params.set('oauth', '0');\n }\n if (options?.flow === \"create-account\") {\n // Explicit account creation must not be short-circuited by a stored\n // passkey-origin user; signup routes already treat switch=1 as that\n // \"show signup anyway\" signal.\n params.set('switch', '1');\n }\n // Seed first-paint attribution. The passkey app re-validates the actual\n // caller from document.referrer / PASSKEY_INIT before trusting it.\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n\n // Add theme params\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const authPath = this.getAuthDialogPath(options?.flow);\n const url = `${dialogUrl}${authPath}?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n this.emitTelemetry(\"dialog.opened\", telemetry, { outcome: \"started\" });\n const result = await this.waitForModalAuthResponse(dialog, iframe, cleanup, requestId);\n if (result.success) {\n this.emitTelemetry(\"auth.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { signerType: result.signerType ?? \"passkey\" },\n });\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"auth.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(result.error),\n },\n );\n }\n return result;\n }\n\n /**\n * Generate a per-dialog nonce used to correlate iframe close messages with\n * the SDK modal that opened them. Chromium can report a different\n * `MessageEvent.source` WindowProxy after the `/dialog/auth` redirect, so\n * auth close handling needs a stable in-band identifier without accepting\n * stale close messages from earlier dialogs.\n */\n private createDialogRequestId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n return `dialog-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n\n /**\n * Resolve the passkey app route for a requested auth flow.\n */\n private getAuthDialogPath(flow: AuthFlow = \"auto\"): string {\n if (flow === \"login\") return \"/dialog/auth/signin\";\n if (flow === \"create-account\") return \"/dialog/auth/signup\";\n return \"/dialog/auth\";\n }\n\n /**\n * Open the connect dialog (lightweight connection without passkey auth).\n *\n * This method shows a simple connection confirmation dialog that doesn't\n * require a passkey signature. Users can optionally enable \"auto-connect\"\n * to skip this dialog in the future.\n *\n * If the user has never connected before, this will return action: \"switch\"\n * to indicate that the full auth modal should be opened instead.\n *\n * @example\n * ```typescript\n * const result = await client.connectWithModal();\n *\n * if (result.success) {\n * console.log('Connected as:', result.user?.username);\n * } else if (result.action === 'switch') {\n * // User needs to sign in first\n * const authResult = await client.authWithModal();\n * }\n * ```\n */\n async connectWithModal(options?: {\n theme?: ThemeConfig;\n }): Promise<ConnectResult> {\n const telemetry = this.createTelemetryOperation(\"connect\");\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: 'iframe',\n });\n if (this.config.clientId) {\n params.set('clientId', this.config.clientId);\n }\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n\n // Add theme params\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const url = `${dialogUrl}/dialog/connect?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n this.emitTelemetry(\"dialog.opened\", telemetry, { outcome: \"started\" });\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n telemetry: this.telemetryPayload(telemetry),\n });\n if (!ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"Connection was cancelled before the dialog became ready\",\n });\n return {\n success: false,\n action: \"cancel\",\n error: { code: \"USER_CANCELLED\", message: \"Connection was cancelled\" },\n };\n }\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n const result = await this.waitForConnectResponse(dialog, iframe, cleanup);\n if (result.success) {\n this.emitTelemetry(\"connect.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n autoConnected: result.autoConnected === true,\n signerType: result.signerType ?? \"passkey\",\n },\n });\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"connect.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(result.error),\n attributes: { action: result.action },\n },\n );\n }\n return result;\n }\n\n /**\n * High-level connect entry point — the method most integrators want.\n *\n * Tries the lightweight {@link connectWithModal} first (no passkey ceremony\n * for returning users on the same browser), and transparently falls back to\n * {@link authWithModal} when the connect dialog reports it has no stored\n * credentials for this origin (`action: \"switch\"`). First-time visitors get\n * one passkey ceremony to register; subsequent connects on the same browser\n * resolve with no biometric prompt — and silently when the user has enabled\n * \"Connect automatically\".\n *\n * The return shape is the same {@link ConnectResult} discriminated union as\n * {@link connectWithModal}, so callers can treat both paths uniformly. When\n * the auth-modal fallback runs, its successful result is normalized into a\n * `ConnectResult` (no `id` field — the embedder origin must not see it).\n *\n * Cancellation: if the user cancels either dialog, the result is\n * `{ success: false, action: \"cancel\", error: { code: \"USER_CANCELLED\", … } }`.\n *\n * @param options - Forwarded to whichever underlying modal is shown.\n * `username` and `oauthEnabled` only apply to the auth-modal fallback path.\n * @returns A {@link ConnectResult} discriminated union.\n *\n * @example\n * ```typescript\n * const result = await client.connect();\n * if (result.success) {\n * console.log(\"Connected as\", result.user?.username ?? result.user?.address);\n * }\n * ```\n */\n async connect(options?: {\n username?: string;\n theme?: ThemeConfig;\n oauthEnabled?: boolean;\n }): Promise<ConnectResult> {\n const connectResult = await this.connectWithModal(\n options?.theme ? { theme: options.theme } : undefined,\n );\n\n // Returning user / auto-connect / explicit confirm — done, no biometrics.\n if (connectResult.success) return connectResult;\n\n // First-time visitor or cleared storage: connect dialog can't prove the\n // user, so it asks the SDK to switch to the full auth modal.\n if (connectResult.action === \"switch\") {\n const authResult = await this.authWithModal(options);\n if (authResult.success && authResult.user) {\n return {\n success: true,\n user: {\n username: authResult.user.username,\n address: authResult.user.address,\n },\n autoConnected: false,\n };\n }\n // Auth modal cancelled or errored — surface as a ConnectResult so callers\n // don't have to handle two error shapes.\n return {\n success: false,\n action: \"cancel\",\n error: authResult.error ?? {\n code: \"USER_CANCELLED\",\n message: \"Connection was cancelled\",\n },\n };\n }\n\n // User cancelled the connect dialog directly — pass through.\n return connectResult;\n }\n\n /**\n * Open the account management dialog.\n *\n * Shows the account overview with guardian status and recovery setup\n * options. The dialog closes when the user clicks the X button or\n * completes their action.\n *\n * @example\n * ```typescript\n * await client.openAccountDialog();\n * ```\n */\n async openAccountDialog(options?: {\n theme?: ThemeConfig;\n }): Promise<void> {\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: 'iframe',\n });\n\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const url = `${dialogUrl}/dialog/account?${params.toString()}`;\n\n // Guardian-setup and session-revoke inside the account dialog submit user\n // intents, which must carry the app's JWT. Fetch it and forward it in the\n // PASSKEY_INIT payload. Best-effort: if sponsorship isn't configured the\n // dialog still opens for read-only / backup actions, and the intent flows\n // surface a clear missing-authorization error rather than a cryptic\n // orchestrator 400.\n //\n // Fetch the token BEFORE creating the iframe: createModalDialog starts\n // loading the dialog, and the listener for its PASSKEY_READY is only\n // installed inside waitForDialogReady. Awaiting a network call between\n // those two would let a fast iframe post READY before the listener exists\n // (→ 10s timeout, dialog never opens). Resolving the token first keeps the\n // create→listen handoff synchronous, as it was originally.\n const accessTokenResult = await this.fetchAccessToken();\n const initMessage: Record<string, unknown> = { mode: \"iframe\" };\n if (accessTokenResult.ok) {\n initMessage.auth = { accessToken: accessTokenResult.accessToken };\n }\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, initMessage);\n if (!ready) return;\n\n // Wait for the dialog to close (no result needed)\n const dialogOrigin = this.getDialogOrigin();\n return new Promise<void>((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_CLOSE\" || event.data?.type === \"PASSKEY_DISCONNECT\") {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n cleanup();\n resolve();\n }\n };\n const handleClose = () => {\n window.removeEventListener(\"message\", handleMessage);\n resolve();\n };\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Open the account-recovery backup flow directly.\n *\n * Deep-links into the \"Backup your account\" flow inside the account dialog\n * (rather than the account overview): the user verifies with their passkey,\n * then saves a recovery passphrase and downloads an encrypted backup file.\n * Use this to prompt users to secure their account after sign-up.\n *\n * Requires an authenticated user (call `authWithModal()` / `connect()`\n * first) — the dialog reads the signed-in user from the passkey origin.\n *\n * Resolves `{ completed: true }` when the user finishes the backup, or\n * `{ completed: false }` if they dismiss it — so callers can mark an\n * onboarding step done or re-prompt later.\n */\n async setupRecovery(options?: {\n theme?: ThemeConfig;\n }): Promise<{ completed: boolean }> {\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: 'iframe',\n // Deep-link the account dialog straight into the backup nudge instead\n // of the account overview.\n action: 'backup',\n });\n\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const url = `${dialogUrl}/dialog/account?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n });\n if (!ready) return { completed: false };\n\n const dialogOrigin = this.getDialogOrigin();\n return new Promise<{ completed: boolean }>((resolve) => {\n let completed = false;\n const finish = () => {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n cleanup();\n resolve({ completed });\n };\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n const type = event.data?.type;\n if (type === \"PASSKEY_RECOVERY_RESULT\") {\n // The dialog reports success right before closing; record it so the\n // subsequent PASSKEY_CLOSE resolves with completed: true.\n completed = Boolean(event.data?.data?.completed ?? event.data?.success);\n return;\n }\n if (type === \"PASSKEY_CLOSE\" || type === \"PASSKEY_DISCONNECT\") {\n finish();\n }\n };\n const handleClose = () => {\n window.removeEventListener(\"message\", handleMessage);\n resolve({ completed });\n };\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Check if a user has already granted consent for the requested fields.\n *\n * @deprecated Data-sharing consent is disabled.\n *\n * Always returns `{ hasConsent: false }`.\n */\n async checkConsent(options: CheckConsentOptions): Promise<CheckConsentResult> {\n void options;\n return { hasConsent: false };\n }\n\n /**\n * Request consent from the user to share their data.\n *\n * @deprecated Data-sharing consent is disabled.\n *\n * Always returns an `INVALID_REQUEST` result.\n */\n async requestConsent(options: RequestConsentOptions): Promise<RequestConsentResult> {\n void options;\n return {\n success: false,\n error: {\n code: \"INVALID_REQUEST\",\n message: \"Data-sharing consent is disabled\",\n },\n };\n }\n\n /**\n * Open the dedicated SmartSession permission grant dialog.\n *\n * The app owns the session key material and sends only the public\n * `sessionKeyAddress`. 1auth renders the permission review, collects the\n * owner's passkey authorization, submits the install/enable intent, and\n * returns a persistable session handle.\n */\n async grantPermissions(options: GrantPermissionsOptions): Promise<GrantPermissionsResult> {\n const telemetry = this.createTelemetryOperation(\"grant_permission\", {\n targetChains: normalizeGrantTargetChains(options).join(\",\"),\n sponsor: options.sponsor !== false,\n });\n if (!options.username && !options.accountAddress) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"Either username or accountAddress is required\",\n });\n return {\n success: false,\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"Either username or accountAddress is required\",\n },\n };\n }\n const targetChains = normalizeGrantTargetChains(options);\n const sourceChains = normalizeGrantSourceChains(options);\n if (targetChains.length === 0 || !options.sessionKeyAddress || !options.permissions?.length) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"targetChains, sessionKeyAddress, and permissions are required\",\n });\n return {\n success: false,\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"targetChains, sessionKeyAddress, and permissions are required\",\n },\n };\n }\n if (!this.sponsorship) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"MISSING_APP_CREDENTIALS\",\n errorMessage: MISSING_APP_CREDENTIALS_MESSAGE,\n });\n return {\n success: false,\n error: {\n code: \"MISSING_APP_CREDENTIALS\",\n message: MISSING_APP_CREDENTIALS_MESSAGE,\n },\n };\n }\n\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: accessTokenResult.message,\n });\n return {\n success: false,\n error: {\n code: \"SPONSORSHIP_FETCH_FAILED\",\n message: accessTokenResult.message,\n },\n };\n }\n\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const grantUrl = `${dialogUrl}/dialog/grant-permission?${params.toString()}`;\n const { dialog, iframe, cleanup } = this.createModalDialog(grantUrl);\n const initPayload = {\n mode: \"iframe\",\n clientId: this.config.clientId,\n grant: cloneGrantPayload({\n username: options.username,\n accountAddress: options.accountAddress,\n targetChain: targetChains[0],\n targetChains,\n sourceChains,\n sessionKeyAddress: options.sessionKeyAddress,\n permissions: options.permissions,\n crossChainPermits: options.crossChainPermits,\n validUntil: options.validUntil,\n validAfter: options.validAfter,\n maxUses: options.maxUses,\n contracts: options.contracts,\n }),\n auth: { accessToken: accessTokenResult.accessToken },\n sponsor: options.sponsor !== false,\n telemetry: this.telemetryPayload(telemetry),\n };\n\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n targetChains,\n });\n const result = await this.waitForGrantPermissionResponse(\n dialog,\n iframe,\n cleanup,\n options.sponsor !== false,\n initPayload,\n );\n if (result.success) {\n this.emitTelemetry(\"grant_permission.succeeded\", telemetry, {\n outcome: \"success\",\n targetChains,\n status: result.status ? String(result.status) : undefined,\n });\n // The grant is already resolved; keep the dialog's \"Permission granted\"\n // success screen (green Done button) on screen until the user dismisses\n // it, then tear the iframe down. Without this the dialog would close the\n // instant the result arrived and the confirmation would never be seen —\n // unlike the sign flow, where sendIntent awaits the dialog close after a\n // confirmed signature.\n await this.waitForDialogClose(dialog, cleanup);\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"grant_permission.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n targetChains,\n ...describeTelemetryError(result.error),\n },\n );\n }\n return result;\n }\n\n /**\n * List SmartSession grants previously granted to the current browser origin.\n *\n * 1auth derives the app identity from the request Origin header. The SDK does\n * not send `clientId` for this lookup because grants are origin-scoped.\n */\n async listSessionGrants(\n options: ListSessionGrantsOptions,\n ): Promise<ListSessionGrantsResult> {\n if (!options.username && !options.accountAddress) {\n return {\n success: false,\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"Either username or accountAddress is required\",\n },\n };\n }\n\n const params = new URLSearchParams();\n if (options.username) params.set(\"username\", options.username);\n if (options.accountAddress) params.set(\"accountAddress\", options.accountAddress);\n if (options.includeRevoked) params.set(\"includeRevoked\", \"true\");\n\n try {\n const response = await fetch(\n `${this.config.providerUrl}/api/sessions/grants?${params.toString()}`,\n { credentials: \"include\" },\n );\n const data = await response.json();\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: \"LIST_SESSION_GRANTS_FAILED\",\n message: data?.error ?? `Request failed with status ${response.status}`,\n },\n };\n }\n return { success: true, grants: data.grants ?? [] };\n } catch (err) {\n return {\n success: false,\n error: {\n code: \"LIST_SESSION_GRANTS_FAILED\",\n message: err instanceof Error ? err.message : String(err),\n },\n };\n }\n }\n\n /**\n * Authenticate a user with an optional challenge to sign.\n *\n * This method combines authentication (sign in / sign up) with optional\n * challenge signing, enabling off-chain login without on-chain transactions.\n *\n * When a challenge is provided:\n * 1. User authenticates (sign in or sign up) through the normal auth dialog\n * 2. User signs the challenge through the normal signing dialog\n * 3. Returns user info + signature for server-side verification\n *\n * This composes the same supported provider routes as calling\n * `authWithModal()` followed by `signMessage()`, so challenge auth cannot\n * drift onto a provider route that the passkey service does not expose.\n *\n * @example\n * ```typescript\n * const result = await client.authenticate({\n * challenge: `Login to MyApp\\nTimestamp: ${Date.now()}\\nNonce: ${crypto.randomUUID()}`\n * });\n *\n * if (result.success && result.challenge) {\n * // Verify signature server-side\n * const isValid = await verifyOnServer(\n * result.user?.username,\n * result.challenge.signature,\n * result.challenge.signedHash\n * );\n * }\n * ```\n */\n async authenticate(options?: AuthenticateOptions & { theme?: ThemeConfig }): Promise<AuthenticateResult> {\n const telemetry = this.createTelemetryOperation(\"authenticate\", {\n hasChallenge: !!options?.challenge,\n });\n const authResult = await this.authWithModal(options?.theme ? { theme: options.theme } : undefined);\n if (!authResult.success) {\n this.emitTelemetry(\n authResult.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"auth.failed\",\n telemetry,\n {\n outcome: authResult.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(authResult.error),\n },\n );\n return authResult;\n }\n\n if (!options?.challenge) {\n this.emitTelemetry(\"auth.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { challengeSigned: false },\n });\n return authResult;\n }\n\n const accountAddress = authResult.user?.address;\n const username = authResult.user?.username;\n if (!accountAddress && !username) {\n const result: AuthenticateResult = {\n success: false,\n user: authResult.user,\n signerType: authResult.signerType,\n error: {\n code: \"AUTHENTICATE_USER_MISSING\",\n message: \"Authentication succeeded but no username or account address was returned for challenge signing\",\n },\n };\n this.emitTelemetry(\"auth.failed\", telemetry, {\n outcome: \"failure\",\n ...describeTelemetryError(result.error),\n });\n return result;\n }\n\n const signResult = await this.signMessage({\n username,\n accountAddress,\n message: options.challenge,\n description: \"Verify your identity\",\n theme: options.theme,\n });\n\n if (signResult.success && signResult.signature && signResult.signedHash) {\n const result: AuthenticateResult = {\n ...authResult,\n challenge: {\n signature: signResult.signature,\n signedHash: signResult.signedHash,\n },\n };\n this.emitTelemetry(\"auth.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { challengeSigned: true },\n });\n return result;\n }\n\n const error = signResult.error\n ? { code: signResult.error.code, message: signResult.error.message }\n : { code: \"SIGNING_FAILED\", message: \"Challenge signing failed\" };\n const result: AuthenticateResult = {\n success: false,\n user: authResult.user,\n signerType: authResult.signerType,\n error,\n };\n const cancelled = error.code === \"USER_CANCELLED\" || error.code === \"USER_REJECTED\";\n this.emitTelemetry(\n cancelled ? \"dialog.cancelled\" : \"auth.failed\",\n telemetry,\n {\n outcome: cancelled ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(error),\n },\n );\n return result;\n }\n\n /**\n * Show signing in a modal overlay (iframe dialog)\n */\n async signWithModal(options: SigningRequestOptions & { theme?: ThemeConfig }): Promise<SigningResult> {\n const telemetry = this.createTelemetryOperation(\"sign\", {\n signingMode: \"transaction\",\n hasTransaction: !!options.transaction,\n hasAccountAddress: !!options.accountAddress,\n });\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n challenge: options.challenge,\n username: options.username,\n accountAddress: options.accountAddress,\n description: options.description,\n transaction: options.transaction,\n metadata: options.metadata,\n telemetry: this.telemetryPayload(telemetry),\n }, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n if (!ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_REJECTED\",\n errorMessage: \"User closed the dialog before signing\",\n });\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n const result = await this.waitForSigningResponse(dialog, iframe, cleanup);\n if (result.success) {\n this.emitTelemetry(\"sign.succeeded\", telemetry, { outcome: \"success\" });\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(result.error),\n },\n );\n }\n return result;\n }\n\n /**\n * Send an intent to the Rhinestone orchestrator\n *\n * This is the high-level method for cross-chain transactions:\n * 1. Prepares the intent (gets quote from orchestrator)\n * 2. Shows the signing modal with real fees\n * 3. Submits the signed intent for execution\n * 4. Returns the transaction hash\n *\n * @example\n * ```typescript\n * const result = await client.sendIntent({\n * username: 'alice',\n * targetChain: 8453, // Base\n * calls: [\n * {\n * to: '0x...',\n * data: '0x...',\n * label: 'Swap ETH for USDC',\n * sublabel: '0.1 ETH → ~250 USDC',\n * },\n * ],\n * });\n *\n * if (result.success) {\n * console.log('Transaction hash:', result.transactionHash);\n * }\n * ```\n */\n async sendIntent(options: SendIntentOptions): Promise<SendIntentResult> {\n const { username, accountAddress, targetChain } = options;\n // Cap label/sublabel up front so every downstream consumer (prepare\n // request body AND the dialog's phase-1 init payload) sees the same\n // truncated strings — keeps wire data and rendered UI in sync.\n const calls = capCallLabels(options.calls);\n const sponsor = options.sponsor !== false;\n const telemetry = this.createTelemetryOperation(\"intent\", {\n targetChain: targetChain ?? null,\n callsCount: calls?.length ?? 0,\n sponsor,\n blindSigning: this.shouldRequestBlindSigning(options),\n });\n\n if (getStoredSignerType() === \"eoa\") {\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"E_SIGNER_UNSUPPORTED\",\n errorMessage: \"Cross-chain intents are not supported for EOA sessions\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"E_SIGNER_UNSUPPORTED\",\n message:\n \"Cross-chain intents are not supported for EOA sessions. Use the connected wallet's native RPC instead.\",\n },\n };\n }\n\n if (!username && !accountAddress) {\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"Either username or accountAddress is required\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"Either username or accountAddress is required\",\n },\n };\n }\n\n const hasCalls = !!calls?.length;\n const hasTokenRequests = !!options.tokenRequests?.length;\n if (!targetChain || (!hasCalls && !hasTokenRequests)) {\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"targetChain and calls or tokenRequests are required\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"targetChain and calls or tokenRequests are required\",\n },\n };\n }\n\n if (!this.sponsorship) {\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"MISSING_APP_CREDENTIALS\",\n errorMessage: \"No sponsorship configured on OneAuthClient\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"MISSING_APP_CREDENTIALS\",\n message:\n \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — configure `sponsorship` on the client.\",\n },\n };\n }\n\n // Convert bigint amounts to strings for API serialization\n const serializedTokenRequests = options.tokenRequests?.map((r) => ({\n token: r.token,\n amount: r.amount.toString(),\n }));\n let prepareResponse: PrepareIntentResponse;\n\n // 1. Show dialog immediately + prepare in parallel.\n //\n // Two-phase approach — why:\n // - The dialog is shown right away so the user sees a UI immediately.\n // - Access-token minting also runs behind the dialog boot. The prepare\n // request still needs the token, but the iframe/chunk load does not;\n // overlapping them removes a cold app-token round trip from the\n // perceived loading path.\n // - Intent preparation (API call to the orchestrator for a quote) can\n // take 1–3 seconds. Hiding the dialog until the quote is ready would\n // make the interaction feel sluggish.\n // - Phase 1: send a stable transaction shell with raw calls but ask the\n // dialog to hold the movement card skeleton until the quote arrives.\n // Decoded previews are useful in isolation, but here they cause noisy\n // value churn when quote-normalized token decimals replace them.\n // - Phase 2: once the quote arrives, send a narrow quote-ready update\n // instead of replaying the whole PASSKEY_INIT path.\n //\n // Fast path: if preparation finishes before the iframe signals PASSKEY_READY\n // (e.g. on a fast connection), we skip phase 1 entirely and send the full\n // payload in a single PASSKEY_INIT message.\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams();\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogOrigin = this.getDialogOrigin();\n const dialogOpenedAt = Date.now();\n let iframeReadyObserved = false;\n type EarlyDialogClose = { type: \"dialog_closed\"; ready: boolean };\n let stopEarlyCloseWatch: () => void = () => undefined;\n const earlyDialogClosePromise = new Promise<EarlyDialogClose>((resolve) => {\n let settled = false;\n const stop = () => {\n if (settled) return;\n settled = true;\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n stopEarlyCloseWatch = stop;\n\n const resolveClosed = (ready: boolean) => {\n stop();\n cleanup();\n resolve({ type: \"dialog_closed\", ready });\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n // Scope the CLOSE to *this* sign dialog's iframe. authWithModal() and\n // sendIntent() share the same dialogOrigin (passkey.1auth.app), so the\n // auth dialog's PASSKEY_CLOSE — emitted async as it tears down on a\n // successful sign-in — can still be in-flight when sendIntent attaches\n // this listener for its brand-new dialog. Without the source check it\n // gets misattributed to the sign dialog and cancels it before it's\n // ready (USER_CANCELLED). Same guard the modal auth listener already\n // applies via event.source === iframe.contentWindow.\n if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n resolveClosed(iframeReadyObserved);\n }\n };\n\n const handleClose = () => {\n resolveClosed(iframeReadyObserved);\n };\n\n // Covers the gap after PASSKEY_READY but before the full signing listener\n // is installed. Without this, closing the loading dialog during a cold\n // access-token fetch drops PASSKEY_CLOSE and lets prepare continue.\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n let dialogReadyDurationMs: number | undefined;\n const dialogReadyPromise = this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n }).then((result) => {\n dialogReadyDurationMs = Date.now() - dialogOpenedAt;\n iframeReadyObserved = result.ready;\n return result;\n });\n const dialogClosedBeforeReadyPromise = dialogReadyPromise.then((result) =>\n result.ready\n ? new Promise<never>(() => undefined)\n : ({ type: \"dialog_closed\" as const, ready: false }),\n );\n\n const accessTokenStartedAt = Date.now();\n let accessTokenDurationMs: number | undefined;\n const accessTokenPromise = this.fetchAccessToken().then((result) => {\n accessTokenDurationMs = Date.now() - accessTokenStartedAt;\n return result;\n });\n\n const accessOrClose = await Promise.race([\n accessTokenPromise.then((result) => ({ type: \"access_token\" as const, result })),\n dialogClosedBeforeReadyPromise,\n earlyDialogClosePromise,\n ]);\n if (accessOrClose.type === \"dialog_closed\") {\n stopEarlyCloseWatch();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: accessOrClose.ready\n ? \"User closed the dialog while intent setup was still loading\"\n : \"User closed the dialog before it became ready\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n },\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n\n const accessTokenResult = accessOrClose.result;\n // Access-token failures are NOT returned early: they're converted into a\n // synthetic failed PrepareResult below so the dialog's prepare-error\n // retry (\"Try Again\" → PASSKEY_RETRY_PREPARE) covers them too — the\n // retry path re-mints the token first, which is exactly the recovery a\n // transient token-endpoint failure needs.\n let accessTokenFailure: { code: string; message: string } | null = null;\n if (!accessTokenResult.ok) {\n const errorCode = accessTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\";\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode,\n errorMessage: accessTokenResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n loadingPhase: \"access_token\",\n },\n });\n accessTokenFailure = { code: errorCode, message: accessTokenResult.message };\n }\n // Mutable: a dialog-initiated prepare retry re-mints the token (the most\n // common prepare failure is an expired app JWT) and later auth bundles\n // must carry the token the successful prepare actually used.\n let accessToken = accessTokenResult.ok ? accessTokenResult.accessToken : \"\";\n\n // Define requestBody outside try block so it's accessible for quote refresh.\n const requestBody = {\n username,\n accountAddress,\n targetChain,\n calls,\n tokenRequests: serializedTokenRequests,\n sourceAssets: options.sourceAssets,\n sourceChainId: options.sourceChainId,\n auth: { accessToken },\n ...(this.config.clientId && { clientId: this.config.clientId }),\n };\n\n // Start prepare in background; track completion via mutable variable.\n // When the iframe becomes ready, earlyPrepareResult will be non-null\n // if prepare finished first (fast path), or null if still in flight.\n type PrepareResult =\n | { success: true; data: PrepareIntentResponse; tier: string | null }\n | { success: false; error: { code: string; message: string; details?: unknown } };\n let earlyPrepareResult: PrepareResult | null = null;\n // Per-intent extension token is fetched in parallel with the signing\n // ceremony: as soon as /prepare returns `intentOp`, we kick off the\n // app-scoped callback. The fetch overlaps with iframe-ready + user\n // review + WebAuthn tap, so by the time the dialog is ready to call\n // /execute the token is already in the init payload. Empty array when\n // `sponsor: false` — the user pays from source assets instead.\n let extensionTokensPromise: Promise<ExtensionTokensFetchResult> =\n Promise.resolve({ ok: true, extensionTokens: [] });\n let extensionTokensDurationMs: number | undefined;\n this.emitTelemetry(\"intent.prepare.started\", telemetry, {\n outcome: \"started\",\n targetChain,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n },\n });\n const prepareStartedAt = Date.now();\n let prepareDurationMs: number | undefined;\n // Wrapped so dialog-initiated retries (PASSKEY_RETRY_PREPARE after a\n // prepare error) can re-run the exact same prepare + telemetry +\n // extension-token kickoff with an updated `requestBody.auth`.\n const runPrepare = () => this.prepareIntent(requestBody, telemetry).then((r) => {\n earlyPrepareResult = r;\n prepareDurationMs = Date.now() - prepareStartedAt;\n if (r.success) {\n this.emitTelemetry(\"intent.prepare.succeeded\", telemetry, {\n outcome: \"success\",\n targetChain,\n status: \"quoted\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n },\n });\n const extensionTokensStartedAt = Date.now();\n extensionTokensPromise = this.fetchExtensionTokens(\n [r.data.intentOp],\n [sponsor],\n ).then((result) => {\n extensionTokensDurationMs = Date.now() - extensionTokensStartedAt;\n return result;\n });\n } else {\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n targetChain,\n ...describeTelemetryError(r.error),\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n loadingPhase: \"prepare\",\n },\n });\n }\n return r;\n });\n // When the access token never materialised, seed the flow with a failed\n // result instead of calling /prepare with empty auth — the fast/\n // progressive retry loops below surface it in the dialog and the user's\n // retry re-mints the token before re-running prepare.\n const preparePromise = accessTokenFailure\n ? Promise.resolve<PrepareResult>({\n success: false,\n error: accessTokenFailure,\n }).then((r) => {\n earlyPrepareResult = r;\n return r;\n })\n : runPrepare();\n\n // Re-run prepare after the dialog requested a retry. Re-mints the app\n // access token first: the dominant cause of prepare failures is the app\n // JWT expiring (orchestrator 401), so retrying with the original token\n // would fail forever. Returns the new PrepareResult — failures feed back\n // into the caller's retry loop.\n const retryPrepare = async (): Promise<PrepareResult> => {\n const retryTokenResult = await this.fetchAccessToken();\n if (!retryTokenResult.ok) {\n return {\n success: false,\n error: {\n code: retryTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\",\n message: retryTokenResult.message,\n },\n };\n }\n accessToken = retryTokenResult.accessToken;\n requestBody.auth = { accessToken };\n return runPrepare();\n };\n\n // Wait for iframe to be ready\n const readyOrClose = await Promise.race([\n dialogReadyPromise.then((result) => ({ type: \"ready\" as const, result })),\n earlyDialogClosePromise,\n ]);\n if (readyOrClose.type === \"dialog_closed\") {\n stopEarlyCloseWatch();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: readyOrClose.ready\n ? \"User closed the dialog while intent setup was still loading\"\n : \"User closed the dialog before it became ready\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n },\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n const dialogResult = readyOrClose.result;\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\n stopEarlyCloseWatch();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the dialog before it became ready\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, {\n outcome: \"started\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n },\n });\n\n // Mutable init payload — starts as early preview, upgraded to full after quote\n let currentInitPayload: Record<string, unknown>;\n const refreshQuote = async () => {\n try {\n // Re-mint the app access token for the refreshed prepare. Quote\n // refreshes happen when the user lingers on the review screen, so\n // the token captured in `requestBody` may be close to (or past) its\n // 1h expiry — the orchestrator would reject it with a 401 and the\n // refresh would fail even though the quote itself is refreshable.\n const refreshedTokenResult = await this.fetchAccessToken();\n const refreshToken = refreshedTokenResult.ok\n ? refreshedTokenResult.accessToken\n : accessToken;\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify({ ...requestBody, auth: { accessToken: refreshToken } }),\n credentials: \"include\",\n });\n\n if (!refreshResponse.ok) {\n console.error(\"[SDK] Quote refresh failed:\", await refreshResponse.text());\n return null;\n }\n\n const refreshedData = await refreshResponse.json();\n\n // Re-bind the ENTIRE auth bundle to the refreshed quote, not just the\n // refresh HTTP call. Extension grants are digest-bound to their\n // intentOp, so a grant minted for the previous quote cannot authorize\n // the refreshed one — execute would sign the new intentOp but submit\n // stale auth and fail. Block until the new grant lands so the dialog\n // can never sign a refreshed quote with mismatched auth.\n const refreshedExtensionPromise = this.fetchExtensionTokens(\n [refreshedData.intentOp],\n [sponsor],\n );\n const extensionResult = await refreshedExtensionPromise;\n if (!extensionResult.ok) {\n console.error(\n \"[SDK] Extension token refresh failed:\",\n extensionResult.message,\n );\n return null;\n }\n const refreshedAuth: SponsorshipTokens = {\n accessToken: refreshToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n\n // Keep execute (legacy SDK-submit path) aligned with the latest quote\n // the dialog is reviewing — token, grant, and quote move together.\n prepareResponse = refreshedData;\n accessToken = refreshToken;\n requestBody.auth = { accessToken: refreshToken };\n extensionTokensPromise = refreshedExtensionPromise;\n // Keep iframe-remount replays (PASSKEY_READY → PASSKEY_INIT) on the\n // refreshed quote too.\n currentInitPayload = {\n ...currentInitPayload,\n transaction: refreshedData.transaction,\n challenge: refreshedData.challenge,\n originMessages: refreshedData.originMessages,\n expiresAt: refreshedData.expiresAt,\n intentOp: refreshedData.intentOp,\n digestResult: refreshedData.digestResult,\n // A refreshed quote mints a fresh binding — it MUST replace the old\n // one, or execute would verify the new intentOp against a stale\n // binding and reject (once enforce mode is on).\n binding: refreshedData.binding,\n auth: refreshedAuth,\n };\n return {\n intentOp: refreshedData.intentOp,\n expiresAt: refreshedData.expiresAt,\n challenge: refreshedData.challenge,\n originMessages: refreshedData.originMessages,\n transaction: refreshedData.transaction,\n digestResult: refreshedData.digestResult,\n binding: refreshedData.binding,\n // Dialog-executed intents read auth from dialog state — ship the\n // rebound bundle with the refresh so PASSKEY_REFRESH_COMPLETE\n // updates it alongside the quote.\n auth: refreshedAuth,\n };\n } catch (error) {\n console.error(\"[SDK] Quote refresh error:\", error);\n return null;\n }\n };\n // Install the close/result listener before the progressive preview init is\n // sent. Otherwise a user can click Cancel while /prepare is still waiting\n // on quote or portfolio work, and the parent page drops the message.\n const signingResultPromise = this.waitForSigningWithRefresh(\n dialog,\n iframe,\n cleanup,\n dialogOrigin,\n refreshQuote,\n );\n stopEarlyCloseWatch();\n\n if (earlyPrepareResult) {\n // Fast path: prepare already finished — send full PASSKEY_INIT (no regression)\n // Type assertion needed: TS control flow doesn't track .then() mutations\n let prepareResult = earlyPrepareResult as PrepareResult;\n // Same retry contract as the progressive path below: any failure before\n // the full payload reaches the dialog surfaces as PASSKEY_PREPARE_ERROR,\n // and the dialog's \"Try Again\" re-enters via PASSKEY_RETRY_PREPARE.\n for (;;) {\n while (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n if (blindSigning) {\n // No visible dialog to host the error/retry UI — fail immediately.\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResult = await retryPrepare();\n }\n prepareResponse = prepareResult.data;\n const extensionResult = await extensionTokensPromise;\n if (extensionResult.ok) {\n const sponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n currentInitPayload = {\n mode: \"iframe\",\n calls,\n chainId: targetChain,\n transaction: prepareResponse.transaction,\n challenge: prepareResponse.challenge,\n username,\n accountAddress: prepareResponse.accountAddress,\n originMessages: prepareResponse.originMessages,\n tokenRequests: serializedTokenRequests,\n expiresAt: prepareResponse.expiresAt,\n userId: prepareResponse.userId,\n intentOp: prepareResponse.intentOp,\n digestResult: prepareResponse.digestResult,\n binding: prepareResponse.binding,\n tier: prepareResult.tier,\n auth: sponsorshipTokens,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentInitPayload);\n break;\n }\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: extensionResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n loadingPhase: \"extension_token\",\n },\n });\n this.sendPrepareError(iframe, extensionResult.message);\n if (blindSigning) {\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n // Retrying just the extension token would be unsafe — grants are\n // digest-bound to the intentOp — so re-run the full prepare.\n prepareResult = await retryPrepare();\n }\n } else {\n // Progressive path: send the raw calls up front so the dialog can\n // decode them locally (/api/decode) and reveal a fully-formed\n // transaction card the moment decode settles — without waiting on the\n // orchestrator quote. The quote follows via PASSKEY_QUOTE_READY below\n // and upgrades the fee row + any routed amounts in place. The dialog\n // gates the Sign button on that authoritative quote, so revealing the\n // decoded preview early never lets the user sign un-quoted data.\n currentInitPayload = {\n mode: \"iframe\",\n signingMode: \"transaction\",\n calls,\n chainId: targetChain,\n username,\n accountAddress: options.accountAddress,\n tokenRequests: serializedTokenRequests,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentInitPayload);\n\n // Wait for prepare to complete, then send quote data\n const prepareOrCancel = await Promise.race([\n preparePromise.then((prepareResult) => ({\n type: \"prepare\" as const,\n prepareResult,\n })),\n signingResultPromise.then((signingResult) => ({\n type: \"signing\" as const,\n signingResult,\n })),\n ]);\n let prepareResult: PrepareResult;\n if (prepareOrCancel.type === \"signing\") {\n const earlySigningResult = prepareOrCancel.signingResult;\n if (earlySigningResult.success) {\n // Signing cannot complete before the prepared challenge arrives, but\n // keep this branch total so TypeScript and future hidden flows have a\n // deterministic path to the quote data needed for execute.\n prepareResult = await preparePromise;\n } else {\n const signingError = earlySigningResult.error;\n this.emitTelemetry(\n signingError?.code === \"USER_REJECTED\"\n ? \"dialog.cancelled\"\n : \"intent.sign.failed\",\n telemetry,\n {\n outcome: signingError?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingError),\n },\n );\n if (blindSigning) cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: signingError,\n };\n }\n } else {\n prepareResult = prepareOrCancel.prepareResult;\n }\n // Drive prepare → quote-ready → extension-token to completion, looping\n // back through the dialog's \"Try Again\" (PASSKEY_RETRY_PREPARE) on any\n // failure along the way. Each retry re-runs the FULL prepare so the\n // quote and the per-intent sponsorship grant always match — a grant is\n // digest-bound to its intentOp, so retrying just the extension token\n // against a re-quoted intent would produce an unusable auth bundle.\n for (;;) {\n while (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n if (blindSigning) {\n // No visible dialog to host the error/retry UI — fail immediately.\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResult = await retryPrepare();\n }\n prepareResponse = prepareResult.data;\n const authReady =\n !sponsor\n ? ({\n accessToken,\n extensionTokens: [],\n } satisfies SponsorshipTokens)\n : undefined;\n\n // Upgrade the init payload with full quote data. For sponsored intents,\n // don't wait for the extension token here: review display needs the quote,\n // while submit auth can arrive as a small follow-up before Sign unlocks.\n currentInitPayload = {\n mode: \"iframe\",\n calls,\n chainId: targetChain,\n transaction: prepareResponse.transaction,\n challenge: prepareResponse.challenge,\n username,\n accountAddress: prepareResponse.accountAddress,\n originMessages: prepareResponse.originMessages,\n tokenRequests: serializedTokenRequests,\n expiresAt: prepareResponse.expiresAt,\n userId: prepareResponse.userId,\n intentOp: prepareResponse.intentOp,\n digestResult: prepareResponse.digestResult,\n binding: prepareResponse.binding,\n tier: prepareResult.tier,\n ...(authReady && { auth: authReady }),\n telemetry: this.telemetryPayload(telemetry),\n };\n\n // Narrow update: avoid replaying PASSKEY_INIT, which would rerun broad\n // dialog initialization and briefly replace the skeleton/preview state\n // before the authoritative quote-backed transaction lands.\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_QUOTE_READY\", ...currentInitPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n\n if (!sponsor) break;\n\n const extensionResult = await extensionTokensPromise;\n if (extensionResult.ok) {\n const sponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n currentInitPayload = {\n ...currentInitPayload,\n auth: sponsorshipTokens,\n };\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_QUOTE_READY\", auth: sponsorshipTokens, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n break;\n }\n\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: extensionResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n loadingPhase: \"extension_token\",\n },\n });\n this.sendPrepareError(iframe, extensionResult.message);\n if (blindSigning) {\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n prepareResult = await retryPrepare();\n }\n }\n\n // 2. Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n // so the sign page recovers its state. Uses currentInitPayload which is the\n // full payload after quote arrives.\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentInitPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n // 3. Wait for signing result with auto-refresh support\n // This custom handler handles both signing results AND quote refresh requests.\n const signingResult = await signingResultPromise;\n\n window.removeEventListener(\"message\", handleReReady);\n\n if (!signingResult.success) {\n this.emitTelemetry(\n signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"intent.sign.failed\",\n telemetry,\n {\n outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingResult.error),\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n },\n },\n );\n if (blindSigning) cleanup();\n return {\n success: false,\n intentId: \"\", // No intentId yet - signing was cancelled before execute\n status: \"failed\",\n error: signingResult.error,\n };\n }\n\n // Check if dialog already executed the intent (new secure flow)\n // In this case, signingResult contains intentId instead of signature\n const dialogExecutedIntent = \"intentId\" in signingResult && signingResult.intentId;\n\n // 5. Execute intent with signature (skip if dialog already executed)\n let executeResponse: ExecuteIntentResponse;\n\n if (dialogExecutedIntent) {\n // Dialog already executed - use the returned intentId\n executeResponse = {\n success: true,\n intentId: signingResult.intentId as string,\n status: \"pending\",\n };\n this.emitTelemetry(\"intent.sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n dialogExecuted: true,\n },\n });\n } else {\n // Legacy flow - execute with signature from dialog. The extension\n // token was already fetched in parallel with signing above, so this\n // just awaits the (usually already-resolved) promise. `accessToken` was\n // fetched before /prepare, overlapped with the dialog iframe boot.\n const extensionResult = await extensionTokensPromise;\n if (!extensionResult.ok) {\n this.emitTelemetry(\"intent.sign.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: extensionResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n loadingPhase: \"extension_token\",\n },\n });\n this.sendTransactionStatus(iframe, \"failed\");\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n const extensionTokens = extensionResult.extensionTokens;\n try {\n this.emitTelemetry(\"intent.sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n dialogExecuted: false,\n },\n });\n this.emitTelemetry(\"intent.execute.started\", telemetry, {\n outcome: \"started\",\n targetChain: prepareResponse.targetChain,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n },\n });\n const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.telemetryHeaders(telemetry),\n },\n body: JSON.stringify({\n // Data from prepare response (no intentId yet - created on execute)\n intentOp: prepareResponse.intentOp,\n userId: prepareResponse.userId,\n targetChain: prepareResponse.targetChain,\n calls: prepareResponse.calls,\n expiresAt: prepareResponse.expiresAt,\n digestResult: prepareResponse.digestResult,\n // Opaque prepare->execute binding, forwarded unchanged.\n binding: prepareResponse.binding,\n // Signature from dialog\n signature: signingResult.signature,\n passkey: signingResult.passkey, // Include passkey info for signature encoding\n // App JWT — `accessToken` is always present. `extensionToken` is\n // only included when sponsorship was requested (sponsor !== false).\n auth: {\n accessToken,\n ...(extensionTokens.length > 0 && {\n extensionToken: extensionTokens[0],\n }),\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n // Send failure status to dialog\n this.sendTransactionStatus(iframe, \"failed\");\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.emitTelemetry(\"intent.execute.failed\", telemetry, {\n outcome: \"failure\",\n targetChain: prepareResponse.targetChain,\n errorCode: \"EXECUTE_FAILED\",\n errorMessage: errorData.error || \"Failed to execute intent\",\n });\n return {\n success: false,\n intentId: \"\", // No intentId - execute failed before creation\n status: \"failed\",\n error: {\n code: \"EXECUTE_FAILED\",\n message: errorData.error || \"Failed to execute intent\",\n },\n };\n }\n\n executeResponse = await response.json();\n this.emitTelemetry(\"intent.execute.succeeded\", telemetry, {\n outcome: \"success\",\n targetChain: prepareResponse.targetChain,\n status: executeResponse.status,\n });\n } catch (error) {\n // Send failure status to dialog\n this.sendTransactionStatus(iframe, \"failed\");\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.emitTelemetry(\"intent.execute.failed\", telemetry, {\n outcome: \"failure\",\n targetChain: prepareResponse.targetChain,\n ...describeTelemetryError(error),\n });\n return {\n success: false,\n intentId: \"\", // No intentId - network error before creation\n status: \"failed\",\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network error\",\n },\n };\n }\n }\n\n // 6. Poll for completion with status updates to dialog\n let finalStatus = executeResponse.status;\n let finalTxHash = executeResponse.transactionHash;\n\n if (finalStatus === \"pending\") {\n // Send initial pending status to dialog\n this.sendTransactionStatus(iframe, \"pending\");\n this.emitTelemetry(\"intent.status.started\", telemetry, {\n outcome: \"started\",\n status: finalStatus,\n });\n\n // Listen for early close (user clicking X) during polling.\n // Close the dialog immediately so the user gets instant feedback.\n let userClosedEarly = false;\n const dialogOrigin = this.getDialogOrigin();\n const earlyCloseHandler = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n // Scope to this dialog's iframe so a same-origin CLOSE from another\n // 1auth dialog (e.g. a queued auth-modal teardown) can't be\n // misattributed to this poll and cancel it. Mirrors the early-close\n // watcher above and the modal auth listener's source guard.\n if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n userClosedEarly = true;\n cleanup();\n }\n };\n window.addEventListener(\"message\", earlyCloseHandler);\n\n // Poll status endpoint for updates\n const maxAttempts = 120; // 3 minutes at 1.5s intervals\n const pollIntervalMs = 1500;\n let lastStatus = \"pending\";\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (userClosedEarly) break;\n\n try {\n const statusResponse = await fetch(\n `${this.config.providerUrl}/api/intent/status/${executeResponse.intentId}`,\n {\n method: \"GET\",\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n }\n );\n\n if (statusResponse.ok) {\n const statusResult = await statusResponse.json();\n finalStatus = statusResult.status;\n finalTxHash = statusResult.transactionHash;\n\n // Send status update to dialog if changed\n if (finalStatus !== lastStatus) {\n this.sendTransactionStatus(iframe, finalStatus, finalTxHash);\n lastStatus = finalStatus;\n }\n\n // Exit if terminal status reached\n // closeOn determines when to consider the intent successful (default: preconfirmed)\n const closeOn = options.closeOn || \"preconfirmed\";\n const successStatuses: Record<string, string[]> = {\n claimed: [\"claimed\", \"preconfirmed\", \"filled\", \"completed\"],\n preconfirmed: [\"preconfirmed\", \"filled\", \"completed\"],\n filled: [\"filled\", \"completed\"],\n completed: [\"completed\"],\n };\n const isTerminal = finalStatus === \"failed\" || finalStatus === \"expired\";\n const isSuccess = successStatuses[closeOn]?.includes(finalStatus) ?? false;\n if (isTerminal || isSuccess) {\n break;\n }\n }\n } catch (pollError) {\n console.error(\"Failed to poll intent status:\", pollError);\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n\n window.removeEventListener(\"message\", earlyCloseHandler);\n\n // If user closed during polling, clean up and return current status\n if (userClosedEarly) {\n cleanup();\n this.emitTelemetry(\"intent.status.failed\", telemetry, {\n outcome: \"cancelled\",\n status: finalStatus,\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the dialog while status polling\",\n });\n return {\n success: false,\n intentId: executeResponse.intentId,\n status: finalStatus,\n transactionHash: finalTxHash,\n operationId: executeResponse.operationId,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n };\n }\n }\n\n // 7. Send final status to dialog\n // Map successful statuses to \"confirmed\" based on closeOn setting\n const closeOn = options.closeOn || \"preconfirmed\";\n const successStatuses: Record<string, string[]> = {\n claimed: [\"claimed\", \"preconfirmed\", \"filled\", \"completed\"],\n preconfirmed: [\"preconfirmed\", \"filled\", \"completed\"],\n filled: [\"filled\", \"completed\"],\n completed: [\"completed\"],\n };\n const isSuccessStatus = successStatuses[closeOn]?.includes(finalStatus) ?? false;\n const displayStatus = isSuccessStatus ? \"confirmed\" : finalStatus;\n\n // Start listening for close BEFORE sending status to avoid race condition\n // where user clicks Done before the listener is registered\n const closePromise = this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.sendTransactionStatus(iframe, displayStatus, finalTxHash);\n\n // Wait for dialog to be closed by user\n await closePromise;\n\n if (options.waitForHash && !finalTxHash) {\n const hash = await this.waitForTransactionHash(executeResponse.intentId, {\n timeoutMs: options.hashTimeoutMs,\n intervalMs: options.hashIntervalMs,\n }, telemetry);\n if (hash) {\n finalTxHash = hash;\n finalStatus = \"completed\";\n } else {\n finalStatus = \"failed\";\n this.emitTelemetry(\"intent.status.failed\", telemetry, {\n outcome: \"failure\",\n status: finalStatus,\n errorCode: \"HASH_TIMEOUT\",\n errorMessage: \"Timed out waiting for transaction hash\",\n });\n return {\n success: false,\n intentId: executeResponse.intentId,\n status: finalStatus,\n transactionHash: finalTxHash,\n operationId: executeResponse.operationId,\n error: {\n code: \"HASH_TIMEOUT\",\n message: \"Timed out waiting for transaction hash\",\n },\n };\n }\n }\n\n this.emitTelemetry(\"intent.status.succeeded\", telemetry, {\n outcome: isSuccessStatus ? \"success\" : \"failure\",\n status: finalStatus,\n });\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: isSuccessStatus ? \"success\" : \"failure\",\n status: finalStatus,\n targetChain,\n });\n\n return {\n success: isSuccessStatus,\n intentId: executeResponse.intentId,\n status: finalStatus,\n transactionHash: finalTxHash,\n operationId: executeResponse.operationId,\n error: executeResponse.error,\n };\n }\n\n /**\n * Send a batch of intents for multi-chain execution with a single passkey tap.\n *\n * This method prepares multiple intents, shows a paginated review,\n * and signs all intents with a single passkey tap via a shared merkle tree.\n *\n * @example\n * ```typescript\n * const result = await client.sendBatchIntent({\n * username: 'alice',\n * intents: [\n * {\n * targetChain: 8453, // Base\n * calls: [{ to: '0x...', data: '0x...', label: 'Swap on Base' }],\n * },\n * {\n * targetChain: 42161, // Arbitrum\n * calls: [{ to: '0x...', data: '0x...', label: 'Mint on Arbitrum' }],\n * },\n * ],\n * });\n *\n * if (result.success) {\n * console.log(`${result.successCount} intents submitted`);\n * }\n * ```\n */\n async sendBatchIntent(options: SendBatchIntentOptions): Promise<SendBatchIntentResult> {\n const telemetry = this.createTelemetryOperation(\"batch_intent\", {\n intentCount: options.intents?.length ?? 0,\n blindSigning: this.shouldRequestBlindSigning(options),\n });\n if (getStoredSignerType() === \"eoa\") {\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"E_SIGNER_UNSUPPORTED\",\n errorMessage: \"Batch intents are not supported for EOA sessions\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n error:\n \"Batch intents are not supported for EOA sessions. Use the connected wallet's native RPC instead.\",\n };\n }\n\n if (!options.username && !options.accountAddress) {\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"Either username or accountAddress is required\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n if (!options.intents?.length) {\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"At least one intent is required\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n if (!this.sponsorship) {\n this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"MISSING_APP_CREDENTIALS\",\n errorMessage: \"No sponsorship configured on OneAuthClient\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n error:\n \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — configure `sponsorship` on the client.\",\n };\n }\n\n const sponsorFlags = options.intents.map((intent) => intent.sponsor !== false);\n\n // Fetch the app's access token up front — /api/intent/batch-prepare\n // requires it so the passkey server can authenticate its orchestrator\n // quote calls with the app's JWT instead of a service-level API key.\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: accessTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: accessTokenResult.message,\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n error: accessTokenResult.message,\n };\n }\n // Mutable: a quote refresh re-mints the token and must keep the execute\n // path's auth aligned with the refreshed quotes.\n let accessToken = accessTokenResult.accessToken;\n\n // Serialize token request amounts to strings for API. Each intent's\n // labels are capped via capCallLabels() so the dialog's phase-1 preview\n // (which reads from serializedIntents below) and the prepare request\n // both ship the same truncated strings.\n const serializedIntents = options.intents.map((intent) => ({\n targetChain: intent.targetChain,\n calls: capCallLabels(intent.calls),\n tokenRequests: intent.tokenRequests?.map((r) => ({\n token: r.token,\n amount: r.amount.toString(),\n })),\n sourceAssets: intent.sourceAssets,\n sourceChainId: intent.sourceChainId,\n moduleInstall: intent.moduleInstall,\n }));\n\n const requestBody = {\n ...(options.username && { username: options.username }),\n ...(options.accountAddress && { accountAddress: options.accountAddress }),\n intents: serializedIntents,\n auth: { accessToken },\n ...(this.config.clientId && { clientId: this.config.clientId }),\n };\n\n // 1. Show dialog immediately + prepare batch in parallel.\n //\n // Same two-phase approach as sendIntent: open the dialog right away with\n // raw call data so the user sees something immediately, then upgrade to the\n // full quote payload once batch-prepare completes. See sendIntent for the\n // full rationale.\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams();\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n intentCount: options.intents.length,\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogOrigin = this.getDialogOrigin();\n\n // Start batch-prepare in background; track completion via mutable variable\n type BatchPrepareResult =\n | { success: true; data: PrepareBatchIntentResponse; tier: string | null }\n | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> };\n let earlyBatchResult: BatchPrepareResult | null = null;\n // Pre-fetch one extension token per intent in parallel with the signing\n // ceremony. Rhinestone's `getIntentExtensionToken(intentInput)` is\n // per-intent, so the passkey server needs a token aligned with each\n // intent's position in the batch.\n let batchExtensionTokensPromise: Promise<ExtensionTokensFetchResult> =\n Promise.resolve({ ok: true, extensionTokens: [] });\n this.emitTelemetry(\"batch.prepare.started\", telemetry, {\n outcome: \"started\",\n intentCount: options.intents.length,\n targetChains: serializedIntents.map((intent) => intent.targetChain),\n });\n const preparePromise = this.prepareBatchIntent(requestBody, telemetry).then((r) => {\n earlyBatchResult = r;\n if (r.success) {\n this.emitTelemetry(\"batch.prepare.succeeded\", telemetry, {\n outcome: \"success\",\n intentCount: r.data.intents.length,\n targetChains: serializedIntents.map((intent) => intent.targetChain),\n });\n batchExtensionTokensPromise = this.fetchExtensionTokens(\n r.data.intents.map((intent) => intent.intentOp),\n sponsorFlags,\n );\n } else {\n this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorMessage: r.error,\n intentCount: options.intents.length,\n });\n }\n return r;\n });\n\n // Wait for iframe to be ready\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the dialog before it became ready\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n // Mutable init payload — starts as early preview, upgraded to full after quote\n let currentBatchPayload: Record<string, unknown>;\n\n // Helper to handle batch prepare failure\n const handleBatchPrepareFailure = async (\n prepareResult: Extract<BatchPrepareResult, { success: false }>,\n ) => {\n const failedIntents = prepareResult.failedIntents;\n const failureResults: import(\"./types\").BatchIntentItemResult[] = failedIntents?.map((f) => ({\n index: f.index,\n success: false,\n intentId: \"\",\n status: \"failed\" as import(\"./types\").IntentStatus,\n error: { message: f.error, code: \"PREPARE_FAILED\" },\n })) ?? [];\n\n this.sendPrepareError(iframe, prepareResult.error);\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n return {\n success: false as const,\n results: failureResults,\n successCount: 0,\n failureCount: failureResults.length,\n error: prepareResult.error,\n };\n };\n\n // Helper to handle sponsorship-fetch failure after batch prepare succeeded.\n // The passkey server cannot submit a sponsored batch without tokens, so\n // tear the dialog down and surface the error as a uniform batch failure.\n const handleSponsorshipFailure = async (message: string) => {\n this.sendPrepareError(iframe, message);\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n return {\n success: false as const,\n results: [],\n successCount: 0,\n failureCount: 0,\n error: `Sponsorship token fetch failed: ${message}`,\n };\n };\n\n let prepareResponse: PrepareBatchIntentResponse;\n\n if (earlyBatchResult) {\n // Fast path: batch-prepare already finished — send full PASSKEY_INIT\n const prepareResult = earlyBatchResult as BatchPrepareResult;\n if (!prepareResult.success) {\n return handleBatchPrepareFailure(prepareResult);\n }\n prepareResponse = prepareResult.data;\n const batchExtensionResult = await batchExtensionTokensPromise;\n if (!batchExtensionResult.ok) {\n return handleSponsorshipFailure(batchExtensionResult.message);\n }\n const batchSponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: batchExtensionResult.extensionTokens,\n };\n currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: prepareResponse.intents,\n batchFailedIntents: prepareResponse.failedIntents,\n challenge: prepareResponse.challenge,\n binding: prepareResponse.binding,\n username: options.username,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\n auth: batchSponsorshipTokens,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentBatchPayload);\n } else {\n // Progressive path: send early preview with raw intent calls\n currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: serializedIntents.map((intent, idx) => ({\n index: idx,\n targetChain: intent.targetChain,\n calls: JSON.stringify(intent.calls),\n // No: transaction, intentOp, expiresAt, originMessages\n })),\n username: options.username,\n accountAddress: options.accountAddress,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentBatchPayload);\n\n // Wait for batch-prepare to complete, then send quote data\n const prepareResult = await preparePromise;\n if (!prepareResult.success) {\n return handleBatchPrepareFailure(prepareResult);\n }\n prepareResponse = prepareResult.data;\n const batchExtensionResult = await batchExtensionTokensPromise;\n if (!batchExtensionResult.ok) {\n return handleSponsorshipFailure(batchExtensionResult.message);\n }\n const batchSponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: batchExtensionResult.extensionTokens,\n };\n\n // Upgrade the payload with full quote data\n currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: prepareResponse.intents,\n batchFailedIntents: prepareResponse.failedIntents,\n challenge: prepareResponse.challenge,\n binding: prepareResponse.binding,\n username: options.username,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\n auth: batchSponsorshipTokens,\n telemetry: this.telemetryPayload(telemetry),\n };\n\n // Re-send as PASSKEY_INIT so all dialog versions handle it\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentBatchPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n\n // 2. Handle iframe remount: resend PASSKEY_INIT on subsequent PASSKEY_READY\n const handleBatchReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentBatchPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleBatchReReady);\n\n // 3. Wait for batch signing result with auto-refresh support\n const batchResult = await new Promise<SendBatchIntentResult>((resolve) => {\n const handleMessage = async (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n\n // Handle quote refresh request\n if (message?.type === \"PASSKEY_REFRESH_QUOTE\") {\n try {\n // Re-mint the app access token — refreshes fire after the user\n // lingered on review, so the token in `requestBody` may have\n // crossed its 1h expiry (orchestrator would 401 the re-quote).\n const refreshedTokenResult = await this.fetchAccessToken();\n const refreshToken = refreshedTokenResult.ok\n ? refreshedTokenResult.accessToken\n : accessToken;\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify({ ...requestBody, auth: { accessToken: refreshToken } }),\n });\n\n if (refreshResponse.ok) {\n const refreshed: PrepareBatchIntentResponse = await refreshResponse.json();\n\n // Re-bind the auth bundle to the refreshed intentOps — same\n // contract as the single-intent refresh: extension grants are\n // digest-bound, so grants minted for the previous quotes\n // cannot authorize the refreshed ones at execute. Mirrors the\n // initial batch fetch (returned-intent order × sponsorFlags).\n const refreshedExtensionPromise = this.fetchExtensionTokens(\n refreshed.intents.map((intent) => intent.intentOp),\n sponsorFlags,\n );\n const extensionResult = await refreshedExtensionPromise;\n if (!extensionResult.ok) {\n console.error(\n \"[SDK] Batch extension token refresh failed:\",\n extensionResult.message,\n );\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh batch quotes\",\n }, dialogOrigin);\n return;\n }\n const refreshedAuth: SponsorshipTokens = {\n accessToken: refreshToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n\n prepareResponse = refreshed;\n accessToken = refreshToken;\n requestBody.auth = { accessToken: refreshToken };\n batchExtensionTokensPromise = refreshedExtensionPromise;\n // Keep iframe-remount replays on the refreshed quotes + auth.\n currentBatchPayload = {\n ...currentBatchPayload,\n batchIntents: refreshed.intents,\n batchFailedIntents: refreshed.failedIntents,\n challenge: refreshed.challenge,\n binding: refreshed.binding,\n expiresAt: refreshed.expiresAt,\n auth: refreshedAuth,\n };\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_COMPLETE\",\n batchIntents: refreshed.intents,\n challenge: refreshed.challenge,\n binding: refreshed.binding,\n expiresAt: refreshed.expiresAt,\n auth: refreshedAuth,\n }, dialogOrigin);\n } else {\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh batch quotes\",\n }, dialogOrigin);\n }\n } catch {\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh batch quotes\",\n }, dialogOrigin);\n }\n return;\n }\n\n // Handle signing result with batch results\n if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n\n if (message.success && message.data?.batchResults) {\n const rawResults: Array<{\n index: number;\n operationId?: string;\n intentId?: string;\n status: string;\n error?: string;\n success?: boolean;\n }> = message.data.batchResults;\n\n const results: BatchIntentItemResult[] = rawResults.map((r) => ({\n index: r.index,\n success: r.success ?? r.status !== \"FAILED\",\n intentId: r.intentId || r.operationId || \"\",\n status: r.status === \"FAILED\" ? \"failed\" : \"pending\",\n error: r.error ? { code: \"EXECUTE_FAILED\", message: r.error } : undefined,\n }));\n\n // Merge in prepare-phase failures (e.g. account not deployed on chain).\n // These intents never reached the dialog (they were filtered out before\n // the signing screen), so we re-attach them here to give callers a\n // complete, index-sorted result set covering every input intent.\n const prepareFailures: BatchIntentItemResult[] = (prepareResponse.failedIntents ?? []).map((f) => ({\n index: f.index,\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"PREPARE_FAILED\", message: f.error },\n }));\n const allResults = [...results, ...prepareFailures].sort((a, b) => a.index - b.index);\n\n const successCount = allResults.filter((r) => r.success).length;\n\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.emitTelemetry(\"batch.sign.succeeded\", telemetry, {\n outcome: \"success\",\n intentCount: allResults.length,\n });\n\n resolve({\n success: successCount === allResults.length,\n results: allResults,\n successCount,\n failureCount: allResults.length - successCount,\n });\n } else {\n // Signing failed or was cancelled\n cleanup();\n this.emitTelemetry(\"batch.sign.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SIGNING_FAILED\",\n errorMessage: \"Batch signing failed or was cancelled\",\n });\n resolve({\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n });\n }\n }\n\n // Handle dialog close\n if (message?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the batch dialog\",\n });\n resolve({\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n\n window.removeEventListener(\"message\", handleBatchReReady);\n\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: batchResult.success ? \"success\" : \"failure\",\n intentCount: batchResult.results.length,\n attributes: {\n successCount: batchResult.successCount,\n failureCount: batchResult.failureCount,\n },\n ...(batchResult.error ? { errorMessage: batchResult.error } : {}),\n });\n\n return batchResult;\n }\n\n /**\n * Send transaction status to the dialog iframe\n */\n private sendTransactionStatus(\n iframe: HTMLIFrameElement,\n status: string,\n transactionHash?: string\n ): void {\n const dialogOrigin = this.getDialogOrigin();\n iframe.contentWindow?.postMessage(\n {\n type: \"TRANSACTION_STATUS\",\n status,\n transactionHash,\n },\n dialogOrigin\n );\n }\n\n /**\n * Listen for a signing result that belongs to a specific `requestId`.\n *\n * Used by legacy server-side signing request flows (popup/embed/modal) where\n * the dialog was pre-loaded with a signing request created via the API. The\n * `requestId` filter is needed because multiple dialogs may be open or there\n * may be stale messages from a previous dialog in the queue.\n *\n * Resolves on `PASSKEY_SIGNING_RESULT` matching `requestId`, or on\n * `PASSKEY_CLOSE` (user dismissed the dialog).\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param dialog - The `<dialog>` element (opened before this call) used to\n * `showModal()` so the dialog becomes interactive.\n * @param _iframe - Unused; kept for signature consistency with other wait helpers.\n * @param cleanup - Idempotent teardown function that closes and removes the dialog.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForIntentSigningResponse(\n requestId: string,\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature; passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string } } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\" && payload?.requestId === requestId) {\n window.removeEventListener(\"message\", handleMessage);\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n passkey: payload.passkey, // Include passkey info for signature encoding\n });\n } else {\n resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (\n message?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // User clicked X button to close/reject. Cross-frame guard: ignore a\n // stray PASSKEY_CLOSE from a sibling same-origin dialog so it can't\n // forge a rejection of this signing request.\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n dialog.showModal();\n });\n }\n\n /**\n * Listen for a signing result from the currently open modal dialog.\n *\n * Unlike `waitForIntentSigningResponse`, this variant does not filter by\n * `requestId` because the inline intent flow (sendIntent / signMessage /\n * signTypedData) owns the dialog exclusively — there is no risk of collisions\n * from other dialogs.\n *\n * Handles two result shapes:\n * - New \"secure flow\": dialog executed the intent server-side and returns\n * only an `intentId` (no signature exposed to the SDK).\n * - Legacy flow: dialog returns a raw `WebAuthnSignature` for the SDK to\n * forward to the execute endpoint.\n *\n * @param dialog - The `<dialog>` element wrapping the signing iframe.\n * @param iframe - The signing iframe; used to authenticate the source of\n * `PASSKEY_CLOSE` so a sibling same-origin dialog can't forge a rejection.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @returns A `SigningResult` extended with an optional `signedHash` field\n * populated when the dialog performs message signing.\n */\n private waitForSigningResponse(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult & { signedHash?: string }> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n const payload = message?.data as { signature?: WebAuthnSignature; passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string }; signedHash?: string; intentId?: string } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n\n // Check if dialog already executed the intent (new secure flow)\n if (message.success && payload?.intentId) {\n resolve({\n success: true,\n intentId: payload.intentId,\n } as SigningResult & { signedHash?: string; intentId?: string });\n } else if (message.success && payload?.signature) {\n // Legacy flow - dialog returns signature for SDK to execute\n resolve({\n success: true,\n signature: payload.signature,\n passkey: payload.passkey,\n signedHash: payload.signedHash,\n });\n } else {\n // Failure path: tear the iframe down here. The passkey app\n // sends `PASSKEY_SIGNING_RESULT(false)` then `PASSKEY_CLOSE`\n // back-to-back on cancel, but we've just removed the\n // listener so the follow-up CLOSE would be dropped, leaving\n // the dialog stuck open.\n cleanup();\n resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (\n message?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Cross-frame guard: ignore a stray PASSKEY_CLOSE from a sibling\n // same-origin dialog (e.g. an auth modal tearing down) so it can't\n // forge a rejection of this signing request.\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for a signing result while also handling quote-refresh requests.\n *\n * Quotes from the Rhinestone orchestrator have a short TTL (typically ~60 s).\n * When the user takes too long to review and the quote expires, the dialog\n * sends `PASSKEY_REFRESH_QUOTE`. This method intercepts that message, calls\n * the provided `onRefresh` callback to fetch a new quote, and replies with\n * either `PASSKEY_REFRESH_COMPLETE` (success) or `PASSKEY_REFRESH_ERROR`\n * (failure) — allowing the dialog to stay open and show the updated fees\n * without requiring a full restart.\n *\n * Once the user confirms or rejects, the promise resolves with the signing\n * result exactly as `waitForSigningResponse` would.\n *\n * @param dialog - The `<dialog>` element wrapping the signing iframe.\n * @param iframe - The iframe element; used to post refresh messages back.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @param dialogOrigin - Trusted origin for message validation (passed in to\n * avoid redundant `getDialogOrigin()` calls from the hot path).\n * @param onRefresh - Async callback that fetches a fresh quote and returns the\n * updated intent fields, or `null` if the refresh failed.\n * @returns A `SigningResult` extended with an optional `signedHash`.\n */\n private waitForSigningWithRefresh(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n dialogOrigin: string,\n onRefresh: () => Promise<{\n intentOp: string;\n expiresAt: string;\n challenge: string;\n originMessages?: Array<{ chainId: number; hash: string }>;\n transaction?: unknown;\n digestResult?: unknown;\n /** Fresh prepare->execute binding for the refreshed quote (opaque). */\n binding?: string;\n /** Auth bundle re-bound to the refreshed intentOp — extension grants\n are digest-bound, so the dialog must swap auth with the quote. */\n auth?: SponsorshipTokens;\n } | null>\n ): Promise<SigningResult & { signedHash?: string }> {\n return new Promise((resolve) => {\n const handleMessage = async (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n\n // Handle quote refresh request from dialog\n if (message?.type === \"PASSKEY_REFRESH_QUOTE\") {\n const refreshedData = await onRefresh();\n\n if (refreshedData) {\n // Send refreshed quote data to dialog\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_COMPLETE\",\n ...refreshedData,\n }, dialogOrigin);\n } else {\n // Send error if refresh failed\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh quote\",\n }, dialogOrigin);\n }\n return;\n }\n\n const payload = message?.data as {\n signature?: WebAuthnSignature;\n passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string };\n signedHash?: string;\n intentId?: string;\n } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n\n // Check if dialog already executed the intent (new secure flow)\n if (message.success && payload?.intentId) {\n resolve({\n success: true,\n intentId: payload.intentId,\n } as SigningResult & { signedHash?: string; intentId?: string });\n } else if (message.success && payload?.signature) {\n // Legacy flow - dialog returns signature for SDK to execute\n resolve({\n success: true,\n signature: payload.signature,\n passkey: payload.passkey,\n signedHash: payload.signedHash,\n });\n } else {\n // Failure path: close the iframe. The passkey app sends the\n // follow-up `PASSKEY_CLOSE` after this `RESULT`, but we've just\n // removed the listener so it would be dropped on the floor —\n // tear down here so the user isn't stuck staring at a dialog\n // that's already done.\n cleanup();\n resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (\n message?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Cross-frame guard: ignore a stray PASSKEY_CLOSE from a sibling\n // same-origin dialog so it can't forge a rejection of this signing\n // request mid-refresh.\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Wait for the dialog to be explicitly closed by the user or the iframe.\n *\n * Resolves on either:\n * - `PASSKEY_CLOSE` postMessage from the iframe (user clicked the X button\n * or the dialog programmatically closed itself after showing a result).\n * - The native `<dialog> close` event (escape key or `dialog.close()` call).\n *\n * Calling `cleanup()` before awaiting this is safe — both resolution paths\n * call `cleanup()` internally but it is idempotent. The primary use case is\n * keeping the dialog open while the SDK polls for a transaction hash, then\n * showing the final success/error state before letting the user dismiss.\n *\n * @param dialog - The `<dialog>` element to watch.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n */\n private waitForDialogClose(\n dialog: HTMLDialogElement,\n cleanup: () => void\n ): Promise<void> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n if (event.data?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve();\n }\n };\n\n // Also handle dialog close via escape key or clicking outside\n const handleClose = () => {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n cleanup();\n resolve();\n };\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Hidden blind-signing iframes have no user-visible Done or Close button.\n * Once the SDK has the result it needs, tear them down immediately instead\n * of waiting for an iframe close event that can never be clicked.\n */\n private async waitForDialogCloseUnlessBlind(\n blindSigning: boolean,\n dialog: HTMLDialogElement,\n cleanup: () => void,\n ): Promise<void> {\n if (blindSigning) {\n cleanup();\n return;\n }\n await this.waitForDialogClose(dialog, cleanup);\n }\n\n /**\n * After a prepare error has been surfaced in the dialog, wait for the user\n * to either close the dialog (give up) or click \"Try Again\", which the\n * dialog forwards as `PASSKEY_RETRY_PREPARE`.\n *\n * On `\"closed\"` the dialog has been cleaned up; on `\"retry\"` it stays open\n * (showing its loading skeleton) while the caller re-runs prepare. Without\n * this, \"Try Again\" after a prepare failure was a dead end: the dialog\n * reset its local state but the SDK had already given up, so the quote\n * never arrived and the Sign button stayed disabled forever.\n */\n private waitForPrepareRetryOrClose(\n dialog: HTMLDialogElement,\n cleanup: () => void,\n ): Promise<\"retry\" | \"closed\"> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const stop = () => {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_RETRY_PREPARE\") {\n stop();\n resolve(\"retry\");\n } else if (event.data?.type === \"PASSKEY_CLOSE\") {\n stop();\n cleanup();\n resolve(\"closed\");\n }\n };\n\n // Also handle dialog close via escape key or clicking outside\n const handleClose = () => {\n stop();\n cleanup();\n resolve(\"closed\");\n };\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Inject a `<link rel=\"preconnect\">` tag for the given URL's origin.\n *\n * Browsers use preconnect hints to resolve DNS, perform the TCP handshake,\n * and negotiate TLS before a resource is actually requested, reducing\n * time-to-first-byte when the dialog iframe loads. The tag is deduplicated —\n * if one already exists for the same origin it will not be added again.\n *\n * Only called in browser environments (guarded by `typeof document` in the\n * constructor). Invalid URLs are silently ignored.\n *\n * @param url - Any URL whose origin should be preconnected to.\n */\n private injectPreconnect(url: string): void {\n try {\n const origin = new URL(url).origin;\n if (document.querySelector(`link[rel=\"preconnect\"][href=\"${origin}\"]`)) return;\n const link = document.createElement(\"link\");\n link.rel = \"preconnect\";\n link.href = origin;\n link.crossOrigin = \"anonymous\";\n document.head.appendChild(link);\n } catch {\n // Invalid URL, skip\n }\n }\n\n /**\n * Warm the dialog ahead of the first user interaction.\n *\n * `preconnect` (run in the constructor) only warms DNS/TLS. This goes\n * further: it loads the dialog into a hidden, off-screen iframe so the\n * browser downloads and parses the dialog HTML + JS bundle and the font, and\n * keeps the cross-origin connection alive. When the user later opens a real\n * auth/sign dialog, the fresh iframe serves those bytes from cache over the\n * warm connection and paints far sooner — so the SDK preload overlay is shown\n * only briefly (or imperceptibly) instead of covering a full cold load.\n *\n * It loads a dedicated `/dialog/warm` route, NOT a real flow route. That\n * matters for two reasons:\n * - **No side effects.** The real `/dialog/auth` route runs the signup\n * flow on mount (identity probe → `POST /api/auth/register?step=start`),\n * which writes an `AuthChallenge` row and counts against the register\n * rate limiter. Warming must never create backend auth state for a user\n * who hasn't acted, so the warm route renders nothing and runs no flow.\n * - **No message cross-talk.** The warm route posts no `PASSKEY_READY` /\n * `PASSKEY_RENDERED`, so a slow warm can never satisfy a visible modal's\n * readiness listener and drive it to `PASSKEY_INIT` at the wrong moment.\n * The warm route still pulls the shared Next.js framework + main + dialog\n * layout chunks (the bulk of every flow's bundle), so the real open is fast.\n *\n * Best called on a *likely-intent* signal — `pointerenter`/`focus` of your\n * \"Sign in\" / \"Pay\" button — rather than on page load, so visitors who never\n * authenticate don't pay for a cross-origin iframe. Pass `prewarm: true` in\n * the client config to have the SDK schedule this once on an idle callback.\n *\n * Idempotent: repeated calls return the same in-flight/settled promise.\n * Resolves `true` once the hidden iframe's document has loaded, `false` on\n * timeout or failure. Never throws and never blocks a real dialog open — a\n * failed prewarm just means the next open does a normal (cold) load.\n *\n * @returns Whether the dialog became warm.\n */\n async prewarm(): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n // Idempotent: a second call (e.g. hover after an idle-scheduled warm)\n // rides the first one's load instead of opening another iframe.\n if (this.prewarmState) return this.prewarmState.ready;\n\n // Dedicated warm route — silent and side-effect-free (see method doc). No\n // theme/flow params needed: it renders nothing, and query strings don't\n // affect caching of the hashed JS chunks the real open reuses.\n const warmUrl = `${this.getDialogUrl()}/dialog/warm`;\n\n // A bare hidden iframe — deliberately NOT the full createModalDialog\n // chrome (no <dialog>, overlay, Escape handler or showModal). We only need\n // the browser to fetch + run the bundle; none of the modal lifecycle\n // applies to a frame the user never sees.\n const iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\"aria-hidden\", \"true\");\n iframe.setAttribute(\"tabindex\", \"-1\");\n iframe.title = \"1auth dialog prewarm\";\n // Off-screen + inert so it can never intercept clicks or take focus, while\n // still being \"rendered\" (display:none would let some browsers defer the\n // load we are trying to trigger).\n iframe.style.cssText =\n \"position:fixed;left:-9999px;top:0;width:1px;height:1px;opacity:0;border:0;pointer-events:none;\";\n\n // Resolve on the iframe `load` event rather than a postMessage. The warm\n // route is intentionally message-silent, and `load` fires for cross-origin\n // frames too (we never touch contentDocument), so it is the right\n // signal — and one a stray frame's messages can never spoof.\n const ready = new Promise<boolean>((resolve) => {\n let settled = false;\n const finish = (value: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(value);\n };\n iframe.onload = () => finish(true);\n iframe.onerror = () => finish(false);\n // Failsafe so the promise always settles even if `load` is missed.\n const timer = setTimeout(() => finish(false), 10000);\n });\n iframe.src = warmUrl;\n document.body.appendChild(iframe);\n\n this.prewarmState = { iframe, ready };\n return ready;\n }\n\n /**\n * Tear down the hidden prewarm iframe created by {@link prewarm}.\n *\n * The HTTP cache that prewarm populated survives teardown, so a subsequent\n * open is still bundle-warm; this only releases the parked frame (and its\n * keep-alive connection). Call it when auth is no longer likely on the\n * current view. Safe to call when nothing is warmed.\n */\n destroyPrewarm(): void {\n const state = this.prewarmState;\n if (!state) return;\n this.prewarmState = null;\n state.iframe.remove();\n }\n\n /**\n * Wait for the dialog iframe to signal ready, but defer sending `PASSKEY_INIT`\n * until the caller decides the time is right.\n *\n * This is the deferred variant of `waitForDialogReady`, used by flows that run\n * the dialog and a background API call in parallel (the \"two-phase\" approach).\n * Rather than blocking until both the iframe is ready AND the API call is done,\n * this method resolves as soon as `PASSKEY_READY` arrives and returns a\n * `sendInit` callback. The caller invokes `sendInit` once prepare data is\n * available, which may happen before or after the iframe is ready.\n *\n * Timeout: if the iframe never signals ready within 10 seconds (e.g. network\n * error, origin mismatch), resolves with `{ ready: false }` and calls cleanup.\n *\n * @param dialog - The `<dialog>` element wrapping the iframe.\n * @param iframe - The iframe element that will receive `PASSKEY_INIT`.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @returns `{ ready: true, sendInit }` when the iframe is ready, or\n * `{ ready: false }` if the dialog was closed or timed out first.\n */\n private waitForDialogReadyDeferred(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n options: { blindSigning?: boolean; reveal?: () => void } = {},\n ): Promise<\n | { ready: true; blindSigning: boolean; sendInit: (initMessage: Record<string, unknown>) => void }\n | { ready: false }\n > {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let settled = false;\n\n const teardown = () => {\n if (settled) return;\n settled = true;\n clearTimeout(readyTimeout);\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n const blindSigning = options.blindSigning === true;\n teardown();\n resolve({\n ready: true,\n blindSigning,\n sendInit: (initMessage: Record<string, unknown>) => {\n if (blindSigning) iframe.focus({ preventScroll: true });\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initMessage, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n },\n });\n } else if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Match by source, not just origin: the auth dialog (authWithModal)\n // emits a stray PASSKEY_CLOSE from the SAME origin as it tears down.\n // Without the source check, that close resolves the sign dialog's\n // ready-promise as { ready: false } → dialogClosedBeforeReadyPromise\n // → a spurious USER_CANCELLED (\"closed before it became ready\").\n // Identical guard to the earlyDialogClosePromise fix.\n teardown();\n cleanup();\n resolve({ ready: false });\n }\n };\n\n const handleClose = () => {\n teardown();\n resolve({ ready: false });\n };\n\n const readyTimeout = setTimeout(() => {\n teardown();\n cleanup();\n resolve({ ready: false });\n }, 10000);\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Call the passkey service to obtain a Rhinestone orchestrator quote for an\n * intent (a single target-chain transaction or swap).\n *\n * The service contacts the Rhinestone orchestrator, which returns a signed\n * `intentOp` structure containing the quote, fees, and a WebAuthn challenge\n * the user must sign to authorize execution.\n *\n * The `X-Origin-Tier` response header is forwarded to the dialog so it can\n * display tier-specific UI (e.g. \"Free\" vs \"Premium\" badge).\n *\n * Side effect: if the server returns \"User not found\", the cached user entry\n * is removed from `localStorage` to force re-authentication.\n *\n * @param requestBody - Serialized intent options (bigint amounts converted to\n * strings before this call).\n * @returns On success: `{ success: true, data: PrepareIntentResponse, tier }`.\n * On failure: `{ success: false, error: { code, message, details? } }`.\n */\n private async prepareIntent(\n requestBody: Record<string, unknown>,\n telemetry?: TelemetryOperation,\n ): Promise<\n | { success: true; data: PrepareIntentResponse; tier: string | null }\n | { success: false; error: { code: string; message: string; details?: unknown } }\n > {\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error || \"Failed to prepare intent\";\n\n if (errorMessage.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n }\n\n return {\n success: false,\n error: {\n code: errorMessage.includes(\"User not found\") ? \"USER_NOT_FOUND\" : \"PREPARE_FAILED\",\n message: errorMessage,\n details: errorData.details ?? errorData.candidateErrors ?? errorData,\n },\n };\n }\n\n const tier = response.headers.get(\"X-Origin-Tier\");\n return { success: true, data: await response.json(), tier };\n } catch (error) {\n return {\n success: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network error\",\n },\n };\n }\n }\n\n /**\n * Call the passkey service to obtain orchestrator quotes for all intents in a\n * batch, returning a single shared WebAuthn challenge.\n *\n * The service prepares each intent independently and assembles a merkle tree\n * whose root becomes the challenge. Signing that root once authorizes every\n * intent in the batch. Partially-failed batches are supported: the response\n * includes both `intents` (succeeded) and `failedIntents` (per-intent errors),\n * so the dialog can still show the successful subset for signing.\n *\n * Side effect: same \"User not found\" localStorage cleanup as `prepareIntent`.\n *\n * @param requestBody - Serialized batch options (bigint amounts converted to\n * strings before this call).\n * @returns On success: `{ success: true, data: PrepareBatchIntentResponse, tier }`.\n * On failure: `{ success: false, error, failedIntents? }`.\n */\n private async prepareBatchIntent(\n requestBody: Record<string, unknown>,\n telemetry?: TelemetryOperation,\n ): Promise<\n | { success: true; data: PrepareBatchIntentResponse; tier: string | null }\n | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> }\n > {\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error || \"Failed to prepare batch intent\";\n\n if (errorMessage.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n }\n\n return {\n success: false,\n error: errorMessage,\n failedIntents: errorData.failedIntents,\n };\n }\n\n const tier = response.headers.get(\"X-Origin-Tier\");\n return { success: true, data: await response.json(), tier };\n } catch {\n return { success: false, error: \"Network error\" };\n }\n }\n\n /**\n * Forward a prepare-phase error to the dialog iframe so it can display a\n * human-readable failure message instead of hanging on the loading state.\n *\n * The dialog listens for `PASSKEY_PREPARE_ERROR` and transitions to an error\n * view. The user can then dismiss the dialog, at which point\n * `waitForDialogClose` resolves and the SDK returns the error to the caller.\n *\n * @param iframe - The iframe element to post the error to.\n * @param error - Human-readable error message from the prepare response.\n */\n private sendPrepareError(iframe: HTMLIFrameElement, error: string): void {\n const dialogOrigin = this.getDialogOrigin();\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_PREPARE_ERROR\", error },\n dialogOrigin,\n );\n }\n\n /**\n * Poll for intent status\n *\n * Use this to check on the status of a submitted intent\n * that hasn't completed yet.\n */\n async getIntentStatus(intentId: string): Promise<SendIntentResult> {\n const telemetry = this.createTelemetryOperation(\"status\");\n this.emitTelemetry(\"intent.status.started\", telemetry, {\n outcome: \"started\",\n attributes: { directStatusCheck: true },\n });\n try {\n const response = await fetch(\n `${this.config.providerUrl}/api/intent/status/${intentId}`,\n {\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n this.emitTelemetry(\"status.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"STATUS_FAILED\",\n errorMessage: errorData.error || \"Failed to get intent status\",\n });\n return {\n success: false,\n intentId,\n status: \"failed\",\n error: {\n code: \"STATUS_FAILED\",\n message: errorData.error || \"Failed to get intent status\",\n },\n };\n }\n\n const data = await response.json();\n this.emitTelemetry(\"status.succeeded\", telemetry, {\n outcome: data.status === \"completed\" ? \"success\" : \"started\",\n status: data.status,\n });\n return {\n success: data.status === \"completed\",\n intentId,\n status: data.status,\n transactionHash: data.transactionHash,\n operationId: data.operationId,\n };\n } catch (error) {\n this.emitTelemetry(\"status.failed\", telemetry, {\n outcome: \"failure\",\n ...describeTelemetryError(error),\n });\n return {\n success: false,\n intentId,\n status: \"failed\",\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network error\",\n },\n };\n }\n }\n\n /**\n * Get the history of intents for the authenticated user.\n *\n * Requires an active session (user must be logged in).\n *\n * @example\n * ```typescript\n * // Get recent intents\n * const history = await client.getIntentHistory({ limit: 10 });\n *\n * // Filter by status\n * const pending = await client.getIntentHistory({ status: 'pending' });\n *\n * // Filter by date range\n * const lastWeek = await client.getIntentHistory({\n * from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),\n * });\n * ```\n */\n async getIntentHistory(\n options?: IntentHistoryOptions\n ): Promise<IntentHistoryResult> {\n const telemetry = this.createTelemetryOperation(\"history\", {\n hasStatusFilter: !!options?.status,\n });\n const queryParams = new URLSearchParams();\n if (options?.limit) queryParams.set(\"limit\", String(options.limit));\n if (options?.offset) queryParams.set(\"offset\", String(options.offset));\n if (options?.status) queryParams.set(\"status\", options.status);\n if (options?.from) queryParams.set(\"from\", options.from);\n if (options?.to) queryParams.set(\"to\", options.to);\n\n const url = `${this.config.providerUrl}/api/intent/history${\n queryParams.toString() ? `?${queryParams}` : \"\"\n }`;\n\n const response = await fetch(url, {\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n this.emitTelemetry(\"history.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"HISTORY_FAILED\",\n errorMessage: errorData.error || \"Failed to get intent history\",\n });\n throw new Error(errorData.error || \"Failed to get intent history\");\n }\n\n const result = await response.json();\n this.emitTelemetry(\"history.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n total: result.total,\n returned: result.intents?.length ?? 0,\n },\n });\n return result;\n }\n\n /**\n * Forward a raw EIP-1193 request to the iframe so the active EOA connector\n * can handle it (wallet-connect session or injected wallet). Opens\n * `/dialog/sign-eoa`, which looks up the wagmi connector and delegates to\n * `connector.getProvider().request({ method, params })`. The wallet's own\n * UI is the review screen; the dialog just transports the request.\n */\n async requestWithWallet(options: {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n expectedAddress?: `0x${string}`;\n theme?: ThemeConfig;\n }): Promise<\n | { success: true; result: unknown }\n | { success: false; error: { code: string; message: string } }\n > {\n // Serialise concurrent calls: the EOA iframe is a single shared resource\n // and the iframe's view + classifyInit state assume one in-flight\n // request at a time.\n const job = this.eoaSerialQueue.then(\n () => this.doRequestWithWallet(options),\n () => this.doRequestWithWallet(options),\n );\n this.eoaSerialQueue = job.then(\n () => undefined,\n () => undefined,\n );\n return job;\n }\n\n private async doRequestWithWallet(options: {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n expectedAddress?: `0x${string}`;\n theme?: ThemeConfig;\n }): Promise<\n | { success: true; result: unknown }\n | { success: false; error: { code: string; message: string } }\n > {\n const dialogOrigin = this.getDialogOrigin();\n const ensureResult = await this.ensureEoaDialog(options?.theme);\n if (!ensureResult.ok) {\n return {\n success: false,\n error: { code: \"USER_REJECTED\", message: \"User closed the dialog\" },\n };\n }\n const { dialog, iframe } = ensureResult;\n\n // requestId binds the SDK call to its dialog instance. Required for\n // every subsequent message: the dialog echoes it on PASSKEY_EOA_RESULT\n // and PASSKEY_EOA_CLOSE so stale messages from a previous flow cannot\n // cross-resolve this promise.\n const requestId =\n typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n const hideDialog = () => {\n if (dialog.open) dialog.close();\n };\n\n // Install the result listener BEFORE PASSKEY_INIT is sent. Fast methods\n // like wallet_getCallsStatus can resolve in the same task as the init\n // and emit PASSKEY_EOA_RESULT before a listener attached afterward\n // would see it.\n const responsePromise = this.waitForEoaResponse(\n iframe,\n hideDialog,\n requestId,\n dialogOrigin,\n );\n\n const initPayload = {\n mode: \"iframe\",\n method: options.method,\n params: options.params,\n expectedAddress: options.expectedAddress,\n requestId,\n };\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n dialogOrigin,\n );\n\n // The iframe may re-emit PASSKEY_READY if its React tree remounts\n // (HMR, Suspense). Re-send PASSKEY_INIT so it picks the current\n // request up — keyed on the same requestId, which the iframe dedupes.\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n const result = await responsePromise;\n window.removeEventListener(\"message\", handleReReady);\n hideDialog();\n return result;\n }\n\n /**\n * Lazily create the persistent `/dialog/sign-eoa` iframe and reveal it.\n * Subsequent calls just re-open the existing `<dialog>` so the iframe's\n * in-page state (notably the WalletConnect SignClient) is preserved\n * between transactions.\n */\n private async ensureEoaDialog(theme: ThemeConfig | undefined): Promise<\n | { ok: true; dialog: HTMLDialogElement; iframe: HTMLIFrameElement }\n | { ok: false }\n > {\n if (this.eoaDialogState) {\n const { dialog, iframe } = this.eoaDialogState;\n if (!dialog.open) {\n // dialog.showModal() throws if already open — guarded above.\n dialog.showModal();\n }\n return { ok: true, dialog, iframe };\n }\n\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n // Keep the persistent EOA iframe on the same parent-origin hint path as\n // the other dialog routes; the passkey app still authenticates the caller\n // from browser-provided referrer/event.origin before trusting it.\n appendParentOriginParam(params);\n const themeParams = this.getThemeParams(theme);\n if (themeParams) {\n new URLSearchParams(themeParams).forEach((value, key) => {\n params.set(key, value);\n });\n }\n const signingUrl = `${dialogUrl}/dialog/sign-eoa?${params.toString()}`;\n\n const { dialog, iframe, destroy } = this.createModalDialog(signingUrl, {\n persistent: true,\n });\n\n const ready = await this.waitForEoaIframeReady(iframe);\n if (!ready) {\n // Iframe never came up — fully tear down and surface as a rejection.\n // Next call will retry from scratch.\n destroy();\n return { ok: false };\n }\n\n this.eoaDialogState = { dialog, iframe };\n return { ok: true, dialog, iframe };\n }\n\n private waitForEoaIframeReady(iframe: HTMLIFrameElement): Promise<boolean> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const cleanup = () => {\n if (timeoutId !== null) clearTimeout(timeoutId);\n window.removeEventListener(\"message\", handler);\n };\n const handler = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n cleanup();\n resolve(true);\n }\n };\n window.addEventListener(\"message\", handler);\n timeoutId = setTimeout(() => {\n cleanup();\n resolve(false);\n }, 10000);\n });\n }\n\n private waitForEoaResponse(\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n requestId: string,\n dialogOrigin: string,\n ): Promise<\n | { success: true; result: unknown }\n | { success: false; error: { code: string; message: string } }\n > {\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n // Three trust checks before reading any payload:\n // 1. event.origin pinned to the dialog origin\n // 2. event.source pinned to this iframe's contentWindow (rejects\n // messages from sibling frames or popups that grabbed a window\n // reference)\n // 3. requestId echoed by the dialog matches ours (rejects stale\n // messages from a prior remount or a concurrent dialog)\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n const message = event.data;\n if (\n message?.type === \"PASSKEY_EOA_RESULT\" ||\n message?.type === \"PASSKEY_EOA_CLOSE\"\n ) {\n if (message.requestId !== requestId) return;\n } else {\n return;\n }\n window.removeEventListener(\"message\", handleMessage);\n if (message.type === \"PASSKEY_EOA_CLOSE\") {\n cleanup();\n resolve({\n success: false,\n error: { code: \"USER_REJECTED\", message: \"User closed the dialog\" },\n });\n return;\n }\n if (message.success) {\n resolve({ success: true, result: message.data?.result });\n } else {\n resolve({\n success: false,\n error: message.error || {\n code: \"EOA_REQUEST_FAILED\",\n message: \"Wallet request failed\",\n },\n });\n }\n };\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Sign an arbitrary message with the user's passkey\n *\n * This is for off-chain message signing (e.g., authentication challenges,\n * terms acceptance, login signatures), NOT for transaction signing.\n * The message is displayed to the user and signed with their passkey.\n *\n * @example\n * ```typescript\n * // Sign a login challenge\n * const result = await client.signMessage({\n * username: 'alice',\n * message: `Sign in to MyApp\\nTimestamp: ${Date.now()}\\nNonce: ${crypto.randomUUID()}`,\n * description: 'Verify your identity to continue',\n * });\n *\n * if (result.success) {\n * // Send signature to your backend for verification\n * await fetch('/api/verify', {\n * method: 'POST',\n * body: JSON.stringify({\n * signature: result.signature,\n * message: result.signedMessage,\n * }),\n * });\n * }\n * ```\n */\n async signMessage(options: SignMessageOptions): Promise<SignMessageResult> {\n const telemetry = this.createTelemetryOperation(\"sign\", {\n signingMode: \"message\",\n hasAccountAddress: !!options.accountAddress,\n });\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n if (!dialogResult.ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_REJECTED\",\n errorMessage: \"User closed the dialog before signing\",\n });\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n\n const initPayload = {\n mode: \"iframe\",\n message: options.message,\n challenge: options.challenge || options.message,\n username: options.username,\n accountAddress: options.accountAddress,\n description: options.description,\n metadata: options.metadata,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(initPayload);\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n // Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n // so the sign page recovers its state.\n const dialogOrigin = this.getDialogOrigin();\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);\n\n window.removeEventListener(\"message\", handleReReady);\n cleanup();\n\n if (signingResult.success) {\n this.emitTelemetry(\"sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { signingMode: \"message\" },\n });\n return {\n success: true,\n signature: signingResult.signature,\n signedMessage: options.message,\n signedHash: signingResult.signedHash as `0x${string}` | undefined,\n passkey: signingResult.passkey,\n };\n }\n\n this.emitTelemetry(\n signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n telemetry,\n {\n outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingResult.error),\n attributes: { signingMode: \"message\" },\n },\n );\n return {\n success: false,\n error: signingResult.error,\n };\n }\n\n /**\n * Sign EIP-712 typed data with the user's passkey\n *\n * This method allows signing structured data following the EIP-712 standard.\n * The typed data is displayed to the user in a human-readable format before signing.\n *\n * @example\n * ```typescript\n * // Sign an ERC-2612 Permit\n * const result = await client.signTypedData({\n * username: 'alice',\n * domain: {\n * name: 'Dai Stablecoin',\n * version: '1',\n * chainId: 1,\n * verifyingContract: '0x6B175474E89094C44Da98b954EecdeCB5BE3830F',\n * },\n * types: {\n * Permit: [\n * { name: 'owner', type: 'address' },\n * { name: 'spender', type: 'address' },\n * { name: 'value', type: 'uint256' },\n * { name: 'nonce', type: 'uint256' },\n * { name: 'deadline', type: 'uint256' },\n * ],\n * },\n * primaryType: 'Permit',\n * message: {\n * owner: '0xabc...',\n * spender: '0xdef...',\n * value: 1000000000000000000n,\n * nonce: 0n,\n * deadline: 1735689600n,\n * },\n * });\n *\n * if (result.success) {\n * console.log('Signed hash:', result.signedHash);\n * }\n * ```\n */\n async signTypedData(options: SignTypedDataOptions): Promise<SignTypedDataResult> {\n const telemetry = this.createTelemetryOperation(\"sign\", {\n signingMode: \"typedData\",\n primaryType: options.primaryType,\n hasAccountAddress: !!options.accountAddress,\n });\n // Compute the EIP-712 hash using viem\n // Use unknown cast to work around viem's strict template literal type requirements\n const signedHash = hashTypedData({\n domain: options.domain,\n types: options.types,\n primaryType: options.primaryType,\n message: options.message,\n } as unknown as TypedDataDefinition);\n\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n if (!dialogResult.ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_REJECTED\",\n errorMessage: \"User closed the dialog before signing\",\n });\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n\n const initPayload = {\n mode: \"iframe\",\n signingMode: \"typedData\",\n typedData: {\n domain: options.domain,\n types: options.types,\n primaryType: options.primaryType,\n message: options.message,\n },\n challenge: signedHash,\n username: options.username,\n accountAddress: options.accountAddress,\n description: options.description,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(initPayload);\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n // Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n // so the sign page recovers its state.\n const dialogOrigin = this.getDialogOrigin();\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);\n\n window.removeEventListener(\"message\", handleReReady);\n cleanup();\n\n if (signingResult.success) {\n this.emitTelemetry(\"sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { signingMode: \"typedData\", primaryType: options.primaryType },\n });\n return {\n success: true,\n signature: signingResult.signature,\n signedHash,\n passkey: signingResult.passkey,\n };\n }\n\n this.emitTelemetry(\n signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n telemetry,\n {\n outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingResult.error),\n attributes: { signingMode: \"typedData\", primaryType: options.primaryType },\n },\n );\n return {\n success: false,\n error: signingResult.error,\n };\n }\n\n async signWithPopup(options: SigningRequestOptions): Promise<SigningResult> {\n const request = await this.createSigningRequest(options, \"popup\");\n\n // Use dialogUrl to construct the signing URL (override server's URL)\n const dialogUrl = this.getDialogUrl();\n const signingUrl = `${dialogUrl}/dialog/sign/${request.requestId}?mode=popup`;\n\n const popup = this.openPopup(signingUrl);\n if (!popup) {\n return {\n success: false,\n error: {\n code: \"POPUP_BLOCKED\",\n message:\n \"Popup was blocked by the browser. Please allow popups for this site.\",\n },\n };\n }\n\n return this.waitForPopupResponse(request.requestId, popup);\n }\n\n async signWithRedirect(\n options: SigningRequestOptions,\n redirectUrl?: string\n ): Promise<void> {\n const finalRedirectUrl = redirectUrl || this.config.redirectUrl;\n if (!finalRedirectUrl) {\n throw new Error(\n \"redirectUrl is required for redirect flow. Pass it to signWithRedirect() or set it in the constructor.\"\n );\n }\n\n const request = await this.createSigningRequest(\n options,\n \"redirect\",\n finalRedirectUrl\n );\n\n // Use dialogUrl to construct the signing URL (override server's URL)\n const dialogUrl = this.getDialogUrl();\n const signingUrl = `${dialogUrl}/dialog/sign/${request.requestId}?mode=redirect&redirectUrl=${encodeURIComponent(finalRedirectUrl)}`;\n\n window.location.href = signingUrl;\n }\n\n async signWithEmbed(\n options: SigningRequestOptions,\n embedOptions: EmbedOptions\n ): Promise<SigningResult> {\n const request = await this.createSigningRequest(options, \"embed\");\n\n const iframe = this.createEmbed(request.requestId, embedOptions);\n\n return this.waitForEmbedResponse(request.requestId, iframe, embedOptions);\n }\n\n /**\n * Create and append a signing iframe to a caller-supplied container element.\n *\n * Used by the `signWithEmbed` flow where the integrator wants the signing UI\n * to appear inline on their page rather than in a modal overlay. The iframe\n * loads a pre-created signing request URL and fires `options.onReady` once\n * the page has loaded.\n *\n * @param requestId - The signing request ID; used to construct the iframe src\n * and give it a stable DOM id for later removal via `removeEmbed`.\n * @param options - Embed configuration including the container element,\n * optional dimensions, and lifecycle callbacks.\n * @returns The created `<iframe>` element (already appended to the container).\n */\n private createEmbed(\n requestId: string,\n options: EmbedOptions\n ): HTMLIFrameElement {\n const dialogUrl = this.getDialogUrl();\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${dialogUrl}/dialog/sign/${requestId}?mode=iframe`;\n iframe.style.width = options.width || DEFAULT_EMBED_WIDTH;\n iframe.style.height = options.height || DEFAULT_EMBED_HEIGHT;\n iframe.style.border = \"none\";\n iframe.style.borderRadius = \"12px\";\n iframe.style.boxShadow = \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\";\n iframe.id = `passkey-embed-${requestId}`;\n iframe.allow = \"publickey-credentials-get *; publickey-credentials-create *; identity-credentials-get\";\n\n iframe.onload = () => {\n options.onReady?.();\n };\n\n options.container.appendChild(iframe);\n\n // Tell the dialog about the parent's viewport so DialogCard can\n // cap itself at 75% of the user's screen instead of auto-growing\n // for long sign flows (e.g. a 20-action transaction). Without\n // this, the dialog falls back to its old infinite-growth\n // behaviour and the scroll-gated Sign button never fires.\n this.wireViewportInfo(iframe);\n\n // Auto-resize the iframe to the dialog's natural content height.\n // Without this, taller screens (e.g. signup with the email field\n // ~552px) get clipped against the fixed `DEFAULT_EMBED_HEIGHT`, and\n // shorter screens leave dead space below. The dialog measures its\n // card via ResizeObserver and posts `PASSKEY_RESIZE` on every change.\n const host = new URL(dialogUrl);\n const onResize = (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n if (event.origin !== host.origin) return;\n if (event.data?.type !== \"PASSKEY_RESIZE\") return;\n const h = Number(event.data.height);\n if (Number.isFinite(h) && h > 0) {\n iframe.style.height = `${h}px`;\n }\n };\n window.addEventListener(\"message\", onResize);\n // ResizeObserver in the iframe keeps firing for the dialog's\n // lifetime; we leave the listener attached until the iframe is\n // removed via `removeEmbed`. No cleanup hook is exposed by\n // `createEmbed`; document a follow-up here if leak becomes an issue.\n\n return iframe;\n }\n\n /**\n * Post `PASSKEY_VIEWPORT_INFO` with the parent's\n * `window.innerHeight` to the iframe whenever it signals\n * `PASSKEY_READY`, and re-post on `window.resize` (rAF-debounced)\n * so the dialog's internal max-height cap follows the user's\n * actual screen.\n *\n * Inside the iframe, `vh`/`dvh` units refer to the iframe's own\n * height (recursive when the iframe auto-sizes), so the parent is\n * the only reliable source of \"what 75% of the user's screen is\".\n * The dialog stores the value in `dialog-context` and falls back\n * to auto-grow when the value is absent — so it's safe to call\n * this even for embedders that don't actually cap (modal mode\n * uses `fullViewport` which has its own outer cap).\n */\n private wireViewportInfo(iframe: HTMLIFrameElement): () => void {\n const dialogOrigin = this.getDialogOrigin();\n\n const post = () => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_VIEWPORT_INFO\", height: window.innerHeight },\n dialogOrigin,\n );\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n post();\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // rAF-debounced resize. Coalesces drag-resize bursts to one post\n // per animation frame so we don't spam the iframe with messages.\n let raf: number | null = null;\n const onResize = () => {\n if (raf !== null) return;\n raf = requestAnimationFrame(() => {\n raf = null;\n post();\n });\n };\n window.addEventListener(\"resize\", onResize);\n\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"resize\", onResize);\n if (raf !== null) cancelAnimationFrame(raf);\n };\n }\n\n /**\n * Listen for a signing result from an embedded (inline) signing iframe.\n *\n * Matches incoming `PASSKEY_SIGNING_RESULT` messages against `requestId`\n * to avoid reacting to messages from other iframes on the page. On resolution\n * (success or failure), the iframe is removed from the DOM and\n * `embedOptions.onClose` is invoked.\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param iframe - The embedded signing iframe.\n * @param embedOptions - Embed configuration; `onClose` is called after cleanup.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForEmbedResponse(\n requestId: string,\n iframe: HTMLIFrameElement,\n embedOptions: EmbedOptions\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const cleanup = () => {\n window.removeEventListener(\"message\", handleMessage);\n iframe.remove();\n embedOptions.onClose?.();\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) {\n return;\n }\n\n const message = event.data;\n // The Messenger sends: { type, success, data: { requestId, signature }, error }\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n if (\n message?.type === \"PASSKEY_SIGNING_RESULT\" &&\n payload?.requestId === requestId\n ) {\n cleanup();\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n });\n } else {\n resolve({\n success: false,\n requestId,\n error: message.error,\n });\n }\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n removeEmbed(requestId: string): void {\n const iframe = document.getElementById(`passkey-embed-${requestId}`);\n if (iframe) {\n iframe.remove();\n }\n }\n\n async handleRedirectCallback(): Promise<SigningResult> {\n const params = new URLSearchParams(window.location.search);\n const requestId = params.get(\"request_id\");\n const status = params.get(\"status\");\n const error = params.get(\"error\");\n const errorMessage = params.get(\"error_message\");\n\n if (error) {\n return {\n success: false,\n requestId: requestId || undefined,\n error: {\n code: error as SigningResult extends { success: false }\n ? SigningResult[\"error\"][\"code\"]\n : never,\n message: errorMessage || \"Unknown error\",\n },\n };\n }\n\n if (!requestId) {\n return {\n success: false,\n error: {\n code: \"INVALID_REQUEST\",\n message: \"No request_id found in callback URL\",\n },\n };\n }\n\n if (status !== \"completed\") {\n return {\n success: false,\n requestId,\n error: {\n code: \"UNKNOWN\",\n message: `Unexpected status: ${status}`,\n },\n };\n }\n\n return this.fetchSigningResult(requestId);\n }\n\n /**\n * Fetch passkeys for a user from the auth provider\n */\n async getPasskeys(username: string): Promise<PasskeyCredential[]> {\n const response = await fetch(\n `${this.config.providerUrl}/api/users/${encodeURIComponent(username)}/passkeys`,\n {\n headers: this.config.clientId\n ? { \"x-client-id\": this.config.clientId }\n : {},\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || errorData.message || \"Failed to fetch passkeys\");\n }\n\n const data: UserPasskeysResponse = await response.json();\n return data.passkeys;\n }\n\n /**\n * Register a signing request with the passkey service and receive a\n * short-lived `requestId`.\n *\n * Used by the legacy popup, redirect, and embed flows. The passkey service\n * stores the challenge and metadata server-side so the dialog page can fetch\n * them by `requestId` without relying on URL parameters alone. This avoids\n * exposing potentially large challenge payloads in query strings.\n *\n * @param options - The signing options (challenge, username, description, etc.).\n * @param mode - How the dialog will be opened (`\"popup\"`, `\"redirect\"`, or `\"embed\"`).\n * @param redirectUrl - Only required for `\"redirect\"` mode; the URL the dialog\n * will navigate back to after signing.\n * @returns The created signing request with its unique `requestId`.\n * @throws If the API call fails.\n */\n private async createSigningRequest(\n options: SigningRequestOptions,\n mode: \"popup\" | \"redirect\" | \"embed\",\n redirectUrl?: string\n ): Promise<CreateSigningRequestResponse> {\n const response = await fetch(\n `${this.config.providerUrl}/api/sign/request`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n ...(this.config.clientId && { clientId: this.config.clientId }),\n username: options.username,\n accountAddress: options.accountAddress,\n challenge: options.challenge,\n description: options.description,\n metadata: options.metadata,\n transaction: options.transaction,\n mode,\n redirectUrl,\n }),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || errorData.message || \"Failed to create signing request\");\n }\n\n return response.json();\n }\n\n /**\n * Open a centered popup window for the signing or auth dialog.\n *\n * Positions the popup near the top of the current window (50px from the top)\n * and horizontally centered relative to the browser window. Uses `popup=true`\n * to request a minimal chrome popup (no address bar) on browsers that support\n * the Window Management API.\n *\n * @param url - The full URL to open in the popup.\n * @returns The popup `Window` reference, or `null` if the browser blocked it.\n */\n private openPopup(url: string): Window | null {\n const left = window.screenX + (window.outerWidth - POPUP_WIDTH) / 2;\n const top = window.screenY + 50; // Near top of window\n\n return window.open(\n url,\n \"passkey-signing\",\n `width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top},popup=true`\n );\n }\n\n /**\n * Wait for the dialog iframe to signal ready, then immediately send init data.\n *\n * This is the synchronous-init variant: `initMessage` is available at call\n * time, so it can be posted as soon as `PASSKEY_READY` arrives. Use\n * `waitForDialogReadyDeferred` when init data depends on an in-flight API call.\n *\n * Also handles early close (X button, escape key, backdrop click) during the\n * ready phase so those paths resolve cleanly without leaking event listeners.\n *\n * Timeout: resolves `false` after 10 seconds if the iframe never signals ready\n * (e.g. origin mismatch or network error loading the dialog app).\n *\n * @param dialog - The `<dialog>` element wrapping the iframe.\n * @param iframe - The iframe element that will receive `PASSKEY_INIT`.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @param initMessage - The `PASSKEY_INIT` payload to send when ready.\n * @returns `true` if the dialog is ready and init was sent; `false` if the\n * dialog was closed or timed out before becoming ready.\n */\n private waitForDialogReady(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n initMessage: Record<string, unknown>,\n options: { blindSigning?: boolean; reveal?: () => void } = {},\n ): Promise<boolean> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let settled = false;\n\n const teardown = () => {\n if (settled) return;\n settled = true;\n clearTimeout(readyTimeout);\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n const blindSigning = options.blindSigning === true;\n teardown();\n if (blindSigning) iframe.focus({ preventScroll: true });\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n ...initMessage,\n fullViewport: true,\n blindSigning,\n }, dialogOrigin);\n resolve(true);\n } else if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Cross-frame guard (same as waitForDialogReadyDeferred): a stray\n // PASSKEY_CLOSE from a sibling same-origin dialog must not resolve\n // this dialog's ready phase as closed-before-ready.\n teardown();\n cleanup();\n resolve(false);\n }\n };\n\n // Handle escape key / backdrop click which call cleanup() -> dialog.close()\n const handleClose = () => {\n teardown();\n resolve(false);\n };\n\n // Timeout: if dialog never signals ready (e.g. origin mismatch), clean up\n const readyTimeout = setTimeout(() => {\n teardown();\n cleanup();\n resolve(false);\n }, 10000);\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Create and open a full-viewport `<dialog>` containing a passkey iframe.\n *\n * The SDK owns the browser `<dialog>` plus a minimal generic preload shell\n * that appears immediately on click. The passkey iframe owns all branded and\n * origin-specific UI (TitleBar, trust icon, action cards); the shell is\n * removed as soon as the iframe reports that its centered card has painted.\n *\n * Lifecycle:\n * 1. A themed generic preload shell is injected and shown immediately\n * while the iframe loads. It intentionally contains no TitleBar or\n * origin chrome so that UI has a single implementation in apps/passkey.\n * 2. When the iframe sends `PASSKEY_RENDERED`, the overlay is removed and\n * the iframe becomes fully visible in the same frame.\n * 3. The returned `cleanup` function tears down all event listeners,\n * disconnects the MutationObserver, closes the `<dialog>`, and removes\n * it from the DOM. It is idempotent — safe to call multiple times.\n *\n * Browser quirks handled:\n * - The 1Password extension sets `inert` on the `<dialog>`, making it\n * non-interactive. A MutationObserver removes the attribute immediately.\n * - Password managers may also set `inert` on dialog siblings; cleanup\n * restores those as well.\n * - The iframe sandbox includes `allow-popups-to-escape-sandbox` so that\n * 1Password's popup UI can render outside the sandboxed context.\n * - `allow-downloads` lets the passkey iframe trigger the recovery-key\n * JSON fallback download without sending sensitive data to the parent.\n *\n * @param url - The full URL (including query params) to load in the iframe.\n * @returns References to the dialog, iframe, and a cleanup function.\n */\n private createModalDialog(url: string, options?: { persistent?: boolean; hidden?: boolean }): {\n dialog: HTMLDialogElement;\n iframe: HTMLIFrameElement;\n cleanup: () => void;\n destroy: () => void;\n reveal: () => void;\n } {\n const dialogUrl = this.getDialogUrl();\n const hostUrl = new URL(dialogUrl);\n\n const urlParams = new URL(url, window.location.href).searchParams;\n const { background: backdropBackground, blur: backdropBlur } =\n resolveBackdropStyle(urlParams);\n const themeMode = urlParams.get(\"theme\") || \"light\";\n const isDark =\n themeMode === \"dark\" ||\n (themeMode !== \"light\" &&\n window.matchMedia(\"(prefers-color-scheme: dark)\").matches);\n const theme = isDark ? DARK_TOKENS : LIGHT_TOKENS;\n\n const dialog = document.createElement(\"dialog\");\n dialog.dataset.passkey = \"\";\n if (options?.hidden) {\n dialog.dataset.passkeyHidden = \"\";\n }\n dialog.style.opacity = \"1\";\n dialog.style.background = \"transparent\";\n document.body.appendChild(dialog);\n\n const style = document.createElement(\"style\");\n style.textContent = `\n dialog[data-passkey] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n max-width: none;\n max-height: none;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n color-scheme: normal;\n outline: none;\n overflow: hidden;\n pointer-events: auto;\n }\n dialog[data-passkey]::backdrop {\n background: transparent !important;\n }\n dialog[data-passkey][data-passkey-hidden] {\n width: 1px;\n height: 1px;\n max-width: 1px;\n max-height: 1px;\n opacity: 0;\n pointer-events: none;\n }\n dialog[data-passkey][data-passkey-hidden] iframe {\n width: 1px;\n height: 1px;\n opacity: 0 !important;\n pointer-events: none;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n dialog[data-passkey] [data-passkey-overlay] {\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${backdropBackground};\n backdrop-filter: blur(${backdropBlur}px);\n -webkit-backdrop-filter: blur(${backdropBlur}px);\n z-index: 1;\n pointer-events: none;\n }\n dialog[data-passkey][data-passkey-hidden] [data-passkey-overlay] {\n display: none;\n }\n dialog[data-passkey] [data-passkey-preload-card] {\n width: ${LOADING_MODAL_WIDTH}px;\n max-width: 100%;\n overflow: hidden;\n border-radius: ${LOADING_MODAL_RADIUS}px;\n background: ${theme.bgPrimary};\n box-shadow: 0 24px 80px rgba(0, 0, 0, 0.24), 0 2px 12px rgba(0, 0, 0, 0.12);\n font-family: ${LOADING_FONT_FAMILY};\n line-height: ${LOADING_LINE_HEIGHT};\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n dialog[data-passkey] [data-passkey-preload-body] {\n box-sizing: border-box;\n display: flex;\n width: 100%;\n flex-direction: column;\n align-items: center;\n gap: ${LOADING_BODY_GAP}px;\n padding: ${LOADING_MODAL_PADDING}px;\n border-radius: ${LOADING_MODAL_RADIUS}px;\n background: ${theme.bgPrimary};\n }\n dialog[data-passkey] [data-passkey-preload-spinner-wrap] {\n display: flex;\n align-items: center;\n padding: ${LOADING_ICON_PADDING}px;\n }\n dialog[data-passkey] [data-passkey-preload-spinner] {\n position: relative;\n width: ${SPINNER_SIZE}px;\n height: ${SPINNER_SIZE}px;\n }\n dialog[data-passkey] [data-passkey-preload-spinner] svg {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n color: ${BRAND_PURPLE};\n animation: _1auth-spin ${SPINNER_SPIN_DURATION_MS}ms linear infinite;\n }\n dialog[data-passkey] [data-passkey-preload-copy] {\n display: flex;\n width: 100%;\n flex-direction: column;\n align-items: center;\n gap: ${LOADING_TITLE_BLOCK_GAP}px;\n text-align: center;\n }\n dialog[data-passkey] [data-passkey-preload-title] {\n margin: 0;\n color: ${theme.textPrimary};\n font-size: ${LOADING_TITLE_FONT_SIZE}px;\n font-weight: ${LOADING_TITLE_FONT_WEIGHT};\n line-height: ${LOADING_LINE_HEIGHT};\n }\n dialog[data-passkey] [data-passkey-preload-subtitle] {\n margin: 0;\n color: ${theme.textSecondary};\n font-size: ${LOADING_SUBTITLE_FONT_SIZE}px;\n font-weight: ${LOADING_SUBTITLE_FONT_WEIGHT};\n line-height: ${LOADING_LINE_HEIGHT};\n }\n @media (max-width: 639px) {\n dialog[data-passkey] [data-passkey-overlay] {\n align-items: flex-end;\n }\n dialog[data-passkey] [data-passkey-preload-card] {\n width: 100%;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n }\n dialog[data-passkey] [data-passkey-preload-body] {\n padding-bottom: calc(${LOADING_MODAL_PADDING}px + env(safe-area-inset-bottom));\n }\n }\n @keyframes _1auth-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n dialog[data-passkey] iframe {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n background-color: transparent;\n color-scheme: normal;\n pointer-events: auto;\n backdrop-filter: blur(${backdropBlur}px);\n -webkit-backdrop-filter: blur(${backdropBlur}px);\n transition: none;\n }\n `;\n dialog.appendChild(style);\n\n const overlay = document.createElement(\"div\");\n overlay.dataset.passkeyOverlay = \"\";\n\n const preloadCard = document.createElement(\"div\");\n preloadCard.dataset.passkeyPreloadCard = \"\";\n\n const preloadBody = document.createElement(\"div\");\n preloadBody.dataset.passkeyPreloadBody = \"\";\n const spinnerWrap = document.createElement(\"div\");\n spinnerWrap.dataset.passkeyPreloadSpinnerWrap = \"\";\n const spinner = document.createElement(\"div\");\n spinner.dataset.passkeyPreloadSpinner = \"\";\n const spinnerCenter = SPINNER_SIZE / 2;\n const spinnerGap = SPINNER_CIRCUMFERENCE - SPINNER_ARC;\n spinner.innerHTML =\n `<svg viewBox=\"0 0 ${SPINNER_SIZE} ${SPINNER_SIZE}\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">` +\n `<circle cx=\"${spinnerCenter}\" cy=\"${spinnerCenter}\" r=\"${SPINNER_RADIUS}\" stroke=\"currentColor\" opacity=\"0.3\" stroke-width=\"${SPINNER_STROKE}\"/>` +\n `<circle cx=\"${spinnerCenter}\" cy=\"${spinnerCenter}\" r=\"${SPINNER_RADIUS}\" stroke=\"currentColor\" stroke-width=\"${SPINNER_STROKE}\" stroke-linecap=\"round\" stroke-dasharray=\"${SPINNER_ARC} ${spinnerGap}\" transform=\"rotate(-90 ${spinnerCenter} ${spinnerCenter})\"/>` +\n `</svg>`;\n spinnerWrap.appendChild(spinner);\n\n const preloadCopy = document.createElement(\"div\");\n preloadCopy.dataset.passkeyPreloadCopy = \"\";\n const preloadTitle = document.createElement(\"p\");\n preloadTitle.dataset.passkeyPreloadTitle = \"\";\n preloadTitle.textContent = LOADING_TITLE;\n const preloadSubtitle = document.createElement(\"p\");\n preloadSubtitle.dataset.passkeyPreloadSubtitle = \"\";\n preloadSubtitle.textContent = LOADING_SUBTITLE;\n preloadCopy.append(preloadTitle, preloadSubtitle);\n preloadBody.append(spinnerWrap, preloadCopy);\n preloadCard.appendChild(preloadBody);\n overlay.appendChild(preloadCard);\n dialog.appendChild(overlay);\n\n // Create full-viewport iframe\n const iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\n \"allow\",\n [\n `publickey-credentials-get ${hostUrl.origin}`,\n `publickey-credentials-create ${hostUrl.origin}`,\n \"clipboard-write\",\n \"identity-credentials-get\",\n ].join(\"; \"),\n );\n iframe.setAttribute(\"aria-label\", \"Passkey Authentication\");\n iframe.setAttribute(\"tabindex\", \"0\");\n // Sandbox with allow-same-origin preserves the iframe's real origin for\n // WebAuthn and cookies. allow-popups-to-escape-sandbox lets 1Password's\n // browser extension render its popup UI outside the sandboxed context.\n // allow-downloads permits same-iframe recovery JSON export.\n iframe.setAttribute(\n \"sandbox\",\n \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-downloads\",\n );\n iframe.setAttribute(\"title\", \"Passkey\");\n // The SDK shell above is visible immediately. Keep the iframe at opacity 0\n // until PASSKEY_RENDERED so the user never sees the pre-layout first paint\n // (the dialog page SSRs with fullViewport=false, so its very first client\n // paint can be the embedded full-width card before the URL-seeded\n // re-render centres it).\n iframe.style.opacity = \"0\";\n\n // Reveal the iframe once it has painted and drop the SDK shell in the same\n // frame. The shell exists only to make click-to-visual immediate while the\n // cross-origin iframe boots; once PASSKEY_RENDERED lands, the iframe owns\n // all visible UI.\n // Register the message listener before assigning `src`: warmed auth\n // routes can render and post PASSKEY_RENDERED very quickly, and missing\n // that one-shot signal would leave the iframe invisible indefinitely.\n let revealed = false;\n // Armed when PASSKEY_READY arrives but PASSKEY_RENDERED hasn't yet — see\n // the handler below. Cleared on reveal so a late RENDERED / teardown\n // doesn't leave a dangling timer.\n let readyFailsafe: ReturnType<typeof setTimeout> | undefined;\n const revealIframe = () => {\n if (revealed) return;\n revealed = true;\n clearTimeout(readyFailsafe);\n iframe.style.opacity = \"1\";\n overlay.style.display = \"none\";\n };\n // Failsafe: if PASSKEY_RENDERED never arrives (redirect race, message\n // dropped, iframe crash) we don't want the iframe stuck invisible forever.\n // After 8s the iframe has either rendered something the user can interact\n // with or is broken in a way that staying hidden can't help with — either\n // way, revealing is strictly better than a blank modal. 8s is well above\n // the normal sub-second iframe-load path so it never preempts the real\n // PASSKEY_RENDERED signal in healthy flows.\n const revealFailsafe = setTimeout(revealIframe, 8000);\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== hostUrl.origin) return;\n // Pin to THIS modal's iframe. Origin alone isn't enough: other\n // same-origin dialog frames can exist on the page (a parked `prewarm()`\n // frame, a second SDK instance, the persistent sign-eoa iframe). Without\n // this, a stray RENDERED/READY from one of them could reveal this modal's\n // iframe before its own content has painted, flashing a blank or\n // half-rendered dialog. (`prewarm`'s warm route is message-silent, so\n // this is defense in depth rather than its only guard.)\n if (event.source !== iframe.contentWindow) return;\n // PASSKEY_RENDERED is the ONLY signal that the iframe has painted its\n // final, correct layout: DialogShell / DialogCard post it after a\n // double-rAF, i.e. once the centered fullViewport card is on screen.\n if (event.data?.type === \"PASSKEY_RENDERED\") {\n revealIframe();\n }\n // PASSKEY_READY fires on mount, BEFORE the iframe has painted the\n // fullViewport layout. The dialog page server-renders with\n // `fullViewport=false` (no `window` on the server), so its first client\n // paint is the embedded, full-width Loading card; the centered layout\n // only lands after the URL-seeded client re-render. Revealing the\n // iframe on READY therefore flashes that full-width card for a frame or\n // two — the exact \"loading screen flash\" we're avoiding. So READY does\n // NOT reveal directly; it only arms a short fallback in case RENDERED is\n // lost (redirect remount, dropped frame). By the time this fires the\n // layout has long settled, so we still never expose the full-width card —\n // and we recover far faster than the 8s `revealFailsafe`. Every modal\n // route (auth/connect/account/grant-permission/sign/sign-eoa) reliably\n // posts RENDERED in fullViewport mode, so in healthy flows this never\n // fires.\n else if (\n event.data?.type === \"PASSKEY_READY\" &&\n !revealed &&\n readyFailsafe === undefined\n ) {\n readyFailsafe = setTimeout(revealIframe, 1000);\n }\n if (event.data?.type === \"PASSKEY_DISCONNECT\") {\n localStorage.removeItem(\"1auth-user\");\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // Append `fullViewport=1` so the iframe's DialogProvider can seed its\n // initial state synchronously. Without this, `fullViewport` defaults to\n // false until PASSKEY_INIT arrives by postMessage — and on slow runs the\n // first paint of Loading.tsx renders as an embedded (full-width, top-of-\n // iframe) card before the message corrects it. Since we reveal the iframe\n // on PASSKEY_RENDERED, that wrong layout would be briefly visible.\n // Reading the flag from the URL eliminates the race.\n const iframeUrl = new URL(url, window.location.href);\n iframeUrl.searchParams.set(\"fullViewport\", \"1\");\n iframe.setAttribute(\"src\", iframeUrl.toString());\n dialog.appendChild(iframe);\n\n // Tell the dialog about the parent viewport so its DialogCard can\n // cap at 75% of screen height. Modal flow sets `fullViewport:\n // true` (which uses its own `calc(100dvh - 100px)` outer cap and\n // makes this no-op), but we wire it up defensively so any future\n // non-fullViewport modal route picks up the same gating without\n // a separate SDK change.\n const viewportInfoCleanup = this.wireViewportInfo(iframe);\n\n // 1Password extension adds `inert` attribute to <dialog>, making it\n // non-interactive. Watch for this and remove it immediately.\n const inertObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.attributeName === \"inert\") {\n dialog.removeAttribute(\"inert\");\n }\n }\n });\n inertObserver.observe(dialog, { attributes: true });\n\n // Handle escape key\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n cleanup();\n }\n };\n document.addEventListener(\"keydown\", handleEscape);\n\n const reveal = () => {\n delete dialog.dataset.passkeyHidden;\n if (!revealed) {\n revealed = true;\n clearTimeout(readyFailsafe);\n clearTimeout(revealFailsafe);\n }\n iframe.style.opacity = \"1\";\n overlay.style.display = \"none\";\n };\n\n // Hidden blind-signing requests must not make the host page inert. They\n // still need a rendered iframe so the passkey origin can run WebAuthn.\n if (options?.hidden) {\n dialog.show();\n } else {\n dialog.showModal();\n }\n\n let cleanedUp = false;\n const destroy = () => {\n if (cleanedUp) return;\n cleanedUp = true;\n clearTimeout(revealFailsafe);\n clearTimeout(readyFailsafe);\n inertObserver.disconnect();\n viewportInfoCleanup();\n window.removeEventListener(\"message\", handleMessage);\n document.removeEventListener(\"keydown\", handleEscape);\n dialog.close();\n // Clean up 1Password inert attributes left on dialog siblings\n if (dialog.parentNode) {\n for (const sibling of Array.from(dialog.parentNode.children)) {\n if (sibling !== dialog && sibling instanceof HTMLElement && sibling.hasAttribute(\"inert\")) {\n sibling.removeAttribute(\"inert\");\n }\n }\n }\n dialog.remove();\n };\n\n // In persistent mode the iframe lives across many open/close cycles\n // (used by `requestWithWallet` so the WalletConnect SignClient inside\n // the iframe is not recreated for every EOA request). `cleanup` here\n // just hides the dialog; full teardown is reachable via `destroy`.\n const cleanup = options?.persistent\n ? () => {\n if (dialog.open) dialog.close();\n }\n : destroy;\n\n return { dialog, iframe, cleanup, destroy, reveal };\n }\n\n /**\n * Listen for the auth result from the modal dialog.\n *\n * Each modal call generates a per-session nonce that the iframe must\n * echo back in `PASSKEY_CLOSE` / `PASSKEY_LOGIN_RESULT` /\n * `PASSKEY_RETRY_POPUP` messages. Without an echo, a queued CLOSE\n * from the previous iframe could be dispatched to the new modal's\n * listener (postMessage events tagged with `event.source` from a now-\n * destroyed iframe still reach the parent's message handler) and\n * silently cancel the fresh auth attempt. The nonce makes that race\n * harmless: a stale message that doesn't carry the current modal's\n * nonce is ignored.\n *\n * Also handles the `PASSKEY_RETRY_POPUP` message: sent by the dialog when a\n * password manager (e.g. Bitwarden) intercepts the WebAuthn call inside the\n * iframe. In that case the SDK seamlessly re-opens a standalone popup window,\n * where WebAuthn works without cross-origin iframe restrictions, and waits\n * for the result from there instead.\n *\n * @param _dialog - Unused; kept for signature consistency.\n * @param iframe - The iframe element; used to send `PASSKEY_INIT` on ready.\n * @param cleanup - Idempotent teardown for the modal dialog.\n * @returns An `AuthResult` discriminated union.\n */\n private waitForModalAuthResponse(\n _dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n requestId?: string\n ): Promise<AuthResult> {\n const dialogOrigin = this.getDialogOrigin();\n // Per-modal nonce so stale messages from a previous iframe can't\n // cancel a fresh auth attempt. The dialog echoes this back on every\n // result-bearing message; messages without the matching nonce are\n // ignored.\n const modalNonce = generateModalNonce();\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n const data = event.data;\n\n const matchesSource = event.source === iframe.contentWindow;\n const matchesRequest =\n typeof requestId === \"string\" && data?.requestId === requestId;\n const matchesNonce = data?.modalNonce === modalNonce;\n const isCurrentFrameClose =\n data?.type === \"PASSKEY_CLOSE\" && matchesSource;\n\n if (\n data?.type === \"PASSKEY_CLOSE\" &&\n (matchesRequest || matchesNonce || isCurrentFrameClose)\n ) {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n return;\n }\n\n // Send init message once the dialog signals it's ready to receive\n // it; many entry routes fire this from their first useEffect.\n // The nonce travels with INIT and the dialog stores it for later\n // echo on CLOSE / RESULT messages.\n if (data?.type === \"PASSKEY_READY\") {\n\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n mode: \"iframe\",\n fullViewport: true,\n modalNonce,\n }, dialogOrigin);\n return;\n }\n\n const hasModalNonce = typeof data?.modalNonce === \"string\";\n const isCurrentDialogMessage =\n matchesSource || matchesNonce || !hasModalNonce;\n if (!isCurrentDialogMessage) return;\n\n // Result-bearing messages without the current modal's nonce are\n // late-arriving CLOSE / RESULT events from a previously cleaned-\n // up iframe (postMessage queue, tab-throttling, etc.). Drop them\n // so they can't cancel or hijack the fresh modal.\n if (data?.modalNonce && data.modalNonce !== modalNonce) return;\n\n if (data?.type === \"PASSKEY_LOGIN_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (data.success) {\n resolve({\n success: true,\n user: {\n id: data.data?.user?.id,\n username: data.data?.username,\n address: data.data?.address as `0x${string}`,\n },\n signerType: data.data?.signerType ?? \"passkey\",\n });\n } else {\n resolve({\n success: false,\n error: data.error,\n });\n }\n } else if (data?.type === \"PASSKEY_RETRY_POPUP\") {\n // Password manager (e.g. Bitwarden) interfered with WebAuthn in iframe\n // Retry in popup mode where WebAuthn works without cross-origin restrictions\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n // Get the current dialog URL and switch to popup mode\n const popupUrl = data.data?.url?.replace(\"mode=iframe\", \"mode=popup\")\n || `${this.getDialogUrl()}/dialog/auth?mode=popup${this.config.clientId ? `&clientId=${this.config.clientId}` : ''}`;\n\n // Open popup and wait for result\n this.waitForPopupAuthResponse(popupUrl).then(resolve);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Open a popup for auth and wait for the result.\n * Used when iframe mode fails (e.g., due to password manager interference).\n */\n private waitForPopupAuthResponse(url: string): Promise<AuthResult> {\n const dialogOrigin = this.getDialogOrigin();\n const popup = this.openPopup(url);\n\n return new Promise((resolve) => {\n // Poll to check if popup was closed\n const pollTimer = setInterval(() => {\n if (popup?.closed) {\n clearInterval(pollTimer);\n window.removeEventListener(\"message\", handleMessage);\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n }\n }, 500);\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n if (data?.type === \"PASSKEY_LOGIN_RESULT\") {\n clearInterval(pollTimer);\n window.removeEventListener(\"message\", handleMessage);\n popup?.close();\n\n if (data.success) {\n resolve({\n success: true,\n user: {\n id: data.data?.user?.id,\n username: data.data?.username,\n address: data.data?.address as `0x${string}`,\n },\n signerType: data.data?.signerType ?? \"passkey\",\n });\n } else {\n resolve({\n success: false,\n error: data.error,\n });\n }\n } else if (data?.type === \"PASSKEY_CLOSE\") {\n clearInterval(pollTimer);\n window.removeEventListener(\"message\", handleMessage);\n popup?.close();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for the connect result from the connect dialog.\n *\n * The connect flow is a lightweight \"are you still you?\" confirmation that\n * does not require a new passkey ceremony. On success, the dialog returns the\n * user's username, address, and an `autoConnected` flag indicating whether the\n * user had previously enabled auto-connect (in which case no UI was shown).\n *\n * On failure with `action: \"switch\"`, the caller should redirect to the full\n * auth flow because the user has no cached session to confirm.\n *\n * @param _dialog - Unused; kept for signature consistency.\n * @param _iframe - Unused; kept for signature consistency.\n * @param cleanup - Idempotent teardown for the modal dialog.\n * @returns A `ConnectResult` discriminated union.\n */\n private waitForConnectResponse(\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<ConnectResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n if (data?.type === \"PASSKEY_CONNECT_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (data.success) {\n resolve({\n success: true,\n user: {\n username: data.data?.username,\n address: data.data?.address as `0x${string}`,\n },\n autoConnected: data.data?.autoConnected,\n });\n } else {\n resolve({\n success: false,\n action: data.data?.action,\n error: data.error,\n });\n }\n } else if (data?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n action: \"cancel\",\n error: {\n code: \"USER_CANCELLED\",\n message: \"Connection was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for grant-permission results and bridge sponsorship token requests.\n *\n * The grant iframe owns the passkey ceremony and install intent submission.\n * Extension-token minting stays in the app origin, so the SDK exposes a\n * narrow postMessage round-trip that never gives the iframe app secrets.\n *\n * @param _dialog - Unused; kept for signature consistency.\n * @param iframe - The grant iframe that receives extension-token responses.\n * @param cleanup - Idempotent teardown for the modal dialog.\n * @param sponsor - Whether this grant flow should request an extension token.\n * @returns A `GrantPermissionsResult` discriminated union.\n */\n private waitForGrantPermissionResponse(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n sponsor: boolean,\n initPayload: Record<string, unknown>\n ): Promise<GrantPermissionsResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let readySeen = false;\n\n const teardown = () => {\n clearTimeout(readyTimeout);\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const postInit = () => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n dialogOrigin,\n );\n };\n\n const handleClose = () => {\n teardown();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n });\n };\n\n const handleMessage = async (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n\n if (data?.type === \"PASSKEY_READY\") {\n readySeen = true;\n clearTimeout(readyTimeout);\n // Grant iframe routes can remount in dev/HMR and after Suspense\n // boundaries. Re-send init on every READY so the review page never\n // gets stranded on its initial loading state.\n postInit();\n return;\n }\n\n if (data?.type === \"PASSKEY_GRANT_EXTENSION_TOKEN_REQUEST\") {\n const requestId = data.requestId as string | undefined;\n const intentOp = data.intentOp as string | undefined;\n const postResponse = (payload: Record<string, unknown>) => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_GRANT_EXTENSION_TOKEN_RESPONSE\", requestId, ...payload },\n dialogOrigin\n );\n };\n\n if (!requestId || !intentOp) {\n postResponse({ success: false, error: \"Invalid extension token request\" });\n return;\n }\n\n if (!sponsor) {\n postResponse({ success: true });\n return;\n }\n\n if (!this.sponsorship) {\n postResponse({ success: false, error: MISSING_APP_CREDENTIALS_MESSAGE });\n return;\n }\n\n try {\n const token = await this.sponsorship.getExtensionToken(intentOp);\n postResponse({ success: true, token });\n } catch (err) {\n postResponse({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n return;\n }\n\n if (data?.type === \"PASSKEY_GRANT_PERMISSION_RESULT\") {\n if (data.success) {\n // Resolve the grant result but DELIBERATELY keep the dialog open.\n // The grant dialog's `success` state renders a \"Permission granted\"\n // confirmation with a green Done button (mirroring the sign flow's\n // `confirmed` screen). Calling cleanup() here — as we still do on\n // the failure path — would destroy that iframe before it paints, so\n // the user would never see a success screen. Instead we just stop\n // listening for grant messages; grantPermissions() then awaits\n // waitForDialogClose() so the confirmation stays up until the user\n // clicks Done (PASSKEY_CLOSE). This matches sendIntent, where\n // waitForSigningResponse resolves on success without cleanup and the\n // caller awaits the dialog close.\n teardown();\n resolve({ success: true, ...(data.data ?? {}) });\n return;\n }\n\n // Failure: there's no success screen to preserve, and the passkey app\n // sends PASSKEY_CLOSE right after this RESULT — but teardown() removes\n // the listener, so that follow-up would be dropped. Close here, the\n // same way the sign failure path does.\n teardown();\n cleanup();\n resolve({\n success: false,\n error: data.error ?? data.data?.error ?? {\n code: \"GRANT_PERMISSION_FAILED\",\n message: \"Permission grant failed\",\n },\n });\n } else if (\n data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Same cross-frame guard as the sign/ready paths: a stray\n // PASSKEY_CLOSE from another same-origin dialog (e.g. an auth modal\n // tearing down) must not cancel an in-flight grant. Only honor the\n // close from THIS grant iframe.\n teardown();\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n const readyTimeout = setTimeout(() => {\n if (readySeen) return;\n teardown();\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n });\n }, 10000);\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Listen for a signing result from a server-request-based modal dialog.\n *\n * Similar to `waitForIntentSigningResponse` but intended for the older\n * `signWithModal` path that pre-creates a signing request via the API (rather\n * than inlining all data in `PASSKEY_INIT`). Filters by `requestId` to handle\n * the case where stale messages from a previous dialog may still be in flight.\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param _dialog - Unused; kept for signature consistency.\n * @param _iframe - Unused; kept for signature consistency.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForModalSigningResponse(\n requestId: string,\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n // The Messenger sends: { type, success, data: { requestId, signature }, error }\n // So we need to check message.data.requestId, not message.requestId\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\" && payload?.requestId === requestId) {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n });\n } else {\n resolve({\n success: false,\n requestId,\n error: message.error,\n });\n }\n } else if (message?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n requestId,\n error: {\n code: \"USER_REJECTED\",\n message: \"Signing was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for a signing result from a popup window.\n *\n * Polls for popup closure every 500 ms as a fallback to detect when the user\n * closes the popup without completing the signing flow (no `PASSKEY_CLOSE`\n * message is fired in that case because the popup's unload event cannot\n * reliably postMessage to the opener on all browsers).\n *\n * On success or cancellation, the popup is programmatically closed and the\n * interval is cleared.\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param popup - The popup `Window` reference returned by `openPopup`.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForPopupResponse(\n requestId: string,\n popup: Window\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const checkClosed = setInterval(() => {\n if (popup.closed) {\n clearInterval(checkClosed);\n window.removeEventListener(\"message\", handleMessage);\n resolve({\n success: false,\n requestId,\n error: {\n code: \"USER_REJECTED\",\n message: \"Popup was closed without completing\",\n },\n });\n }\n }, 500);\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) {\n return;\n }\n\n const message = event.data;\n // The Messenger sends: { type, success, data: { requestId, signature }, error }\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n if (\n message?.type === \"PASSKEY_SIGNING_RESULT\" &&\n payload?.requestId === requestId\n ) {\n clearInterval(checkClosed);\n window.removeEventListener(\"message\", handleMessage);\n popup.close();\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n });\n } else {\n resolve({\n success: false,\n requestId,\n error: message.error,\n });\n }\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Fetch the completed signing result from the passkey service by request ID.\n *\n * Used by the redirect flow: after the passkey service redirects back to\n * `redirectUrl`, the integrator calls `handleRedirectCallback()`, which\n * extracts `requestId` from the URL query params and delegates here to\n * retrieve the full signature from the server.\n *\n * @param requestId - The signing request ID from the redirect callback URL.\n * @returns A `SigningResult` discriminated union.\n */\n private async fetchSigningResult(requestId: string): Promise<SigningResult> {\n const response = await fetch(\n `${this.config.providerUrl}/api/sign/request/${requestId}`,\n {\n headers: this.config.clientId\n ? { \"x-client-id\": this.config.clientId }\n : {},\n }\n );\n\n if (!response.ok) {\n return {\n success: false,\n requestId,\n error: {\n code: \"NETWORK_ERROR\",\n message: \"Failed to fetch signing result\",\n },\n };\n }\n\n const data: SigningRequestStatus = await response.json();\n\n if (data.status === \"COMPLETED\" && data.signature) {\n return {\n success: true,\n requestId,\n signature: data.signature,\n };\n }\n\n const errorCode: SigningErrorCode = data.error?.code || \"UNKNOWN\";\n return {\n success: false,\n requestId,\n error: {\n code: errorCode,\n message: data.error?.message || `Request status: ${data.status}`,\n },\n };\n }\n}\n","import { isTestnet } from \"./registry\";\nimport type { AssetBalance, AssetsResponse } from \"./types\";\n\ntype PortfolioChainBalance = {\n chainId?: number;\n chain?: number;\n address?: string;\n token?: string;\n balance?: string;\n amount?: string;\n decimals?: number;\n isTestnet?: boolean;\n};\n\ntype PortfolioAsset = {\n symbol?: string;\n decimals?: number;\n balance?: string;\n amount?: string;\n address?: string;\n token?: string;\n usdValue?: number;\n chains?: PortfolioChainBalance[];\n};\n\ntype FetchAssetsResponseOptions = {\n providerUrl: string;\n identifier: string;\n clientId?: string;\n accessToken?: string;\n headers?: Record<string, string>;\n};\n\n/**\n * Mark a normalized portfolio row with a stable network bucket flag.\n */\nfunction withNetworkBucket(balance: AssetBalance): AssetBalance {\n return {\n ...balance,\n isTestnet: balance.isTestnet ?? isTestnet(balance.chainId),\n };\n}\n\n/**\n * Split normalized balances into explicit mainnet and testnet buckets.\n */\nfunction bucketAssetBalances(balances: AssetBalance[]): Pick<\n AssetsResponse,\n \"mainnets\" | \"testnets\"\n> {\n const mainnetBalances: AssetBalance[] = [];\n const testnetBalances: AssetBalance[] = [];\n\n for (const balance of balances) {\n const normalized = withNetworkBucket(balance);\n if (normalized.isTestnet) {\n testnetBalances.push(normalized);\n } else {\n mainnetBalances.push(normalized);\n }\n }\n\n return {\n mainnets: { balances: mainnetBalances },\n testnets: { balances: testnetBalances },\n };\n}\n\n/**\n * Convert passkey portfolio responses into the documented assets response.\n */\nexport function normalizeAssetsResponse(payload: unknown): AssetsResponse {\n const data = payload && typeof payload === \"object\"\n ? (payload as Record<string, unknown>)\n : {};\n if (Array.isArray(data.balances)) {\n const balances = (data.balances as AssetBalance[]).map(withNetworkBucket);\n const buckets = bucketAssetBalances(balances);\n return { ...data, balances, ...buckets };\n }\n\n const balances: AssetBalance[] = [];\n const assets = Array.isArray(data.assets) ? (data.assets as PortfolioAsset[]) : [];\n for (const asset of assets) {\n const symbol = asset.symbol ?? \"UNKNOWN\";\n const decimals = asset.decimals ?? 18;\n const chains = Array.isArray(asset.chains) ? asset.chains : [];\n\n if (chains.length === 0) {\n const token = asset.token ?? asset.address;\n if (token) {\n balances.push(withNetworkBucket({\n chainId: 0,\n token,\n symbol,\n decimals,\n balance: asset.balance ?? asset.amount ?? \"0\",\n ...(asset.usdValue !== undefined && { usdValue: asset.usdValue }),\n }));\n }\n continue;\n }\n\n for (const chain of chains) {\n const chainId = chain.chainId ?? chain.chain;\n const token = chain.token ?? chain.address;\n if (typeof chainId !== \"number\" || !token) continue;\n balances.push(withNetworkBucket({\n chainId,\n token,\n symbol,\n decimals: chain.decimals ?? decimals,\n balance: chain.balance ?? chain.amount ?? \"0\",\n ...(asset.usdValue !== undefined && { usdValue: asset.usdValue }),\n ...(chain.isTestnet !== undefined && { isTestnet: chain.isTestnet }),\n }));\n }\n }\n\n return { ...data, balances, ...bucketAssetBalances(balances) };\n}\n\n/**\n * Fetch the unified passkey portfolio and return normalized wallet assets.\n */\nexport async function fetchAssetsResponse(\n options: FetchAssetsResponseOptions,\n): Promise<AssetsResponse> {\n const portfolioUrl = new URL(\n `/api/users/${encodeURIComponent(options.identifier)}/portfolio`,\n options.providerUrl,\n );\n // `all=true` keeps the SDK from silently hiding testnet balances when the\n // caller is using a mixed mainnet/testnet account during dogfooding.\n portfolioUrl.searchParams.set(\"all\", \"true\");\n\n const response = await fetch(portfolioUrl.toString(), {\n headers: {\n ...options.headers,\n ...(options.accessToken ? { Authorization: `Bearer ${options.accessToken}` } : {}),\n ...(options.clientId ? { \"x-client-id\": options.clientId } : {}),\n },\n });\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get assets\");\n }\n return normalizeAssetsResponse(await response.json());\n}\n","// Shared constants for the loading screen that's rendered in two places:\n// 1. packages/sdk/src/client.ts — host-page overlay (vanilla DOM, before\n// the passkey iframe paints).\n// 2. apps/passkey/src/components/dialog/screens/Loading.tsx — same screen\n// drawn by the iframe via React + DialogShell + IconWithStatus.\n//\n// The handoff between the two is a crossfade on `PASSKEY_RENDERED`, so any\n// drift in geometry / colour / copy produces a visible flash. SDK-side\n// values live here instead of being inlined; the iframe side imports from\n// here too. If a value isn't in this file, BOTH sides duplicated it inline\n// — drift is now likely.\n//\n// Theme tokens are mirrored from apps/passkey/src/app/globals.css. If the\n// CSS values change there, update the LIGHT/DARK pairs below in the same PR.\n\n// === Spinner geometry =====================================================\n// 82×82 SVG with two concentric circles; the foreground arc covers 17 % of\n// the circumference and rotates via CSS `animate-spin`.\nexport const SPINNER_SIZE = 82;\nexport const SPINNER_STROKE = 2.4118;\nexport const SPINNER_RADIUS = (SPINNER_SIZE - SPINNER_STROKE) / 2;\nexport const SPINNER_CIRCUMFERENCE = 2 * Math.PI * SPINNER_RADIUS;\nexport const SPINNER_ARC_FRACTION = 0.17;\nexport const SPINNER_ARC = SPINNER_CIRCUMFERENCE * SPINNER_ARC_FRACTION;\n// One full rotation, in ms. Shared so the SDK host-page overlay and the\n// iframe's `IconWithStatus` spinner rotate at the SAME rate — otherwise the\n// arc visibly changes speed at the PASSKEY_RENDERED crossfade and the two\n// loading screens read as different. The iframe side previously inherited\n// Tailwind's `animate-spin` default (1s) while the SDK hardcoded 0.8s.\nexport const SPINNER_SPIN_DURATION_MS = 800;\n\n// === Modal geometry =======================================================\n// Mirrors apps/passkey DialogShell's full-viewport iframe placement:\n// centered desktop card at Tailwind's `sm` breakpoint, bottom sheet below it.\n// Source of truth: Figma \"Sizing changes\" frame (3036:9897) — Modal width\n// is 380px on desktop. Must stay in sync with `--spacing-modal-width` /\n// `--spacing-modal-padding` in apps/passkey/src/app/globals.css and with\n// the SDK's POPUP_WIDTH / DEFAULT_EMBED_WIDTH in packages/sdk/src/client.ts.\nexport const LOADING_MODAL_WIDTH = 380;\nexport const LOADING_MODAL_PADDING = 12;\nexport const LOADING_MODAL_RADIUS = 16;\nexport const LOADING_MOBILE_BREAKPOINT = 640;\n\n// === Spacing (inside the card) ============================================\n// Vertical rhythm between body and footer, and within the body block.\n// 16px between body and footer is the same value DialogShell uses for the\n// outer column gap; we keep them in lockstep so embedded dialogs share the\n// rhythm too.\nexport const LOADING_CARD_GAP = 16;\nexport const LOADING_BODY_GAP = 12;\nexport const LOADING_ICON_PADDING = 12;\nexport const LOADING_TITLE_BLOCK_GAP = 4;\nexport const LOADING_FOOTER_GAP = 4;\n\n// === Typography ===========================================================\n// Title + subtitle + footer. `line-height: normal` is critical: the host\n// page may set a different value on <body> (Tailwind preflight 1.5, etc)\n// and inheritance would otherwise blow up the card height.\nexport const LOADING_TITLE_FONT_SIZE = 20;\nexport const LOADING_TITLE_FONT_WEIGHT = 700;\nexport const LOADING_SUBTITLE_FONT_SIZE = 12;\nexport const LOADING_SUBTITLE_FONT_WEIGHT = 500;\nexport const LOADING_FOOTER_FONT_SIZE = 11;\nexport const LOADING_FOOTER_FONT_WEIGHT = 500;\nexport const LOADING_LINE_HEIGHT = \"normal\" as const;\n// Font stack matches `data-connect-v2` in apps/passkey globals.css. Inter\n// is loaded by the host app; the rest are safe fallbacks. Includes emoji\n// stack for screens that render copy with emoji characters.\nexport const LOADING_FONT_FAMILY =\n \"'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'\";\n\n// === Rhinestone wordmark ==================================================\n// Footer \"Powered by [logo]\". Source SVG is 72×16; both consumers render\n// at native size.\nexport const LOGO_WIDTH = 72;\nexport const LOGO_HEIGHT = 16;\n\n// === Brand colour =========================================================\n// Mirrors `--color-primary-500` in apps/passkey globals.css.\nexport const BRAND_PURPLE = \"#685bff\";\n\n// === Theme tokens =========================================================\n// Hex pairs mirroring the iframe's `light-dark()` CSS custom properties.\n// The host-page SDK overlay can't read those custom properties (different\n// document), so it picks light/dark from the `theme` URL param and falls\n// back to `prefers-color-scheme`.\nexport type LoadingThemeTokens = {\n /** `--color-modal-bg` */\n bgPrimary: string;\n /** `--color-modal-border` */\n borderColor: string;\n /** `--color-view-text-primary` */\n textPrimary: string;\n /** `--color-view-text-secondary` */\n textSecondary: string;\n};\n\nexport const LIGHT_TOKENS: LoadingThemeTokens = {\n bgPrimary: \"#ffffff\",\n borderColor: \"#f4f4f5\",\n textPrimary: \"#27272a\",\n textSecondary: \"#71717b\",\n};\n\nexport const DARK_TOKENS: LoadingThemeTokens = {\n bgPrimary: \"#0a0a0a\",\n borderColor: \"#18181b\",\n textPrimary: \"#e4e4e7\",\n textSecondary: \"#9f9fa9\",\n};\n\n// `--color-modal-text-footer` — a single value across both themes.\nexport const FOOTER_TEXT_COLOR = \"#71717b\";\n\n// === Copy =================================================================\nexport const LOADING_TITLE = \"Loading...\";\nexport const LOADING_SUBTITLE =\n \"This will only take a few moments, do not close the window.\";\n","import type { Abi, Address } from \"viem\";\nimport type { Permission } from \"@rhinestone/sdk\";\n\nexport type DefinePermissionsConfig<TAbi extends Abi> = Permission<TAbi> & {\n /** Optional human-readable name surfaced in the review UI. */\n name?: string;\n};\n\nexport interface DefinedPermissions<TAbi extends Abi = Abi> {\n /**\n * v2 SmartSession permissions, ready to pass to\n * `OneAuthClient.grantPermissions({ ...definePermissions(...) })`.\n *\n * Always a single-element array so the `...spread` pattern works cleanly\n * with `grantPermissions`, which accepts `permissions: Permission[]`.\n *\n * Widened to `Permission<Abi>` (rather than `Permission<TAbi>`) so the\n * spread composes with `GrantPermissionsOptions.permissions: Permission<Abi>[]`.\n * The SDK's v2 `Permission<TAbi>` includes conditional `SpendingLimitField<TFn>` /\n * `ValueLimitField<TFn>` types that break covariance over `TAbi`, so an inferred\n * narrow `Permission<erc20Abi>` is no longer assignable to `Permission<Abi>`.\n * We keep `TAbi` on the type parameter so `contracts[].abi` retains its\n * narrow shape for the review UI.\n */\n permissions: [Permission<Abi>];\n /**\n * Contract metadata for the permission review UI. The address and ABI\n * here mirror the entry in `permissions[0]`; `name` is optional and\n * purely cosmetic (it's never sent to a contract).\n */\n contracts: Array<{\n address: Address;\n name?: string;\n abi: TAbi;\n }>;\n}\n\n/**\n * Build a v2 SmartSession `Permission` from an ABI + function map.\n *\n * The Rhinestone SDK derives function selectors and universal-action\n * calldata offsets from the ABI internally, so app code no longer needs\n * to spell out raw 4-byte selectors or parameter indices. The accepted\n * shape is the SDK's own `Permission<TAbi>` plus an optional `name` for\n * the review UI.\n *\n * @example\n * const permissions = definePermissions({\n * address: USDC,\n * abi: erc20Abi,\n * name: \"USDC\",\n * functions: {\n * transfer: {\n * params: { to: { condition: \"equal\", value: RECIPIENT } },\n * },\n * },\n * });\n *\n * await oneAuth.grantPermissions({ ...permissions, sessionKeyAddress });\n */\nexport function definePermissions<const TAbi extends Abi>(\n config: DefinePermissionsConfig<TAbi>,\n): DefinedPermissions<TAbi> {\n const { name, ...permission } = config;\n return {\n permissions: [permission as unknown as Permission<Abi>],\n contracts: [\n {\n address: config.address,\n name,\n abi: config.abi,\n },\n ],\n };\n}\n","import { isAddress, type Address, type Chain } from \"viem\";\n\nimport { getTokenAddress } from \"./registry\";\n\nexport type CrossChainSettlementLayer = \"SAME_CHAIN\" | \"ECO\" | \"ACROSS\";\n\nexport interface CrossChainPermit {\n /** Allowed source legs: chain + token, with an optional amount cap. */\n from: Array<{ chain: Chain; token: Address; maxAmount?: bigint }>;\n /** Allowed destination legs: chain + token, with an optional recipient pin. */\n to: Array<{ chain: Chain; token: Address; recipient?: Address | \"any\" }>;\n /** Upper bound on the Permit2 deadline, expressed as Unix seconds. */\n validUntil?: bigint;\n /** Lower bound on the Permit2 deadline, expressed as Unix seconds. */\n validAfter?: bigint;\n /** Per-destination fill-deadline windows, expressed as Unix seconds. */\n fillDeadline?: Array<{ chain: Chain; min?: bigint; max?: bigint }>;\n /** When true, the destination recipient must be the smart account. */\n recipientIsAccount?: boolean;\n /** Allowed settlement layers. Omit or pass an empty array to allow any supported layer. */\n settlementLayers?: CrossChainSettlementLayer[];\n}\n\ninterface FromLeg {\n chain: Chain;\n token: Address | string;\n maxAmount?: bigint;\n}\n\ninterface ToLeg {\n chain: Chain;\n token: Address | string;\n recipient?: Address | \"any\";\n}\n\nexport interface CreateCrossChainPermissionInput {\n /** Source chain + token, with an optional amount cap. Pass an array for multi-leg permits. */\n from: FromLeg | FromLeg[];\n /** Destination chain + token, with an optional recipient pin. Pass an array for fan-out destinations. */\n to: ToLeg | ToLeg[];\n /** Upper bound on the Permit2 deadline. Accepts Unix-seconds bigint or Date. */\n validUntil?: bigint | Date;\n /** Lower bound on the Permit2 deadline. Accepts Unix-seconds bigint or Date. */\n validAfter?: bigint | Date;\n /** Per-destination fill-deadline windows, expressed as Unix seconds. */\n fillDeadline?: Array<{ chain: Chain; min?: bigint; max?: bigint }>;\n /**\n * Allow the destination recipient to differ from the smart account.\n * Defaults to false so bridge permissions are bridge-to-self unless the\n * caller explicitly broadens the grant.\n */\n allowRecipientNotAccount?: boolean;\n /** Settlement layers this session is permitted to use. */\n settlementLayers?: CrossChainSettlementLayer[];\n}\n\nfunction toUnixSecondsBigint(input: bigint | Date): bigint {\n if (typeof input === \"bigint\") return input;\n // Permit2 deadlines are Unix seconds; Date stores milliseconds.\n return BigInt(Math.floor(input.getTime() / 1000));\n}\n\nfunction resolveTokenForChain(token: Address | string, chainId: number): Address {\n return isAddress(token, { strict: false }) ? token : getTokenAddress(token, chainId);\n}\n\n/**\n * Build a CrossChainPermit for Permit2-backed bridge settlement.\n *\n * The returned object is JSON-safe after callers stringify bigint fields at\n * the iframe/API boundary and can be passed as\n * `grantPermissions({ crossChainPermits: [...] })`.\n */\nexport function createCrossChainPermission(\n input: CreateCrossChainPermissionInput,\n): CrossChainPermit {\n const fromLegs = Array.isArray(input.from) ? input.from : [input.from];\n const toLegs = Array.isArray(input.to) ? input.to : [input.to];\n\n if (fromLegs.length === 0) {\n throw new Error(\"createCrossChainPermission: `from` must contain at least one leg\");\n }\n if (toLegs.length === 0) {\n throw new Error(\"createCrossChainPermission: `to` must contain at least one leg\");\n }\n\n const validUntil =\n input.validUntil !== undefined ? toUnixSecondsBigint(input.validUntil) : undefined;\n const validAfter =\n input.validAfter !== undefined ? toUnixSecondsBigint(input.validAfter) : undefined;\n\n // Catch a broken time window before the user reaches the passkey dialog.\n if (validUntil !== undefined && validAfter !== undefined && validAfter > validUntil) {\n throw new Error(\n `createCrossChainPermission: validAfter (${validAfter}) is greater than validUntil (${validUntil})`,\n );\n }\n\n return {\n from: fromLegs.map((leg) => ({\n chain: leg.chain,\n token: resolveTokenForChain(leg.token, leg.chain.id),\n maxAmount: leg.maxAmount,\n })),\n to: toLegs.map((leg) => ({\n chain: leg.chain,\n token: resolveTokenForChain(leg.token, leg.chain.id),\n recipient: leg.recipient,\n })),\n validUntil,\n validAfter,\n fillDeadline: input.fillDeadline,\n recipientIsAccount: !input.allowRecipientNotAccount,\n settlementLayers: input.settlementLayers,\n };\n}\n","/**\n * viem LocalAccount adapter for 1auth passkey-controlled smart accounts.\n *\n * Bridges viem's `LocalAccount` interface to the 1auth passkey service so that\n * any viem-based library (e.g. permissionless, viem itself) can use a passkey\n * account without handling WebAuthn directly. All cryptographic operations are\n * delegated to the passkey service via `OneAuthClient`.\n *\n * @module\n */\n\nimport {\n bytesToString,\n hexToString,\n isHex,\n type Address,\n type LocalAccount,\n type SignableMessage,\n type TypedData,\n type TypedDataDefinition,\n} from \"viem\";\nimport { toAccount } from \"viem/accounts\";\nimport { OneAuthClient } from \"./client\";\nimport type { EIP712Domain, EIP712Types } from \"./types\";\nimport { encodeWebAuthnSignature } from \"./walletClient/utils\";\n\nexport type PasskeyAccount = LocalAccount<\"1auth\"> & {\n /** Optional username hint retained for legacy integrations. */\n username?: string;\n /** Smart account address used as the canonical signer identity. */\n accountAddress: Address;\n};\n\n/**\n * Creates a viem `LocalAccount` that delegates signing to the 1auth passkey service.\n *\n * The returned account satisfies the `LocalAccount` interface expected by viem's\n * `createWalletClient` and similar APIs. `signTransaction` is explicitly unsupported\n * because 1auth uses the intent/bundler model instead of raw signed transactions —\n * callers should use `sendIntent` (via `eth_sendTransaction` on the provider) instead.\n *\n * All signing operations encode the resulting WebAuthn signature with\n * `encodeWebAuthnSignature` so the output is directly usable with ERC-1271\n * on-chain verification.\n *\n * @param client - A configured `OneAuthClient` instance\n * @param params.address - The EVM address of the user's smart account\n * @param params.username - Optional 1auth username hint for older accounts\n * @returns A `PasskeyAccount` extending `LocalAccount<\"1auth\">`\n *\n * @example\n * ```typescript\n * import { createWalletClient, http } from \"viem\";\n * import { base } from \"viem/chains\";\n * import { OneAuthClient, createPasskeyAccount } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n * const account = createPasskeyAccount(client, {\n * address: \"0xYourSmartAccountAddress\",\n * });\n *\n * const walletClient = createWalletClient({\n * account,\n * chain: base,\n * transport: http(),\n * });\n *\n * const signature = await walletClient.signMessage({ message: \"Hello\" });\n * ```\n */\nexport function createPasskeyAccount(\n client: OneAuthClient,\n params: { address: Address; username?: string }\n): PasskeyAccount {\n const { address, username } = params;\n\n /**\n * Converts viem's polymorphic `SignableMessage` type to a plain string.\n *\n * viem allows messages to be passed as a plain string, a hex-encoded string under\n * the `{ raw: Hex }` form, or raw bytes under the `{ raw: Uint8Array }` form. The\n * passkey service only accepts plain strings, so this helper normalises all three\n * variants. Hex values are decoded to their UTF-8 representation; if decoding fails\n * (e.g. the hex is not valid UTF-8) the raw hex string is passed through unchanged.\n *\n * @param message - viem `SignableMessage` in any of its supported forms\n * @returns Plain string representation of the message\n */\n const normalizeMessage = (message: SignableMessage): string => {\n if (typeof message === \"string\") return message;\n const raw = message.raw;\n if (isHex(raw)) {\n try {\n return hexToString(raw);\n } catch {\n return raw;\n }\n }\n return bytesToString(raw);\n };\n\n const account = toAccount({\n address,\n signMessage: async ({ message }: { message: SignableMessage }) => {\n const result = await client.signMessage({\n username: username || undefined,\n accountAddress: address,\n message: normalizeMessage(message),\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n },\n signTransaction: async () => {\n throw new Error(\"signTransaction not supported; use sendIntent\");\n },\n signTypedData: async <\n const typedData extends TypedData | Record<string, unknown>,\n primaryType extends keyof typedData | \"EIP712Domain\" = keyof typedData\n >(\n typedData: TypedDataDefinition<typedData, primaryType>\n ) => {\n if (!typedData.domain || !typedData.types || !typedData.primaryType) {\n throw new Error(\"Invalid typed data\");\n }\n const domainInput = typedData.domain as Partial<EIP712Domain>;\n if (!domainInput.name || !domainInput.version) {\n throw new Error(\"Typed data domain must include name and version\");\n }\n const domain: EIP712Domain = {\n name: domainInput.name,\n version: domainInput.version,\n // viem uses bigint for chainId in typed data; the passkey service expects number\n chainId:\n typeof domainInput.chainId === \"bigint\"\n ? Number(domainInput.chainId)\n : domainInput.chainId,\n verifyingContract: domainInput.verifyingContract,\n salt: domainInput.salt,\n };\n const rawTypes =\n typedData.types as Record<string, readonly { name: string; type: string }[]>;\n // Strip any extra fields (e.g. readonly markers) that viem attaches to type\n // entries — the passkey service expects plain { name, type } objects.\n const normalizedTypes = Object.fromEntries(\n Object.entries(rawTypes).map(([key, fields]) => [\n key,\n fields.map((field) => ({ name: field.name, type: field.type })),\n ])\n ) as EIP712Types;\n const result = await client.signTypedData({\n username: username || undefined,\n accountAddress: address,\n domain,\n types: normalizedTypes,\n primaryType: typedData.primaryType as string,\n message: typedData.message as Record<string, unknown>,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n },\n });\n\n return {\n ...(account as LocalAccount<\"1auth\">),\n ...(username ? { username } : {}),\n accountAddress: address,\n };\n}\n","/**\n * @file viem WalletClient factory backed by passkey signing.\n *\n * {@link createPasskeyWalletClient} returns a standard viem `WalletClient`\n * augmented with a `sendCalls` method for batched ERC-4337 intents. All\n * signing operations open the 1auth passkey modal so that private keys never\n * leave the secure enclave on the user's device.\n *\n * The factory is framework-agnostic — it works in any environment that can\n * run viem (React, Vue, plain Node.js scripts, etc.).\n */\n\nimport {\n createWalletClient,\n hashMessage,\n hashTypedData,\n type WalletClient,\n type Hash,\n type SignableMessage,\n type TypedDataDefinition,\n} from 'viem';\nimport { toAccount } from 'viem/accounts';\nimport { OneAuthClient } from '../client';\nimport type { IntentCall, IntentTokenRequest } from '../types';\nimport type {\n PasskeyWalletClientConfig,\n SendCallsParams,\n TransactionCall,\n} from './types';\nimport {\n encodeWebAuthnSignature,\n hashCalls,\n buildTransactionReview,\n} from './utils';\n\nexport type { PasskeyWalletClientConfig, TransactionCall, SendCallsParams } from './types';\nexport { encodeWebAuthnSignature, hashCalls } from './utils';\n\n/**\n * Extended WalletClient with passkey signing and batch transaction support\n */\nexport type PasskeyWalletClient = WalletClient & {\n /**\n * Send multiple calls as a single batched transaction\n * Opens the passkey modal for user approval\n */\n sendCalls: (params: SendCallsParams) => Promise<Hash>;\n};\n\n/**\n * Create a viem-compatible WalletClient that uses passkeys for signing\n *\n * @example\n * ```typescript\n * import { createPasskeyWalletClient } from '@rhinestone/1auth';\n * import { baseSepolia } from 'viem/chains';\n * import { http } from 'viem';\n *\n * const walletClient = createPasskeyWalletClient({\n * accountAddress: '0x...',\n * username: 'alice',\n * providerUrl: 'https://passkey.1auth.app',\n * clientId: 'my-dapp',\n * chain: baseSepolia,\n * transport: http(),\n * });\n *\n * // Standard viem API\n * const hash = await walletClient.sendTransaction({\n * to: '0x...',\n * data: '0x...',\n * value: 0n,\n * });\n *\n * // Batched transactions\n * const batchHash = await walletClient.sendCalls({\n * calls: [\n * { to: '0x...', data: '0x...' },\n * { to: '0x...', data: '0x...' },\n * ],\n * });\n * ```\n */\nexport function createPasskeyWalletClient(\n config: PasskeyWalletClientConfig\n): PasskeyWalletClient {\n const identity = {\n ...(config.username ? { username: config.username } : {}),\n accountAddress: config.accountAddress,\n };\n\n const provider = new OneAuthClient({\n providerUrl: config.providerUrl,\n clientId: config.clientId,\n dialogUrl: config.dialogUrl,\n theme: config.theme,\n blind_signing: config.blind_signing,\n testnets: config.testnets,\n sponsorship: config.sponsorship,\n });\n\n /**\n * Sign an arbitrary message using the passkey modal.\n *\n * Hashes the message with EIP-191 (`hashMessage`) before passing it to the\n * modal as the WebAuthn challenge so the on-chain verifier receives a\n * deterministic, typed hash rather than raw user data.\n *\n * @param message - A plain string or a `{ raw: Hex | Uint8Array }` object\n * as accepted by viem's `SignableMessage`.\n * @returns ABI-encoded WebAuthn signature as a `0x`-prefixed hex string.\n */\n const signMessageImpl = async (message: SignableMessage): Promise<`0x${string}`> => {\n const hash = hashMessage(message);\n\n const result = await provider.signWithModal({\n challenge: hash,\n ...identity,\n description: 'Sign message',\n transaction: {\n actions: [\n {\n type: 'custom',\n label: 'Sign Message',\n sublabel:\n typeof message === 'string'\n ? message.slice(0, 50) + (message.length > 50 ? '...' : '')\n : 'Raw message',\n },\n ],\n },\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Signing failed');\n }\n\n if (!result.signature) {\n throw new Error('No signature received');\n }\n\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Sign a single transaction object using the passkey modal.\n *\n * Normalises the transaction into a `TransactionCall` array, computes a\n * deterministic hash over the calls with {@link hashCalls}, then presents\n * the transaction for user approval before encoding the resulting WebAuthn\n * signature.\n *\n * @param transaction - A viem transaction request object containing at least\n * `to`, and optionally `data` and `value`.\n * @returns ABI-encoded WebAuthn signature as a `0x`-prefixed hex string.\n */\n const signTransactionImpl = async (transaction: any): Promise<`0x${string}`> => {\n const calls: TransactionCall[] = [\n {\n to: transaction.to!,\n data: transaction.data,\n value: transaction.value,\n },\n ];\n\n const hash = hashCalls(calls);\n\n const result = await provider.signWithModal({\n challenge: hash,\n ...identity,\n description: 'Sign transaction',\n transaction: buildTransactionReview(calls),\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Signing failed');\n }\n\n if (!result.signature) {\n throw new Error('No signature received');\n }\n\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Sign EIP-712 typed data using the passkey modal.\n *\n * Hashes the structured data with viem's `hashTypedData` (which applies the\n * EIP-712 domain separator and struct hashing) and presents the primary type\n * name to the user as a human-readable label inside the signing dialog.\n *\n * @param typedData - EIP-712 typed data definition including `domain`,\n * `types`, `primaryType`, and `message`.\n * @returns ABI-encoded WebAuthn signature as a `0x`-prefixed hex string.\n */\n const signTypedDataImpl = async (typedData: any): Promise<`0x${string}`> => {\n const hash = hashTypedData(typedData as TypedDataDefinition);\n\n const result = await provider.signWithModal({\n challenge: hash,\n ...identity,\n description: 'Sign typed data',\n transaction: {\n actions: [\n {\n type: 'custom',\n label: 'Sign Data',\n sublabel: typedData.primaryType || 'Typed Data',\n },\n ],\n },\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Signing failed');\n }\n\n if (!result.signature) {\n throw new Error('No signature received');\n }\n\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Build the intent payload shared by `sendTransaction` and `sendCalls`.\n *\n * Converts `TransactionCall` objects (viem-style, with bigint values) into\n * `IntentCall` objects (serialisable, with string values) expected by the\n * passkey service. The target chain defaults to `config.chain.id` when no\n * override is provided.\n *\n * @param calls - One or more transaction calls to include in the intent.\n * @param targetChainOverride - Optional chain ID; overrides `config.chain.id`\n * when the intent should execute on a chain different from the client's\n * default (e.g. cross-chain intent routing).\n * @param extra - Optional token request and source asset metadata forwarded\n * to the Rhinestone orchestrator for cross-chain bridging intents.\n * @returns A plain object ready to spread into `provider.sendIntent(...)`.\n */\n const buildIntentPayload = async (\n calls: TransactionCall[],\n targetChainOverride?: number,\n extra?: { tokenRequests?: IntentTokenRequest[]; sourceAssets?: string[] },\n ) => {\n const targetChain = targetChainOverride ?? config.chain.id;\n const intentCalls: IntentCall[] = calls.map((call) => ({\n to: call.to,\n data: call.data || \"0x\",\n value: call.value !== undefined ? call.value.toString() : \"0\",\n label: call.label,\n sublabel: call.sublabel,\n icon: call.icon,\n abi: call.abi,\n }));\n\n return {\n ...(config.username ? { username: config.username } : {}),\n accountAddress: config.accountAddress,\n targetChain,\n calls: intentCalls,\n };\n };\n\n // toAccount returns a generic LocalAccount<string> but viem's WalletClient\n // constructor expects LocalAccount<\"custom\"> — the type assertion satisfies\n // this constraint without changing runtime behaviour.\n const account = toAccount({\n address: config.accountAddress,\n signMessage: ({ message }) => signMessageImpl(message),\n signTransaction: signTransactionImpl,\n signTypedData: signTypedDataImpl as any,\n });\n\n // Create the base wallet client\n const client = createWalletClient({\n account,\n chain: config.chain,\n transport: config.transport,\n });\n\n // Extend with sendCalls for batched transactions\n const extendedClient = Object.assign(client, {\n /**\n * Send a single transaction via intent flow\n */\n async sendTransaction(transaction: any): Promise<Hash> {\n const targetChain =\n typeof transaction.chainId === \"number\"\n ? transaction.chainId\n : transaction.chain?.id;\n const calls: TransactionCall[] = [\n {\n to: transaction.to!,\n data: transaction.data || \"0x\",\n value: transaction.value,\n },\n ];\n\n const intentPayload = await buildIntentPayload(calls, targetChain);\n const result = await provider.sendIntent({\n ...intentPayload,\n waitForHash: config.waitForHash ?? true,\n hashTimeoutMs: config.hashTimeoutMs,\n hashIntervalMs: config.hashIntervalMs,\n });\n\n if (!result.success || !result.transactionHash) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n return result.transactionHash as Hash;\n },\n /**\n * Send multiple calls as a single batched transaction\n */\n async sendCalls(params: SendCallsParams): Promise<Hash> {\n const { calls, chainId: targetChain, tokenRequests, sourceAssets, sourceChainId } = params;\n const intentPayload = await buildIntentPayload(calls, targetChain, { tokenRequests, sourceAssets });\n const result = await provider.sendIntent({\n ...intentPayload,\n tokenRequests,\n sourceAssets,\n sourceChainId,\n waitForHash: config.waitForHash ?? true,\n hashTimeoutMs: config.hashTimeoutMs,\n hashIntervalMs: config.hashIntervalMs,\n });\n\n if (!result.success || !result.transactionHash) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n return result.transactionHash as Hash;\n },\n });\n\n return extendedClient as PasskeyWalletClient;\n}\n","import * as React from \"react\";\nimport type { OneAuthClient } from \"../client\";\nimport type { IntentCall, SendIntentResult } from \"../types\";\nimport { getChainName as getRegistryChainName } from \"../registry\";\n\n/** Identity used to sign a queued batch. Account address is the canonical path. */\nexport interface BatchQueueIdentity {\n /** Optional username hint for legacy accounts. */\n username?: string;\n /** Smart account address of the signer. */\n accountAddress?: string;\n}\n\n/**\n * A batched call in the queue\n */\nexport interface BatchedCall {\n /** Unique ID for removal */\n id: string;\n /** The actual call data */\n call: IntentCall;\n /** Chain ID for execution */\n targetChain: number;\n /** Timestamp when added */\n addedAt: number;\n}\n\nexport function getChainName(chainId: number): string {\n return getRegistryChainName(chainId);\n}\n\n/**\n * Batch queue context value\n */\nexport interface BatchQueueContextValue {\n /** Current queue of batched calls */\n queue: BatchedCall[];\n /** Chain ID of the current batch (from first call) */\n batchChainId: number | null;\n /** Add a call to the batch */\n addToBatch: (call: IntentCall, targetChain: number) => { success: boolean; error?: string };\n /** Remove a call from the batch */\n removeFromBatch: (id: string) => void;\n /** Clear all calls from the batch */\n clearBatch: () => void;\n /** Sign and execute all batched calls */\n signAll: (identity?: string | BatchQueueIdentity) => Promise<SendIntentResult>;\n /** Whether the widget is expanded */\n isExpanded: boolean;\n /** Set widget expanded state */\n setExpanded: (expanded: boolean) => void;\n /** Whether signing is in progress */\n isSigning: boolean;\n /** Animation trigger for bounce effect */\n animationTrigger: number;\n}\n\nconst BatchQueueContext = React.createContext<BatchQueueContextValue | null>(null);\n\n/**\n * Hook to access the batch queue context\n */\nexport function useBatchQueue(): BatchQueueContextValue {\n const context = React.useContext(BatchQueueContext);\n if (!context) {\n throw new Error(\"useBatchQueue must be used within a BatchQueueProvider\");\n }\n return context;\n}\n\n/**\n * Generate a unique ID for a batched call\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * localStorage key for persisting the batch queue.\n *\n * We key by address when possible because new 1auth sessions may not expose a\n * username. The username fallback preserves existing queues for older apps.\n */\nfunction getStorageKey(identity?: BatchQueueIdentity): string {\n const key = identity?.accountAddress || identity?.username;\n return key ? `1auth_batch_queue_${key.toLowerCase()}` : \"1auth_batch_queue_anonymous\";\n}\n\n/** Convert legacy `signAll(username)` calls and provider props into one shape. */\nfunction resolveIdentity(\n passedIdentity: string | BatchQueueIdentity | undefined,\n providerIdentity: BatchQueueIdentity,\n): BatchQueueIdentity {\n if (typeof passedIdentity === \"string\") {\n return { username: passedIdentity, accountAddress: providerIdentity.accountAddress };\n }\n return {\n username: passedIdentity?.username ?? providerIdentity.username,\n accountAddress: passedIdentity?.accountAddress ?? providerIdentity.accountAddress,\n };\n}\n\nexport interface BatchQueueProviderProps {\n /** The OneAuthClient instance */\n client: OneAuthClient;\n /** Optional username for legacy localStorage persistence and account lookup. */\n username?: string;\n /** Optional account address for address-only sessions and persistence. */\n accountAddress?: string;\n /** Children to render */\n children: React.ReactNode;\n}\n\n/**\n * Provider component for the batch queue\n */\nexport function BatchQueueProvider({\n client,\n username,\n accountAddress,\n children,\n}: BatchQueueProviderProps) {\n const [queue, setQueue] = React.useState<BatchedCall[]>([]);\n const [isExpanded, setExpanded] = React.useState(false);\n const [isSigning, setIsSigning] = React.useState(false);\n const [animationTrigger, setAnimationTrigger] = React.useState(0);\n\n const providerIdentity = React.useMemo(\n () => ({ username, accountAddress }),\n [username, accountAddress],\n );\n\n // Derive batch chain from first call in queue\n const batchChainId = queue.length > 0 ? queue[0].targetChain : null;\n\n // Load queue from localStorage on mount\n React.useEffect(() => {\n const storageKey = getStorageKey(providerIdentity);\n try {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n const parsed = JSON.parse(stored) as BatchedCall[];\n // Validate the structure\n if (Array.isArray(parsed) && parsed.every(item =>\n typeof item.id === 'string' &&\n typeof item.call === 'object' &&\n typeof item.targetChain === 'number'\n )) {\n setQueue(parsed);\n }\n }\n } catch {\n // Ignore localStorage errors\n }\n }, [providerIdentity]);\n\n // Save queue to localStorage when it changes\n React.useEffect(() => {\n const storageKey = getStorageKey(providerIdentity);\n try {\n if (queue.length > 0) {\n localStorage.setItem(storageKey, JSON.stringify(queue));\n } else {\n localStorage.removeItem(storageKey);\n }\n } catch {\n // Ignore localStorage errors\n }\n }, [queue, providerIdentity]);\n\n const addToBatch = React.useCallback((call: IntentCall, targetChain: number): { success: boolean; error?: string } => {\n // Check if trying to add to a batch with a different chain\n if (batchChainId !== null && batchChainId !== targetChain) {\n return {\n success: false,\n error: `Batch is set to ${getChainName(batchChainId)}. Sign current batch first or clear it.`,\n };\n }\n\n const batchedCall: BatchedCall = {\n id: generateId(),\n call,\n targetChain,\n addedAt: Date.now(),\n };\n\n setQueue(prev => [...prev, batchedCall]);\n setAnimationTrigger(prev => prev + 1);\n\n return { success: true };\n }, [batchChainId]);\n\n const removeFromBatch = React.useCallback((id: string) => {\n setQueue(prev => prev.filter(item => item.id !== id));\n }, []);\n\n const clearBatch = React.useCallback(() => {\n setQueue([]);\n setExpanded(false);\n }, []);\n\n const signAll = React.useCallback(async (\n identity?: string | BatchQueueIdentity,\n ): Promise<SendIntentResult> => {\n if (queue.length === 0) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"EMPTY_BATCH\",\n message: \"No calls in batch to sign\",\n },\n };\n }\n\n const signer = resolveIdentity(identity, providerIdentity);\n if (!signer.username && !signer.accountAddress) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"MISSING_IDENTITY\",\n message: \"Batch signing requires an accountAddress or username\",\n },\n };\n }\n\n const targetChain = queue[0].targetChain;\n const calls = queue.map(item => item.call);\n\n setIsSigning(true);\n\n try {\n const result = await client.sendIntent({\n username: signer.username,\n accountAddress: signer.accountAddress,\n targetChain,\n calls,\n });\n\n if (result.success) {\n // Clear the batch on success\n clearBatch();\n }\n\n return result;\n } finally {\n setIsSigning(false);\n }\n }, [queue, client, clearBatch, providerIdentity]);\n\n const value: BatchQueueContextValue = {\n queue,\n batchChainId,\n addToBatch,\n removeFromBatch,\n clearBatch,\n signAll,\n isExpanded,\n setExpanded,\n isSigning,\n animationTrigger,\n };\n\n return (\n <BatchQueueContext.Provider value={value}>\n {children}\n </BatchQueueContext.Provider>\n );\n}\n","/**\n * @file Floating UI widget for the 1auth batch transaction queue.\n *\n * Renders a fixed-position card anchored to the bottom-right of the viewport\n * that shows how many calls are queued and on which chain. The widget is\n * invisible while the queue is empty and mounts itself into the React tree\n * wherever `BatchQueueProvider` wraps the application.\n *\n * CSS keyframe animations are injected into `document.head` once on mount\n * via {@link injectStyles} so that no stylesheet import is required from the\n * consumer's bundler.\n */\n\nimport * as React from \"react\";\nimport { useBatchQueue, getChainName } from \"./BatchQueueContext\";\n\n// batch-bounce-in: played on the whole widget when a new call is added to the\n// queue — a subtle scale pop that draws attention without being distracting.\n// batch-item-bounce: reserved for future per-item jiggle feedback (not\n// currently triggered by default, available via inline animation assignment).\nconst ANIMATION_STYLES = `\n@keyframes batch-bounce-in {\n 0% { transform: scale(0.8); opacity: 0; }\n 50% { transform: scale(1.05); }\n 100% { transform: scale(1); opacity: 1; }\n}\n@keyframes batch-item-bounce {\n 0%, 100% { transform: translateX(0); }\n 25% { transform: translateX(-2px); }\n 75% { transform: translateX(2px); }\n}\n`;\n\n/**\n * Inject the widget's CSS keyframe animations into `document.head`.\n *\n * Uses a stable element ID (`\"batch-queue-widget-styles\"`) as a guard so the\n * style tag is only inserted once even if the component mounts multiple times\n * (e.g. during React strict-mode double-invocation or hot reloads). No-ops in\n * non-browser environments (SSR/Node) where `document` is undefined.\n */\nfunction injectStyles() {\n if (typeof document === \"undefined\") return;\n const styleId = \"batch-queue-widget-styles\";\n if (document.getElementById(styleId)) return;\n\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.textContent = ANIMATION_STYLES;\n document.head.appendChild(style);\n}\n\n// Fixed bottom-right positioning keeps the widget out of the page flow so it\n// never displaces content. z-index 50 sits above typical page elements but\n// below full-screen modals (which usually start at 100+).\nconst widgetStyles: React.CSSProperties = {\n position: \"fixed\",\n bottom: \"16px\",\n right: \"16px\",\n zIndex: 50,\n backgroundColor: \"#18181b\",\n color: \"#ffffff\",\n borderRadius: \"12px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.3)\",\n minWidth: \"240px\",\n maxWidth: \"360px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n fontSize: \"14px\",\n overflow: \"hidden\",\n};\n\nconst headerStyles: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"12px 16px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n};\n\nconst headerLeftStyles: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\nconst counterBadgeStyles: React.CSSProperties = {\n backgroundColor: \"#ffffff\",\n color: \"#18181b\",\n borderRadius: \"9999px\",\n padding: \"2px 8px\",\n fontSize: \"12px\",\n fontWeight: 600,\n};\n\nconst chainBadgeStyles: React.CSSProperties = {\n backgroundColor: \"rgba(255,255,255,0.15)\",\n color: \"#a1a1aa\",\n borderRadius: \"4px\",\n padding: \"2px 6px\",\n fontSize: \"11px\",\n};\n\nconst signAllButtonStyles: React.CSSProperties = {\n backgroundColor: \"#ffffff\",\n color: \"#18181b\",\n border: \"none\",\n borderRadius: \"6px\",\n padding: \"6px 12px\",\n fontSize: \"13px\",\n fontWeight: 500,\n cursor: \"pointer\",\n transition: \"background-color 0.15s\",\n};\n\nconst signAllButtonHoverStyles: React.CSSProperties = {\n backgroundColor: \"#e4e4e7\",\n};\n\nconst signAllButtonDisabledStyles: React.CSSProperties = {\n opacity: 0.5,\n cursor: \"not-allowed\",\n};\n\nconst listContainerStyles: React.CSSProperties = {\n maxHeight: \"300px\",\n overflowY: \"auto\",\n borderTop: \"1px solid #27272a\",\n};\n\nconst callItemStyles: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"flex-start\",\n padding: \"10px 16px\",\n borderBottom: \"1px solid #27272a\",\n position: \"relative\",\n};\n\nconst callItemLastStyles: React.CSSProperties = {\n borderBottom: \"none\",\n};\n\nconst callContentStyles: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\nconst callLabelStyles: React.CSSProperties = {\n fontWeight: 500,\n marginBottom: \"2px\",\n};\n\nconst callSublabelStyles: React.CSSProperties = {\n color: \"#a1a1aa\",\n fontSize: \"12px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n};\n\nconst removeButtonStyles: React.CSSProperties = {\n position: \"absolute\",\n left: \"8px\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n backgroundColor: \"#dc2626\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: \"4px\",\n width: \"20px\",\n height: \"20px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n fontSize: \"14px\",\n opacity: 0,\n transition: \"opacity 0.15s\",\n};\n\nconst removeButtonVisibleStyles: React.CSSProperties = {\n opacity: 1,\n};\n\nconst clearButtonStyles: React.CSSProperties = {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n backgroundColor: \"transparent\",\n color: \"#a1a1aa\",\n border: \"none\",\n borderTop: \"1px solid #27272a\",\n fontSize: \"12px\",\n cursor: \"pointer\",\n textAlign: \"center\",\n transition: \"color 0.15s\",\n};\n\nconst clearButtonHoverStyles: React.CSSProperties = {\n color: \"#ffffff\",\n};\n\n/**\n * Animated chevron arrow used as the expand/collapse indicator in the widget\n * header. Points downward when the list is expanded and rotates 90° counter-\n * clockwise (points right) when collapsed, providing a clear affordance for\n * the toggle action.\n *\n * @param down - `true` when the queue list is expanded (chevron points down).\n */\nfunction ChevronIcon({ down }: { down: boolean }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transition: \"transform 0.2s\",\n transform: down ? \"rotate(0deg)\" : \"rotate(-90deg)\",\n }}\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nexport interface BatchQueueWidgetProps {\n /** Callback when \"Sign All\" is clicked. */\n onSignAll: () => void;\n}\n\n/**\n * Floating widget that displays the current batch transaction queue.\n *\n * Renders nothing while the queue is empty. When calls are present it shows a\n * fixed card in the bottom-right corner of the viewport with:\n * - A count badge and optional chain name in the header.\n * - A \"Sign All\" button that invokes `onSignAll` to begin the signing ceremony.\n * - An expandable list of queued calls with per-item remove buttons revealed\n * on hover and a \"Clear batch\" footer to discard all pending calls at once.\n *\n * A brief scale animation (`batch-bounce-in`) plays each time a new call is\n * added to the queue to draw the user's attention without interrupting flow.\n *\n * Must be rendered inside a `BatchQueueProvider`.\n *\n * @param props.onSignAll - Called when the user clicks \"Sign All\". The\n * implementor is responsible for resolving the account identity and passing\n * it to `useBatchQueue().signAll({ accountAddress, username })`.\n */\nexport function BatchQueueWidget({ onSignAll }: BatchQueueWidgetProps) {\n const {\n queue,\n batchChainId,\n removeFromBatch,\n clearBatch,\n isExpanded,\n setExpanded,\n isSigning,\n animationTrigger,\n } = useBatchQueue();\n\n const [hoveredItemId, setHoveredItemId] = React.useState<string | null>(null);\n const [isSignAllHovered, setIsSignAllHovered] = React.useState(false);\n const [isClearHovered, setIsClearHovered] = React.useState(false);\n const [shouldAnimate, setShouldAnimate] = React.useState(false);\n\n // Inject CSS animations on mount\n React.useEffect(() => {\n injectStyles();\n }, []);\n\n // Trigger bounce animation when item is added\n React.useEffect(() => {\n if (animationTrigger > 0) {\n setShouldAnimate(true);\n const timer = setTimeout(() => setShouldAnimate(false), 300);\n return () => clearTimeout(timer);\n }\n }, [animationTrigger]);\n\n // Don't render if queue is empty\n if (queue.length === 0) {\n return null;\n }\n\n const handleHeaderClick = () => {\n setExpanded(!isExpanded);\n };\n\n const handleSignAllClick = (e: React.MouseEvent) => {\n e.stopPropagation(); // Don't toggle expand\n if (!isSigning) {\n onSignAll();\n }\n };\n\n const animatedWidgetStyles: React.CSSProperties = {\n ...widgetStyles,\n animation: shouldAnimate ? \"batch-bounce-in 0.3s ease-out\" : undefined,\n };\n\n const currentSignAllStyles: React.CSSProperties = {\n ...signAllButtonStyles,\n ...(isSignAllHovered && !isSigning ? signAllButtonHoverStyles : {}),\n ...(isSigning ? signAllButtonDisabledStyles : {}),\n };\n\n return (\n <div style={animatedWidgetStyles}>\n {/* Header - always visible */}\n <div style={headerStyles} onClick={handleHeaderClick}>\n <div style={headerLeftStyles}>\n <ChevronIcon down={isExpanded} />\n <span style={counterBadgeStyles}>{queue.length}</span>\n <span>call{queue.length !== 1 ? \"s\" : \"\"} queued</span>\n {batchChainId && (\n <span style={chainBadgeStyles}>{getChainName(batchChainId)}</span>\n )}\n </div>\n <button\n style={currentSignAllStyles}\n onClick={handleSignAllClick}\n onMouseEnter={() => setIsSignAllHovered(true)}\n onMouseLeave={() => setIsSignAllHovered(false)}\n disabled={isSigning}\n >\n {isSigning ? \"Signing...\" : \"Sign All\"}\n </button>\n </div>\n\n {/* Expanded list of calls */}\n {isExpanded && (\n <>\n <div style={listContainerStyles}>\n {queue.map((item, index) => {\n const isHovered = hoveredItemId === item.id;\n const isLast = index === queue.length - 1;\n\n return (\n <div\n key={item.id}\n style={{\n ...callItemStyles,\n ...(isLast ? callItemLastStyles : {}),\n paddingLeft: isHovered ? \"36px\" : \"16px\",\n transition: \"padding-left 0.15s\",\n }}\n onMouseEnter={() => setHoveredItemId(item.id)}\n onMouseLeave={() => setHoveredItemId(null)}\n >\n <button\n style={{\n ...removeButtonStyles,\n ...(isHovered ? removeButtonVisibleStyles : {}),\n }}\n onClick={() => removeFromBatch(item.id)}\n title=\"Remove from batch\"\n >\n ×\n </button>\n <div style={callContentStyles}>\n <div style={callLabelStyles}>\n {item.call.label || \"Contract Call\"}\n </div>\n {item.call.sublabel && (\n <div style={callSublabelStyles}>{item.call.sublabel}</div>\n )}\n {!item.call.sublabel && item.call.to && (\n <div style={callSublabelStyles}>\n To: {item.call.to.slice(0, 6)}...{item.call.to.slice(-4)}\n </div>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Clear batch button */}\n <button\n style={{\n ...clearButtonStyles,\n ...(isClearHovered ? clearButtonHoverStyles : {}),\n }}\n onClick={clearBatch}\n onMouseEnter={() => setIsClearHovered(true)}\n onMouseLeave={() => setIsClearHovered(false)}\n >\n Clear batch\n </button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["balances","result","next","prepareResult","signingResult","dialogOrigin","closeOn","successStatuses","dialog","iframe","hashMessage","hashTypedData","toAccount","hashMessage","hashTypedData","toAccount","getChainName","React","jsx","getChainName"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/assets.ts","../../loading-tokens/src/index.ts","../src/permissions.ts","../src/crossChainPermissions.ts","../src/connection.ts","../src/account.ts","../src/walletClient/index.ts","../src/batch/BatchQueueContext.tsx","../src/batch/BatchQueueWidget.tsx"],"sourcesContent":["/**\n * OneAuthClient — the primary entry point for the @rhinestone/1auth SDK.\n *\n * Manages all communication between an integrating app and the 1auth passkey\n * service (apps/passkey). Interactions happen in two ways:\n *\n * 1. HTTP — direct REST calls to the passkey service API for non-interactive\n * operations such as intent preparation, status polling, and consent checks.\n *\n * 2. PostMessage — iframe/popup dialogs hosted at the passkey domain handle\n * WebAuthn ceremonies and return results to the parent page.\n *\n * Supported flows:\n * - Authentication (sign in / sign up) via modal, popup, or redirect\n * - Passkey challenge signing for off-chain login\n * - EIP-712 typed data signing\n * - Cross-chain intents via the Rhinestone orchestrator\n * - Batch intents (multiple chains, single passkey tap)\n * - Data consent management\n */\nimport { hashTypedData, type TypedDataDefinition } from \"viem\";\nimport { fetchAssetsResponse } from \"./assets\";\nimport { tokenFetchError } from \"./sponsorship-fetch\";\nimport type {\n AssetsResponse,\n PasskeyProviderConfig,\n SigningRequestOptions,\n SigningResult,\n CreateSigningRequestResponse,\n SigningRequestStatus,\n SigningErrorCode,\n EmbedOptions,\n UserPasskeysResponse,\n PasskeyCredential,\n AuthResult,\n AuthFlow,\n AuthWithModalOptions,\n LoginWithModalOptions,\n CreateAccountWithModalOptions,\n ConnectResult,\n AuthenticateOptions,\n AuthenticateResult,\n IntentCall,\n SendIntentOptions,\n SendIntentResult,\n PrepareIntentResponse,\n ExecuteIntentResponse,\n WebAuthnSignature,\n ThemeConfig,\n SignMessageOptions,\n SignMessageResult,\n SignTypedDataOptions,\n SignTypedDataResult,\n IntentHistoryOptions,\n IntentHistoryResult,\n GetAssetsOptions,\n SendBatchIntentOptions,\n SendBatchIntentResult,\n PrepareBatchIntentResponse,\n BatchIntentItemResult,\n CheckConsentOptions,\n CheckConsentResult,\n RequestConsentOptions,\n RequestConsentResult,\n GrantPermissionsOptions,\n GrantPermissionsResult,\n ListSessionGrantsOptions,\n ListSessionGrantsResult,\n SponsorshipConfig,\n SponsorshipCallbackConfig,\n OneAuthTelemetryAttributes,\n OneAuthTelemetryEvent,\n OneAuthTelemetryEventName,\n OneAuthTelemetryFlow,\n OneAuthTelemetryTraceContext,\n} from \"./types\";\nimport {\n BRAND_PURPLE,\n DARK_TOKENS,\n LIGHT_TOKENS,\n LOADING_BODY_GAP,\n LOADING_FONT_FAMILY,\n LOADING_ICON_PADDING,\n LOADING_LINE_HEIGHT,\n LOADING_MODAL_PADDING,\n LOADING_MODAL_RADIUS,\n LOADING_MODAL_WIDTH,\n LOADING_SUBTITLE,\n LOADING_SUBTITLE_FONT_SIZE,\n LOADING_SUBTITLE_FONT_WEIGHT,\n LOADING_TITLE,\n LOADING_TITLE_BLOCK_GAP,\n LOADING_TITLE_FONT_SIZE,\n LOADING_TITLE_FONT_WEIGHT,\n SPINNER_ARC,\n SPINNER_CIRCUMFERENCE,\n SPINNER_RADIUS,\n SPINNER_SIZE,\n SPINNER_SPIN_DURATION_MS,\n SPINNER_STROKE,\n} from \"@1auth/loading-tokens\";\n\n// Modal width is derived from LOADING_MODAL_WIDTH (single source of truth,\n// owned by `@1auth/loading-tokens`). Changing the width here in isolation\n// would let popup/iframe drift from the Figma spec; keep them tied.\nconst POPUP_WIDTH = LOADING_MODAL_WIDTH;\nconst POPUP_HEIGHT = 600;\nconst DEFAULT_EMBED_WIDTH = `${LOADING_MODAL_WIDTH}px`;\nconst DEFAULT_EMBED_HEIGHT = \"500px\";\nconst DEFAULT_PROVIDER_URL = \"https://passkey.1auth.app\";\n\n/**\n * Return the embedding page origin when the SDK is running in a browser.\n * The dialog uses this only for first-paint attribution and postMessage\n * targeting; authenticated server-side origin decisions still use browser\n * provided referrer/event.origin values inside the passkey app.\n */\nfunction currentWindowOrigin(): string | null {\n if (typeof window === \"undefined\") return null;\n const origin = window.location?.origin;\n return typeof origin === \"string\" && origin.length > 0 ? origin : null;\n}\n\n/**\n * Add the host origin to a dialog URL so the iframe can render the origin pill\n * on its first client render instead of waiting for PASSKEY_INIT or\n * document.referrer effects. Kept as a URL hint, not an authorization signal.\n */\nfunction appendParentOriginParam(params: URLSearchParams): void {\n const origin = currentWindowOrigin();\n if (origin) params.set(\"parentOrigin\", origin);\n}\n\n// Max characters for IntentCall.label / .sublabel before the SDK truncates\n// with an ellipsis. The sign dialog renders these in a ~200–260px column at\n// text-[16px] bold (see SignDialogBody.tsx TokenMovementCard). At that font\n// you fit ~17 typical chars; 20 is a forgiving cap that still avoids wrapping\n// for most strings while letting CSS `truncate` handle the worst-case fonts\n// as a safety net.\nconst MAX_LABEL_LEN = 20;\n\n// Default scrim appearance — preserved verbatim from the pre-`backdrop`-option\n// behavior so apps that never set `theme.backdrop` see no change. The dialog\n// (apps/passkey) uses the identical defaults for its in-iframe scrim.\nconst DEFAULT_BACKDROP_COLOR = \"#000000\";\nconst DEFAULT_BACKDROP_OPACITY = 0.4;\nconst DEFAULT_BACKDROP_BLUR = 8;\n// Only `#rrggbb` is allowed — same hard restriction the dialog applies to the\n// accent color (apps/passkey/src/lib/dialog-messages.ts ACCENT_RE). The value\n// is interpolated into a stylesheet string below, so anything looser (named\n// colors, `rgb()`, escapes) could become a CSS-injection vector.\nconst HEX_COLOR_RE = /^#[0-9a-fA-F]{6}$/;\n\n/**\n * Resolve the scrim tint (as an `rgba(...)` string) and blur radius (px) for\n * the SDK loading overlay from the dialog URL's `backdrop*` query params.\n *\n * The overlay is painted by the SDK on the host page before the iframe renders\n * (see {@link OneAuthClient.createModalDialog}); it must match the in-iframe\n * scrim the passkey app paints afterward so the host→iframe handoff is\n * seamless. Both sides read the same params and clamp identically.\n *\n * Every field falls back to its default independently and invalid/out-of-range\n * values are coerced back to the default, so a malformed param can never\n * produce a broken `background`/`backdrop-filter` declaration.\n */\nexport function resolveBackdropStyle(params: URLSearchParams): {\n background: string;\n blur: number;\n} {\n const rawColor = params.get(\"backdropColor\");\n const hex = (rawColor && HEX_COLOR_RE.test(rawColor) ? rawColor : DEFAULT_BACKDROP_COLOR).slice(1);\n const r = parseInt(hex.slice(0, 2), 16);\n const g = parseInt(hex.slice(2, 4), 16);\n const b = parseInt(hex.slice(4, 6), 16);\n\n // Parse a numeric param back to its default when the field is absent.\n // `URLSearchParams.get` returns null for omitted params and \"\" for empty\n // ones, and `Number(null) === Number(\"\") === 0` — which passes\n // `Number.isFinite`. Guarding on the raw value first keeps an omitted\n // `backdropOpacity`/`backdropBlur` on its historical default (0.4 / 8px)\n // instead of collapsing to a fully-transparent, unblurred overlay. An\n // explicit \"0\" is still a real, finite value and is honored.\n const clampNumber = (key: string, min: number, max: number, fallback: number): number => {\n const raw = params.get(key);\n if (!raw) return fallback;\n const n = Number(raw);\n return Number.isFinite(n) ? Math.min(max, Math.max(min, n)) : fallback;\n };\n\n const opacity = clampNumber(\"backdropOpacity\", 0, 1, DEFAULT_BACKDROP_OPACITY);\n const blur = clampNumber(\"backdropBlur\", 0, 40, DEFAULT_BACKDROP_BLUR);\n\n return { background: `rgba(${r}, ${g}, ${b}, ${opacity})`, blur };\n}\n\n/**\n * Generate a unique nonce for a single modal session. Used by\n * `waitForModalAuthResponse` (and any other per-modal message listener)\n * to reject stale CLOSE / RESULT messages that a previous, already\n * cleaned-up iframe queued before its teardown — without the nonce the\n * new modal's listener would process the stale event and silently cancel\n * the fresh auth attempt. `crypto.randomUUID` is available in every\n * browser this SDK targets; fall back to a Math.random pair so non-\n * conformant environments don't throw at construction time.\n */\nfunction generateModalNonce(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;\n}\n\ntype TelemetryOperation = {\n operationId: string;\n flow: OneAuthTelemetryFlow;\n startedAt: number;\n trace?: OneAuthTelemetryTraceContext;\n attributes?: OneAuthTelemetryAttributes;\n};\n\ntype TelemetryEventPatch = Partial<\n Omit<OneAuthTelemetryEvent, \"name\" | \"operationId\" | \"flow\" | \"timestamp\">\n>;\n\n/**\n * Generate a stable correlation id for one SDK operation. It is intentionally\n * opaque and random so it can be logged safely without leaking user data.\n */\nfunction generateTelemetryOperationId(): string {\n return `1auth-${generateModalNonce()}`;\n}\n\n/**\n * Keep telemetry attributes JSON/log friendly. Undefined values are dropped so\n * callbacks and headers do not need to normalize SDK-produced objects.\n */\nfunction cleanTelemetryAttributes(\n attributes: OneAuthTelemetryAttributes | undefined,\n): OneAuthTelemetryAttributes | undefined {\n if (!attributes) return undefined;\n const clean: OneAuthTelemetryAttributes = {};\n for (const [key, value] of Object.entries(attributes)) {\n if (value !== undefined) clean[key] = value;\n }\n return Object.keys(clean).length > 0 ? clean : undefined;\n}\n\n/**\n * Extract a consistent code/message pair from SDK result errors or thrown\n * exceptions without assuming a specific error class.\n */\nfunction describeTelemetryError(error: unknown): {\n errorCode?: string;\n errorMessage?: string;\n} {\n if (!error) return {};\n if (error instanceof Error) {\n return { errorCode: error.name, errorMessage: error.message };\n }\n if (typeof error === \"object\") {\n const err = error as { code?: unknown; message?: unknown };\n return {\n errorCode: typeof err.code === \"string\" ? err.code : undefined,\n errorMessage: typeof err.message === \"string\" ? err.message : String(error),\n };\n }\n return { errorMessage: String(error) };\n}\n\n/**\n * Truncate an IntentCall's `label` / `sublabel` to fit the sign dialog's\n * single-line label column. Returns the same call shape with capped strings;\n * leaves all other fields (to, data, value, icon) untouched. Returns the\n * input unchanged when `calls` is undefined or empty.\n *\n * The dialog also applies `truncate` CSS as a defense-in-depth measure — this\n * SDK cap exists so the request on the wire matches what the user sees, and\n * so apps can tell their label was too long (the truncated form ships).\n */\nfunction capCallLabels(calls: IntentCall[] | undefined): IntentCall[] | undefined {\n if (!calls) return calls;\n return calls.map((c) => {\n const cappedLabel =\n c.label && c.label.length > MAX_LABEL_LEN\n ? c.label.slice(0, MAX_LABEL_LEN - 1) + \"…\"\n : c.label;\n const cappedSublabel =\n c.sublabel && c.sublabel.length > MAX_LABEL_LEN\n ? c.sublabel.slice(0, MAX_LABEL_LEN - 1) + \"…\"\n : c.sublabel;\n if (cappedLabel === c.label && cappedSublabel === c.sublabel) return c;\n return { ...c, label: cappedLabel, sublabel: cappedSublabel };\n });\n}\n\n/**\n * Reads the `signerType` from the stored session in localStorage. Absent or\n * malformed storage falls back to `\"passkey\"` so existing installs remain\n * backwards compatible.\n */\nfunction getStoredSignerType(): \"passkey\" | \"eoa\" {\n if (typeof window === \"undefined\") return \"passkey\";\n try {\n const raw = window.localStorage.getItem(\"1auth-user\");\n if (!raw) return \"passkey\";\n const parsed = JSON.parse(raw) as { signerType?: \"passkey\" | \"eoa\" };\n return parsed?.signerType === \"eoa\" ? \"eoa\" : \"passkey\";\n } catch {\n return \"passkey\";\n }\n}\n\ntype NormalizedPasskeyProviderConfig = PasskeyProviderConfig & {\n providerUrl: string;\n dialogUrl: string;\n};\n\ntype BlindSigningOption = { blind_signing?: boolean };\n\n/**\n * Global default for blind signing, used when neither the per-call option nor\n * the client config expresses a preference.\n *\n * `true` means apps get blind signing out of the box and must *opt in* to\n * 1auth's visible review UI (clear signing) by passing `blind_signing: false`\n * on the client or per call. This is the single switch for the rollout: when\n * we're ready to change the platform-wide default, flip this one constant —\n * every app that hasn't set its own preference follows it.\n */\nconst DEFAULT_BLIND_SIGNING = true;\n\ntype SponsorshipTokens = { accessToken: string; extensionTokens: string[] };\n\ntype AccessTokenFetchResult =\n | { ok: true; accessToken: string }\n | { ok: false; code?: \"MISSING_APP_CREDENTIALS\"; message: string };\n\ntype ExtensionTokensFetchResult =\n | { ok: true; extensionTokens: string[] }\n | { ok: false; message: string };\n\nconst MISSING_APP_CREDENTIALS_MESSAGE =\n \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — pass `sponsorship: { accessToken, getExtensionToken }` (or URL form) to the constructor.\";\n\n/**\n * Normalize any `SponsorshipConfig` shape to the internal callback form.\n *\n * The URL form is a thin convenience — it gets wrapped into callbacks that\n * hit the app's own endpoints. Using same-origin URLs is recommended so the\n * browser forwards session cookies and the app can authenticate the user\n * server-side before minting a sponsorship grant.\n *\n * The access-token endpoint is GET and returns `{ token }`. The extension-\n * token endpoint is POST `{ intentOp }` and returns `{ token }`.\n */\nfunction normalizeSponsorship(\n config: SponsorshipConfig | undefined,\n): SponsorshipCallbackConfig | null {\n if (!config) return null;\n if (\"accessToken\" in config && \"getExtensionToken\" in config) {\n return config;\n }\n const { accessTokenUrl, extensionTokenUrl } = config;\n return {\n accessToken: async () => {\n const response = await fetch(accessTokenUrl, { credentials: \"include\" });\n if (!response.ok) {\n throw await tokenFetchError(\"access token\", response);\n }\n const data = (await response.json()) as { token?: string };\n if (!data.token) {\n throw new Error(\"Access token response missing `token` field\");\n }\n return data.token;\n },\n getExtensionToken: async (intentOp: string) => {\n const response = await fetch(extensionTokenUrl, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ intentOp }),\n });\n if (!response.ok) {\n throw await tokenFetchError(\"extension token\", response);\n }\n const data = (await response.json()) as { token?: string };\n if (!data.token) {\n throw new Error(\"Extension token response missing `token` field\");\n }\n return data.token;\n },\n };\n}\n\n/**\n * JSON.stringify replacer for grant-permission payloads. Session policy\n * helpers naturally use bigint values, but postMessage payloads must be\n * structured-clone friendly across browsers and JSON-safe for server calls.\n */\nfunction grantPermissionReplacer(_key: string, value: unknown): unknown {\n return typeof value === \"bigint\" ? value.toString() : value;\n}\n\nfunction cloneGrantPayload<T>(value: T): T {\n return JSON.parse(JSON.stringify(value, grantPermissionReplacer)) as T;\n}\n\nfunction normalizeGrantTargetChains(options: GrantPermissionsOptions): number[] {\n const chainCandidates = options.targetChains ?? (\n options.targetChain !== undefined ? [options.targetChain] : []\n );\n return Array.from(new Set(chainCandidates));\n}\n\nfunction normalizeGrantSourceChains(options: GrantPermissionsOptions): number[] {\n return Array.from(new Set(options.sourceChains ?? []));\n}\n\nexport class OneAuthClient {\n private config: NormalizedPasskeyProviderConfig;\n private theme: ThemeConfig;\n private sponsorship: SponsorshipCallbackConfig | null;\n // Persistent state for EOA forwarding via `/dialog/sign-eoa`. The iframe\n // is created lazily on the first `requestWithWallet` call and reused for\n // every subsequent call so its WalletConnect SignClient survives between\n // transactions — otherwise each call would spin up a fresh SignClient\n // that restores stale relay state from localStorage, producing\n // \"Restore will override\" warnings and \"emitting session_request:N\n // without any listeners\" errors on the second and later txs.\n private eoaDialogState: {\n dialog: HTMLDialogElement;\n iframe: HTMLIFrameElement;\n } | null = null;\n // Hidden iframe that warms the dialog ahead of the first real open (see\n // `prewarm()`). The passkey app runs on a long-lived server (not serverless),\n // so there is no backend cold-start to hide — what stays expensive is the\n // *browser-side* cost of a freshly created cross-origin iframe: downloading\n // the dialog HTML + JS bundle, parsing it, hydrating React, and loading the\n // font. Loading that bundle once into a parked hidden iframe lets the real\n // open hit the HTTP cache (Next.js chunks/fonts are immutable-cached) over an\n // already-warm connection, so the SDK preload overlay is shown only briefly.\n private prewarmState: {\n iframe: HTMLIFrameElement;\n ready: Promise<boolean>;\n } | null = null;\n // Serialises concurrent `requestWithWallet` calls — they would otherwise\n // both try to drive the same iframe and cross-resolve each other.\n private eoaSerialQueue: Promise<unknown> = Promise.resolve();\n\n /**\n * Create a new OneAuthClient.\n *\n * Normalizes the config (filling in default URLs), then immediately injects\n * `<link rel=\"preconnect\">` tags for the passkey domain so that DNS lookup\n * and TLS handshake start before the first dialog is opened, shaving\n * noticeable latency from the first user interaction.\n *\n * @param config - Client configuration including optional providerUrl, dialogUrl,\n * clientId, theme, and redirect settings.\n */\n constructor(config: PasskeyProviderConfig) {\n const providerUrl = config.providerUrl || DEFAULT_PROVIDER_URL;\n const dialogUrl = config.dialogUrl || providerUrl;\n this.config = { ...config, providerUrl, dialogUrl };\n this.theme = this.config.theme || {};\n this.sponsorship = normalizeSponsorship(config.sponsorship);\n\n // Pre-warm DNS + TLS connections to passkey domain\n if (typeof document !== \"undefined\") {\n this.injectPreconnect(providerUrl);\n if (dialogUrl !== providerUrl) {\n this.injectPreconnect(dialogUrl);\n }\n // Opt-in deeper warming: load the dialog bundle into a hidden iframe once\n // the main thread is idle so it never competes with the host app's own\n // first paint. Errors are swallowed — prewarm is best-effort.\n if (this.config.prewarm) {\n const warm = () => void this.prewarm();\n const ric = (window as Window & {\n requestIdleCallback?: (cb: () => void, opts?: { timeout: number }) => void;\n }).requestIdleCallback;\n if (typeof ric === \"function\") {\n ric(warm, { timeout: 2000 });\n } else {\n setTimeout(warm, 200);\n }\n }\n }\n\n const initOperation = this.createTelemetryOperation(\"client\", {\n hasClientId: !!this.config.clientId,\n hasDialogUrlOverride: dialogUrl !== providerUrl,\n });\n this.emitTelemetry(\"client.init\", initOperation, { outcome: \"started\" });\n }\n\n /**\n * Update the sponsorship configuration at runtime. Pass `undefined` to\n * disable sponsorship.\n */\n setSponsorship(sponsorship: SponsorshipConfig | undefined): void {\n this.sponsorship = normalizeSponsorship(sponsorship);\n }\n\n /**\n * Whether the caller opted into SDK telemetry propagation or callbacks.\n */\n private shouldUseTelemetry(): boolean {\n return !!this.config.telemetry && this.config.telemetry.enabled !== false;\n }\n\n /**\n * Resolve the host app's current trace context. Callback failures are\n * ignored because observability can never be allowed to break signing.\n */\n private getTelemetryTraceContext(): OneAuthTelemetryTraceContext | undefined {\n const traceContext = this.config.telemetry?.traceContext;\n if (!traceContext || !this.shouldUseTelemetry()) return undefined;\n try {\n return typeof traceContext === \"function\" ? traceContext() : traceContext;\n } catch {\n return undefined;\n }\n }\n\n /**\n * Resolve host-provided SDK event attributes and remove undefined fields.\n */\n private getTelemetryAttributes(): OneAuthTelemetryAttributes | undefined {\n const attributes = this.config.telemetry?.attributes;\n if (!attributes || !this.shouldUseTelemetry()) return undefined;\n try {\n const resolved = typeof attributes === \"function\" ? attributes() : attributes;\n return cleanTelemetryAttributes(resolved);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Create per-operation telemetry context shared by callbacks, HTTP headers,\n * dialog URL params, and PASSKEY_INIT messages.\n */\n private createTelemetryOperation(\n flow: OneAuthTelemetryFlow,\n attributes?: OneAuthTelemetryAttributes,\n ): TelemetryOperation {\n return {\n operationId: generateTelemetryOperationId(),\n flow,\n startedAt: Date.now(),\n trace: this.getTelemetryTraceContext(),\n attributes: cleanTelemetryAttributes({\n ...this.getTelemetryAttributes(),\n ...attributes,\n }),\n };\n }\n\n /**\n * Emit a telemetry event to the host app. The callback is intentionally\n * fire-and-forget and exception-safe so app telemetry cannot affect users.\n */\n private emitTelemetry(\n name: OneAuthTelemetryEventName,\n operation: TelemetryOperation,\n patch: TelemetryEventPatch = {},\n ): void {\n const onEvent = this.config.telemetry?.onEvent;\n if (!onEvent || !this.shouldUseTelemetry()) return;\n\n const attributes = cleanTelemetryAttributes({\n ...operation.attributes,\n ...patch.attributes,\n });\n const event: OneAuthTelemetryEvent = {\n name,\n operationId: operation.operationId,\n flow: operation.flow,\n timestamp: new Date().toISOString(),\n durationMs: patch.durationMs ?? Date.now() - operation.startedAt,\n clientId: this.config.clientId,\n providerUrl: this.config.providerUrl,\n dialogUrl: this.getDialogUrl(),\n trace: operation.trace,\n ...patch,\n attributes,\n };\n\n try {\n onEvent(event);\n } catch {\n // Telemetry callbacks are intentionally isolated from SDK behavior.\n }\n }\n\n /**\n * Attach SDK correlation and optional W3C trace context to dialog URLs.\n */\n private appendTelemetryParams(\n params: URLSearchParams,\n operation: TelemetryOperation,\n ): void {\n if (!this.shouldUseTelemetry()) return;\n params.set(\"sdkOperationId\", operation.operationId);\n params.set(\"sdkTelemetryFlow\", operation.flow);\n if (operation.trace?.traceparent) {\n params.set(\"traceparent\", operation.trace.traceparent);\n }\n if (operation.trace?.tracestate) {\n params.set(\"tracestate\", operation.trace.tracestate);\n }\n if (operation.trace?.traceId) {\n params.set(\"sdkTraceId\", operation.trace.traceId);\n }\n if (operation.trace?.spanId) {\n params.set(\"sdkSpanId\", operation.trace.spanId);\n }\n }\n\n /**\n * Add SDK correlation headers to passkey API calls. These headers are also\n * valid W3C trace propagation inputs when the host app supplies traceparent.\n */\n private telemetryHeaders(operation?: TelemetryOperation): Record<string, string> {\n if (!operation || !this.shouldUseTelemetry()) return {};\n return {\n \"x-1auth-sdk-operation-id\": operation.operationId,\n \"x-1auth-sdk-flow\": operation.flow,\n ...(operation.trace?.traceparent ? { traceparent: operation.trace.traceparent } : {}),\n ...(operation.trace?.tracestate ? { tracestate: operation.trace.tracestate } : {}),\n };\n }\n\n /**\n * Embed telemetry context in PASSKEY_INIT payloads for dialog-side API calls.\n */\n private telemetryPayload(\n operation: TelemetryOperation,\n ): Record<string, string> | undefined {\n if (!this.shouldUseTelemetry()) return undefined;\n return {\n operationId: operation.operationId,\n flow: operation.flow,\n ...(operation.trace?.traceparent ? { traceparent: operation.trace.traceparent } : {}),\n ...(operation.trace?.tracestate ? { tracestate: operation.trace.tracestate } : {}),\n ...(operation.trace?.traceId ? { traceId: operation.trace.traceId } : {}),\n ...(operation.trace?.spanId ? { spanId: operation.trace.spanId } : {}),\n };\n }\n\n /**\n * Determine whether this signing call should request invisible dialog mode.\n * Resolution order: per-call option wins over the constructor config, which\n * wins over the platform-wide {@link DEFAULT_BLIND_SIGNING}. This lets an app\n * flip the global default for itself while still overriding individual\n * high-risk calls — e.g. default-blind but force the review UI for a large\n * transfer, or default-visible but blind-sign selected low-risk signatures.\n */\n private shouldRequestBlindSigning(options?: BlindSigningOption): boolean {\n return options?.blind_signing ?? this.config.blind_signing ?? DEFAULT_BLIND_SIGNING;\n }\n\n /**\n * Fetch the app's access token (JWT). Called up front, before\n * `/api/intent/prepare`, so the passkey server can authenticate the\n * orchestrator quote call with the app's JWT instead of a service-level\n * API key.\n *\n * Does not depend on `intentOp` — can run in parallel with anything that\n * also doesn't depend on the quote.\n */\n private async fetchAccessToken(): Promise<AccessTokenFetchResult> {\n if (!this.sponsorship) {\n return {\n ok: false,\n code: \"MISSING_APP_CREDENTIALS\",\n message: MISSING_APP_CREDENTIALS_MESSAGE,\n };\n }\n try {\n const accessToken = await this.sponsorship.accessToken();\n return { ok: true, accessToken };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /**\n * Fetch one extension token per intent, aligned with `sponsorFlags`.\n * Returns an empty array when no intent is sponsored. Fired after\n * `/prepare` so each token can be bound to its quote's `intentOp`, and\n * overlaps the dialog / WebAuthn ceremony for no added serial latency.\n */\n private async fetchExtensionTokens(\n intentOps: string[],\n sponsorFlags: boolean[],\n ): Promise<ExtensionTokensFetchResult> {\n if (!this.sponsorship) {\n return { ok: false, message: MISSING_APP_CREDENTIALS_MESSAGE };\n }\n const anySponsored = sponsorFlags.some(Boolean);\n if (!anySponsored) return { ok: true, extensionTokens: [] };\n try {\n const sponsorship = this.sponsorship;\n const tokens = await Promise.all(\n intentOps.map((op, i) =>\n sponsorFlags[i] ? sponsorship.getExtensionToken(op) : Promise.resolve(\"\"),\n ),\n );\n return { ok: true, extensionTokens: tokens };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n }\n\n /**\n * Update the theme configuration at runtime\n */\n setTheme(theme: ThemeConfig): void {\n this.theme = theme;\n }\n\n /**\n * Serialize the active theme into URL query parameters for the dialog.\n *\n * Merges the instance-level theme (set via constructor or `setTheme`) with any\n * per-call override, so callers can temporarily change the appearance for a\n * single dialog invocation without mutating shared state.\n *\n * @param overrideTheme - One-shot theme values that take precedence over the\n * instance theme for this call only.\n * @returns A URL-encoded query string (e.g. `\"theme=dark&accent=%230090ff\"`),\n * or an empty string if no theme properties are set.\n */\n private getThemeParams(overrideTheme?: ThemeConfig): string {\n const theme = { ...this.theme, ...overrideTheme };\n const params = new URLSearchParams();\n\n if (theme.mode) {\n params.set('theme', theme.mode);\n }\n // `primaryColor` is the documented name; `accent` is the legacy alias.\n // Resolve each layer independently before merging so that a per-call\n // override (either field) wins over the instance value (either field) —\n // a plain spread merge would let an instance `primaryColor` shadow a\n // per-call `accent`, breaking the documented \"overrides take precedence\"\n // contract while `accent` remains a back-compat alias.\n const instancePrimary = this.theme.primaryColor ?? this.theme.accent;\n const overridePrimary = overrideTheme?.primaryColor ?? overrideTheme?.accent;\n const primary = overridePrimary ?? instancePrimary;\n if (primary) {\n params.set('accent', primary);\n }\n\n // Backdrop (scrim) tint/blur. Each field is emitted only when present so\n // the dialog keeps its per-field defaults (black / 0.4 / 8px) for the\n // common case where the app sets none. The dialog re-validates and clamps\n // each value, so we pass them through verbatim here.\n const backdrop = theme.backdrop;\n if (backdrop) {\n if (backdrop.color) {\n params.set('backdropColor', backdrop.color);\n }\n if (backdrop.opacity !== undefined) {\n params.set('backdropOpacity', String(backdrop.opacity));\n }\n if (backdrop.blur !== undefined) {\n params.set('backdropBlur', String(backdrop.blur));\n }\n }\n\n return params.toString();\n }\n\n /**\n * Resolve the URL of the dialog app (the Vite/Next.js frontend that renders\n * the WebAuthn UI inside the iframe).\n *\n * `dialogUrl` is a separate config option to support split deployments where\n * the API server and the dialog frontend run at different origins. Falls back\n * to `providerUrl` when not explicitly configured — the common case.\n *\n * @returns The base URL used when constructing all dialog endpoint paths.\n */\n private getDialogUrl(): string {\n return this.config.dialogUrl || this.config.providerUrl;\n }\n\n /**\n * Extract the trusted origin used to validate incoming postMessage events.\n *\n * All `window.addEventListener(\"message\", ...)` handlers in this class check\n * `event.origin` against this value to prevent cross-origin spoofing. Wraps\n * `getDialogUrl()` in a `new URL()` parse so that paths and query strings are\n * stripped — only the scheme + host + port are compared.\n *\n * Falls back to the raw dialog URL string if URL parsing fails (e.g. during\n * unit tests with non-standard URL formats).\n *\n * @returns The scheme + host + optional port of the dialog app (e.g. `\"https://passkey.1auth.app\"`).\n */\n private getDialogOrigin(): string {\n const dialogUrl = this.getDialogUrl();\n try {\n return new URL(dialogUrl).origin;\n } catch {\n return dialogUrl;\n }\n }\n\n /**\n * Get the base provider URL\n */\n getProviderUrl(): string {\n return this.config.providerUrl;\n }\n\n /**\n * Get the configured client ID\n */\n getClientId(): string | undefined {\n return this.config.clientId;\n }\n\n /**\n * Whether this client operates on testnet chains only.\n */\n getTestnets(): boolean {\n return this.config.testnets ?? false;\n }\n\n /**\n * Get a unified token portfolio for a 1auth account across mainnets and\n * testnets.\n *\n * @example\n * ```typescript\n * const assets = await client.getAssets({\n * accountAddress: \"0x1111111111111111111111111111111111111111\",\n * });\n * console.log(assets.mainnets.balances, assets.testnets.balances);\n * ```\n */\n async getAssets(options: GetAssetsOptions): Promise<AssetsResponse> {\n if (!options.accountAddress) {\n throw new Error(\"getAssets requires accountAddress\");\n }\n\n const telemetry = this.createTelemetryOperation(\"assets\", {\n hasAccountAddress: !!options.accountAddress,\n });\n\n try {\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n throw new Error(accessTokenResult.message);\n }\n\n const result = await fetchAssetsResponse({\n providerUrl: this.config.providerUrl,\n identifier: options.accountAddress,\n clientId: this.config.clientId,\n accessToken: accessTokenResult.accessToken,\n headers: this.telemetryHeaders(telemetry),\n });\n this.emitTelemetry(\"assets.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n balanceCount: result.balances.length,\n mainnetBalanceCount: result.mainnets.balances.length,\n testnetBalanceCount: result.testnets.balances.length,\n },\n });\n return result;\n } catch (error) {\n this.emitTelemetry(\"assets.failed\", telemetry, {\n outcome: \"failure\",\n ...describeTelemetryError(error),\n });\n throw error;\n }\n }\n\n /**\n * Poll the intent status endpoint until a transaction hash appears or the\n * intent reaches a terminal failure state.\n *\n * This is used after `sendIntent` resolves (with `waitForHash: true`) to\n * continue waiting for the on-chain hash even after the dialog has been\n * dismissed. It is intentionally separate from the in-dialog polling loop so\n * callers that don't need the hash can skip it entirely.\n *\n * Errors during individual poll attempts are swallowed so that transient\n * network issues don't abort the wait prematurely.\n *\n * @param intentId - The Rhinestone intent ID returned by the execute endpoint.\n * @param options.timeoutMs - Maximum wait time in milliseconds (default 120 000).\n * @param options.intervalMs - Time between polls in milliseconds (default 2 000).\n * @returns The transaction hash string, or `undefined` if the deadline was\n * reached or the intent failed/expired before a hash was produced.\n */\n private async waitForTransactionHash(\n intentId: string,\n options: { timeoutMs?: number; intervalMs?: number } = {},\n telemetry?: TelemetryOperation,\n ): Promise<string | undefined> {\n const timeoutMs = options.timeoutMs ?? 120_000;\n const intervalMs = options.intervalMs ?? 2_000;\n const deadline = Date.now() + timeoutMs;\n\n while (Date.now() < deadline) {\n try {\n const response = await fetch(\n `${this.config.providerUrl}/api/intent/status/${intentId}`,\n {\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n }\n );\n if (response.ok) {\n const data = await response.json();\n if (data.transactionHash) {\n return data.transactionHash as string;\n }\n if (data.status === \"failed\" || data.status === \"expired\") {\n return undefined;\n }\n }\n } catch {\n // Keep polling until timeout.\n }\n\n await new Promise((resolve) => setTimeout(resolve, intervalMs));\n }\n\n return undefined;\n }\n\n /**\n * Open the authentication modal (sign in + sign up).\n *\n * Handles both new user registration and returning user login in a single\n * call — the modal shows the appropriate flow based on whether the user\n * has a passkey registered.\n *\n * @param options.theme - Override the theme for this modal invocation\n * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons\n * @param options.flow - Force the login or account-creation route instead\n * of the default auto-detect entry route\n * @returns {@link AuthResult} with user details and typed address\n *\n * @example\n * ```typescript\n * const result = await client.authWithModal();\n *\n * if (result.success) {\n * console.log('Signed in as:', result.user?.address);\n * console.log('Address:', result.user?.address); // typed `0x${string}`\n * } else if (result.error?.code === 'USER_CANCELLED') {\n * // User closed the modal\n * }\n * ```\n */\n async authWithModal(options?: AuthWithModalOptions): Promise<AuthResult> {\n return this.openAuthModal(options);\n }\n\n /**\n * Open the sign-in modal directly.\n *\n * This bypasses the `/dialog/auth` auto-router and targets the dedicated\n * returning-user flow. Use it when the embedding app already knows the user\n * is creating a login session, for example after an app-level \"Log in\"\n * button. The result intentionally matches {@link authWithModal}.\n *\n * @param options.theme - Override the theme for this modal invocation\n * @returns {@link AuthResult} with user details and typed address\n */\n async loginWithModal(options?: LoginWithModalOptions): Promise<AuthResult> {\n return this.openAuthModal({ ...options, flow: \"login\" });\n }\n\n /**\n * Open the account-creation modal directly.\n *\n * This bypasses the `/dialog/auth` auto-router and targets the dedicated\n * sign-up flow. Account creation still happens server-side in the passkey\n * service; the SDK only opens the dialog and receives the postMessage result.\n *\n * @param options.theme - Override the theme for this modal invocation\n * @param options.oauthEnabled - Set to false to hide OAuth sign-in buttons\n * @returns {@link AuthResult} with the newly authenticated account details\n */\n async createAccountWithModal(options?: CreateAccountWithModalOptions): Promise<AuthResult> {\n return this.openAuthModal({ ...options, flow: \"create-account\" });\n }\n\n /**\n * Open one of the passkey authentication modal routes and wait for the\n * login-result message.\n *\n * Keeping URL construction in one helper prevents the explicit login/signup\n * methods from drifting away from the legacy `authWithModal` behavior.\n */\n private async openAuthModal(options?: AuthWithModalOptions): Promise<AuthResult> {\n const telemetry = this.createTelemetryOperation(\"auth\", {\n flow: options?.flow ?? \"auto\",\n });\n const dialogUrl = this.getDialogUrl();\n const requestId = this.createDialogRequestId();\n const params = new URLSearchParams({\n mode: 'iframe',\n requestId,\n });\n if (this.config.clientId) {\n params.set('clientId', this.config.clientId);\n }\n if (options?.oauthEnabled === false) {\n params.set('oauth', '0');\n }\n if (options?.eoaConnect) {\n // Signals the dialog's wallet path to terminate as a pure EOA signer\n // session (plain tx, no intents) rather than wallet-assisted passkey\n // signup. Read by useSignupFlow and the wallet sub-routes.\n params.set('eoaConnect', '1');\n }\n if (options?.flow === \"create-account\") {\n // Explicit account creation must not be short-circuited by a stored\n // passkey-origin user; signup routes already treat switch=1 as that\n // \"show signup anyway\" signal.\n params.set('switch', '1');\n }\n // Seed first-paint attribution. The passkey app re-validates the actual\n // caller from document.referrer / PASSKEY_INIT before trusting it.\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n\n // Add theme params\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const authPath = this.getAuthDialogPath(options?.flow);\n const url = `${dialogUrl}${authPath}?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n this.emitTelemetry(\"dialog.opened\", telemetry, { outcome: \"started\" });\n const result = await this.waitForModalAuthResponse(dialog, iframe, cleanup, requestId);\n if (result.success) {\n this.emitTelemetry(\"auth.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { signerType: result.signerType ?? \"passkey\" },\n });\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"auth.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(result.error),\n },\n );\n }\n return result;\n }\n\n /**\n * Generate a per-dialog nonce used to correlate iframe close messages with\n * the SDK modal that opened them. Chromium can report a different\n * `MessageEvent.source` WindowProxy after the `/dialog/auth` redirect, so\n * auth close handling needs a stable in-band identifier without accepting\n * stale close messages from earlier dialogs.\n */\n private createDialogRequestId(): string {\n if (typeof crypto !== \"undefined\" && \"randomUUID\" in crypto) {\n return crypto.randomUUID();\n }\n return `dialog-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n\n /**\n * Resolve the passkey app route for a requested auth flow.\n */\n private getAuthDialogPath(flow: AuthFlow = \"auto\"): string {\n if (flow === \"login\") return \"/dialog/auth/signin\";\n if (flow === \"create-account\") return \"/dialog/auth/signup\";\n return \"/dialog/auth\";\n }\n\n /**\n * Open the connect dialog (lightweight connection without passkey auth).\n *\n * This method shows a simple connection confirmation dialog that doesn't\n * require a passkey signature. Users can optionally enable \"auto-connect\"\n * to skip this dialog in the future.\n *\n * If the user has never connected before, this will return action: \"switch\"\n * to indicate that the full auth modal should be opened instead.\n *\n * @example\n * ```typescript\n * const result = await client.connectWithModal();\n *\n * if (result.success) {\n * console.log('Connected as:', result.user?.address);\n * } else if (result.action === 'switch') {\n * // User needs to sign in first\n * const authResult = await client.authWithModal();\n * }\n * ```\n */\n async connectWithModal(options?: {\n theme?: ThemeConfig;\n }): Promise<ConnectResult> {\n const telemetry = this.createTelemetryOperation(\"connect\");\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: 'iframe',\n });\n if (this.config.clientId) {\n params.set('clientId', this.config.clientId);\n }\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n\n // Add theme params\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const url = `${dialogUrl}/dialog/connect?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n this.emitTelemetry(\"dialog.opened\", telemetry, { outcome: \"started\" });\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n telemetry: this.telemetryPayload(telemetry),\n });\n if (!ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"Connection was cancelled before the dialog became ready\",\n });\n return {\n success: false,\n action: \"cancel\",\n error: { code: \"USER_CANCELLED\", message: \"Connection was cancelled\" },\n };\n }\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n const result = await this.waitForConnectResponse(dialog, iframe, cleanup);\n if (result.success) {\n this.emitTelemetry(\"connect.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n autoConnected: result.autoConnected === true,\n signerType: result.signerType ?? \"passkey\",\n },\n });\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"connect.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(result.error),\n attributes: { action: result.action },\n },\n );\n }\n return result;\n }\n\n /**\n * High-level connect entry point — the method most integrators want.\n *\n * Tries the lightweight {@link connectWithModal} first (no passkey ceremony\n * for returning users on the same browser), and transparently falls back to\n * {@link authWithModal} when the connect dialog reports it has no stored\n * credentials for this origin (`action: \"switch\"`). First-time visitors get\n * one passkey ceremony to register; subsequent connects on the same browser\n * resolve with no biometric prompt — and silently when the user has enabled\n * \"Connect automatically\".\n *\n * The return shape is the same {@link ConnectResult} discriminated union as\n * {@link connectWithModal}, so callers can treat both paths uniformly. When\n * the auth-modal fallback runs, its successful result is normalized into a\n * `ConnectResult` (no `id` field — the embedder origin must not see it).\n *\n * Cancellation: if the user cancels either dialog, the result is\n * `{ success: false, action: \"cancel\", error: { code: \"USER_CANCELLED\", … } }`.\n *\n * @param options - Forwarded to whichever underlying modal is shown.\n * `oauthEnabled` only applies to the auth-modal fallback path.\n * @returns A {@link ConnectResult} discriminated union.\n *\n * @example\n * ```typescript\n * const result = await client.connect();\n * if (result.success) {\n * console.log(\"Connected as\", result.user?.address);\n * }\n * ```\n */\n async connect(options?: {\n theme?: ThemeConfig;\n oauthEnabled?: boolean;\n /**\n * Opt into \"wallet as signer\" mode for the auth-modal fallback — see\n * {@link AuthWithModalOptions.eoaConnect}. Set by {@link createOneAuthConnection}.\n */\n eoaConnect?: boolean;\n }): Promise<ConnectResult> {\n const connectResult = await this.connectWithModal(\n options?.theme ? { theme: options.theme } : undefined,\n );\n\n // Returning user / auto-connect / explicit confirm — done, no biometrics.\n if (connectResult.success) return connectResult;\n\n // First-time visitor or cleared storage: connect dialog can't prove the\n // user, so it asks the SDK to switch to the full auth modal.\n if (connectResult.action === \"switch\") {\n const authResult = await this.authWithModal(options);\n if (authResult.success && authResult.user) {\n return {\n success: true,\n user: {\n address: authResult.user.address,\n },\n // Preserve the signer type from the auth modal — a wallet-picked\n // (EOA) signup must not be silently normalized to \"passkey\", or the\n // provider would route its transactions through intents.\n signerType: authResult.signerType ?? \"passkey\",\n autoConnected: false,\n };\n }\n // Auth modal cancelled or errored — surface as a ConnectResult so callers\n // don't have to handle two error shapes.\n return {\n success: false,\n action: \"cancel\",\n error: authResult.error ?? {\n code: \"USER_CANCELLED\",\n message: \"Connection was cancelled\",\n },\n };\n }\n\n // User cancelled the connect dialog directly — pass through.\n return connectResult;\n }\n\n /**\n * Open the account management dialog.\n *\n * Shows the account overview with guardian status and recovery setup\n * options. The dialog closes when the user clicks the X button or\n * completes their action.\n *\n * @example\n * ```typescript\n * await client.openAccountDialog();\n * ```\n */\n async openAccountDialog(options?: {\n theme?: ThemeConfig;\n }): Promise<void> {\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: 'iframe',\n });\n\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const url = `${dialogUrl}/dialog/account?${params.toString()}`;\n\n // Guardian-setup and session-revoke inside the account dialog submit user\n // intents, which must carry the app's JWT. Fetch it and forward it in the\n // PASSKEY_INIT payload. Best-effort: if sponsorship isn't configured the\n // dialog still opens for read-only / backup actions, and the intent flows\n // surface a clear missing-authorization error rather than a cryptic\n // orchestrator 400.\n //\n // Fetch the token BEFORE creating the iframe: createModalDialog starts\n // loading the dialog, and the listener for its PASSKEY_READY is only\n // installed inside waitForDialogReady. Awaiting a network call between\n // those two would let a fast iframe post READY before the listener exists\n // (→ 10s timeout, dialog never opens). Resolving the token first keeps the\n // create→listen handoff synchronous, as it was originally.\n const accessTokenResult = await this.fetchAccessToken();\n const initMessage: Record<string, unknown> = { mode: \"iframe\" };\n if (accessTokenResult.ok) {\n initMessage.auth = { accessToken: accessTokenResult.accessToken };\n }\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, initMessage);\n if (!ready) return;\n\n // Wait for the dialog to close (no result needed)\n const dialogOrigin = this.getDialogOrigin();\n return new Promise<void>((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_CLOSE\" || event.data?.type === \"PASSKEY_DISCONNECT\") {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n cleanup();\n resolve();\n }\n };\n const handleClose = () => {\n window.removeEventListener(\"message\", handleMessage);\n resolve();\n };\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Open the account-recovery backup flow directly.\n *\n * Deep-links into the \"Backup your account\" flow inside the account dialog\n * (rather than the account overview): the user verifies with their passkey,\n * then saves a recovery passphrase and downloads an encrypted backup file.\n * Use this to prompt users to secure their account after sign-up.\n *\n * Requires an authenticated user (call `authWithModal()` / `connect()`\n * first) — the dialog reads the signed-in user from the passkey origin.\n *\n * Resolves `{ completed: true }` when the user finishes the backup, or\n * `{ completed: false }` if they dismiss it — so callers can mark an\n * onboarding step done or re-prompt later.\n */\n async setupRecovery(options?: {\n theme?: ThemeConfig;\n }): Promise<{ completed: boolean }> {\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: 'iframe',\n // Deep-link the account dialog straight into the backup nudge instead\n // of the account overview.\n action: 'backup',\n });\n\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n\n const url = `${dialogUrl}/dialog/account?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n });\n if (!ready) return { completed: false };\n\n const dialogOrigin = this.getDialogOrigin();\n return new Promise<{ completed: boolean }>((resolve) => {\n let completed = false;\n const finish = () => {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n cleanup();\n resolve({ completed });\n };\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n const type = event.data?.type;\n if (type === \"PASSKEY_RECOVERY_RESULT\") {\n // The dialog reports success right before closing; record it so the\n // subsequent PASSKEY_CLOSE resolves with completed: true.\n completed = Boolean(event.data?.data?.completed ?? event.data?.success);\n return;\n }\n if (type === \"PASSKEY_CLOSE\" || type === \"PASSKEY_DISCONNECT\") {\n finish();\n }\n };\n const handleClose = () => {\n window.removeEventListener(\"message\", handleMessage);\n resolve({ completed });\n };\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Check if a user has already granted consent for the requested fields.\n *\n * @deprecated Data-sharing consent is disabled.\n *\n * Always returns `{ hasConsent: false }`.\n */\n async checkConsent(options: CheckConsentOptions): Promise<CheckConsentResult> {\n void options;\n return { hasConsent: false };\n }\n\n /**\n * Request consent from the user to share their data.\n *\n * @deprecated Data-sharing consent is disabled.\n *\n * Always returns an `INVALID_REQUEST` result.\n */\n async requestConsent(options: RequestConsentOptions): Promise<RequestConsentResult> {\n void options;\n return {\n success: false,\n error: {\n code: \"INVALID_REQUEST\",\n message: \"Data-sharing consent is disabled\",\n },\n };\n }\n\n /**\n * Open the dedicated SmartSession permission grant dialog.\n *\n * The app owns the session key material and sends only the public\n * `sessionKeyAddress`. 1auth renders the permission review, collects the\n * owner's passkey authorization, submits the install/enable intent, and\n * returns a persistable session handle.\n */\n async grantPermissions(options: GrantPermissionsOptions): Promise<GrantPermissionsResult> {\n const telemetry = this.createTelemetryOperation(\"grant_permission\", {\n targetChains: normalizeGrantTargetChains(options).join(\",\"),\n sponsor: options.sponsor !== false,\n });\n if (!options.accountAddress) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"accountAddress is required\",\n });\n return {\n success: false,\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"accountAddress is required\",\n },\n };\n }\n const targetChains = normalizeGrantTargetChains(options);\n const sourceChains = normalizeGrantSourceChains(options);\n if (targetChains.length === 0 || !options.sessionKeyAddress || !options.permissions?.length) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"targetChains, sessionKeyAddress, and permissions are required\",\n });\n return {\n success: false,\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"targetChains, sessionKeyAddress, and permissions are required\",\n },\n };\n }\n if (!this.sponsorship) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"MISSING_APP_CREDENTIALS\",\n errorMessage: MISSING_APP_CREDENTIALS_MESSAGE,\n });\n return {\n success: false,\n error: {\n code: \"MISSING_APP_CREDENTIALS\",\n message: MISSING_APP_CREDENTIALS_MESSAGE,\n },\n };\n }\n\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n this.emitTelemetry(\"grant_permission.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: accessTokenResult.message,\n });\n return {\n success: false,\n error: {\n code: \"SPONSORSHIP_FETCH_FAILED\",\n message: accessTokenResult.message,\n },\n };\n }\n\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const grantUrl = `${dialogUrl}/dialog/grant-permission?${params.toString()}`;\n const { dialog, iframe, cleanup } = this.createModalDialog(grantUrl);\n const initPayload = {\n mode: \"iframe\",\n clientId: this.config.clientId,\n grant: cloneGrantPayload({\n accountAddress: options.accountAddress,\n targetChain: targetChains[0],\n targetChains,\n sourceChains,\n sessionKeyAddress: options.sessionKeyAddress,\n permissions: options.permissions,\n crossChainPermits: options.crossChainPermits,\n validUntil: options.validUntil,\n validAfter: options.validAfter,\n maxUses: options.maxUses,\n contracts: options.contracts,\n }),\n auth: { accessToken: accessTokenResult.accessToken },\n sponsor: options.sponsor !== false,\n telemetry: this.telemetryPayload(telemetry),\n };\n\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n targetChains,\n });\n const result = await this.waitForGrantPermissionResponse(\n dialog,\n iframe,\n cleanup,\n options.sponsor !== false,\n initPayload,\n );\n if (result.success) {\n this.emitTelemetry(\"grant_permission.succeeded\", telemetry, {\n outcome: \"success\",\n targetChains,\n status: result.status ? String(result.status) : undefined,\n });\n // The grant is already resolved; keep the dialog's \"Permission granted\"\n // success screen (green Done button) on screen until the user dismisses\n // it, then tear the iframe down. Without this the dialog would close the\n // instant the result arrived and the confirmation would never be seen —\n // unlike the sign flow, where sendIntent awaits the dialog close after a\n // confirmed signature.\n await this.waitForDialogClose(dialog, cleanup);\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"grant_permission.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n targetChains,\n ...describeTelemetryError(result.error),\n },\n );\n }\n return result;\n }\n\n /**\n * List SmartSession grants previously granted to the current browser origin.\n *\n * 1auth derives the app identity from the request Origin header. The SDK does\n * not send `clientId` for this lookup because grants are origin-scoped.\n */\n async listSessionGrants(\n options: ListSessionGrantsOptions,\n ): Promise<ListSessionGrantsResult> {\n if (!options.accountAddress) {\n return {\n success: false,\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"accountAddress is required\",\n },\n };\n }\n\n const params = new URLSearchParams();\n if (options.accountAddress) params.set(\"accountAddress\", options.accountAddress);\n if (options.includeRevoked) params.set(\"includeRevoked\", \"true\");\n\n try {\n const response = await fetch(\n `${this.config.providerUrl}/api/sessions/grants?${params.toString()}`,\n { credentials: \"include\" },\n );\n const data = await response.json();\n if (!response.ok) {\n return {\n success: false,\n error: {\n code: \"LIST_SESSION_GRANTS_FAILED\",\n message: data?.error ?? `Request failed with status ${response.status}`,\n },\n };\n }\n return { success: true, grants: data.grants ?? [] };\n } catch (err) {\n return {\n success: false,\n error: {\n code: \"LIST_SESSION_GRANTS_FAILED\",\n message: err instanceof Error ? err.message : String(err),\n },\n };\n }\n }\n\n /**\n * Authenticate a user with an optional challenge to sign.\n *\n * This method combines authentication (sign in / sign up) with optional\n * challenge signing, enabling off-chain login without on-chain transactions.\n *\n * When a challenge is provided:\n * 1. User authenticates (sign in or sign up) through the normal auth dialog\n * 2. User signs the challenge through the normal signing dialog\n * 3. Returns user info + signature for server-side verification\n *\n * This composes the same supported provider routes as calling\n * `authWithModal()` followed by `signMessage()`, so challenge auth cannot\n * drift onto a provider route that the passkey service does not expose.\n *\n * @example\n * ```typescript\n * const result = await client.authenticate({\n * challenge: `Login to MyApp\\nTimestamp: ${Date.now()}\\nNonce: ${crypto.randomUUID()}`\n * });\n *\n * if (result.success && result.challenge) {\n * // Verify signature server-side\n * const isValid = await verifyOnServer(\n * result.user?.address,\n * result.challenge.signature,\n * result.challenge.signedHash\n * );\n * }\n * ```\n */\n async authenticate(options?: AuthenticateOptions & { theme?: ThemeConfig }): Promise<AuthenticateResult> {\n const telemetry = this.createTelemetryOperation(\"authenticate\", {\n hasChallenge: !!options?.challenge,\n });\n const authResult = await this.authWithModal(options?.theme ? { theme: options.theme } : undefined);\n if (!authResult.success) {\n this.emitTelemetry(\n authResult.error?.code === \"USER_CANCELLED\" ? \"dialog.cancelled\" : \"auth.failed\",\n telemetry,\n {\n outcome: authResult.error?.code === \"USER_CANCELLED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(authResult.error),\n },\n );\n return authResult;\n }\n\n if (!options?.challenge) {\n this.emitTelemetry(\"auth.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { challengeSigned: false },\n });\n return authResult;\n }\n\n const accountAddress = authResult.user?.address;\n if (!accountAddress) {\n const result: AuthenticateResult = {\n success: false,\n user: authResult.user,\n signerType: authResult.signerType,\n error: {\n code: \"AUTHENTICATE_USER_MISSING\",\n message: \"Authentication succeeded but no account address was returned for challenge signing\",\n },\n };\n this.emitTelemetry(\"auth.failed\", telemetry, {\n outcome: \"failure\",\n ...describeTelemetryError(result.error),\n });\n return result;\n }\n\n const signResult = await this.signMessage({\n accountAddress,\n message: options.challenge,\n description: \"Verify your identity\",\n theme: options.theme,\n });\n\n if (signResult.success && signResult.signature && signResult.signedHash) {\n const result: AuthenticateResult = {\n ...authResult,\n challenge: {\n signature: signResult.signature,\n signedHash: signResult.signedHash,\n },\n };\n this.emitTelemetry(\"auth.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { challengeSigned: true },\n });\n return result;\n }\n\n const error = signResult.error\n ? { code: signResult.error.code, message: signResult.error.message }\n : { code: \"SIGNING_FAILED\", message: \"Challenge signing failed\" };\n const result: AuthenticateResult = {\n success: false,\n user: authResult.user,\n signerType: authResult.signerType,\n error,\n };\n const cancelled = error.code === \"USER_CANCELLED\" || error.code === \"USER_REJECTED\";\n this.emitTelemetry(\n cancelled ? \"dialog.cancelled\" : \"auth.failed\",\n telemetry,\n {\n outcome: cancelled ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(error),\n },\n );\n return result;\n }\n\n /**\n * Show signing in a modal overlay (iframe dialog)\n */\n async signWithModal(options: SigningRequestOptions & { theme?: ThemeConfig }): Promise<SigningResult> {\n const telemetry = this.createTelemetryOperation(\"sign\", {\n signingMode: \"transaction\",\n hasTransaction: !!options.transaction,\n hasAccountAddress: !!options.accountAddress,\n });\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n challenge: options.challenge,\n accountAddress: options.accountAddress,\n description: options.description,\n transaction: options.transaction,\n metadata: options.metadata,\n telemetry: this.telemetryPayload(telemetry),\n }, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n if (!ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_REJECTED\",\n errorMessage: \"User closed the dialog before signing\",\n });\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n const result = await this.waitForSigningResponse(dialog, iframe, cleanup);\n if (result.success) {\n this.emitTelemetry(\"sign.succeeded\", telemetry, { outcome: \"success\" });\n } else {\n this.emitTelemetry(\n result.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n telemetry,\n {\n outcome: result.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(result.error),\n },\n );\n }\n return result;\n }\n\n /**\n * Send an intent to the Rhinestone orchestrator\n *\n * This is the high-level method for cross-chain transactions:\n * 1. Prepares the intent (gets quote from orchestrator)\n * 2. Shows the signing modal with real fees\n * 3. Submits the signed intent for execution\n * 4. Returns the transaction hash\n *\n * @example\n * ```typescript\n * const result = await client.sendIntent({\n * accountAddress: '0x...',\n * targetChain: 8453, // Base\n * calls: [\n * {\n * to: '0x...',\n * data: '0x...',\n * label: 'Swap ETH for USDC',\n * sublabel: '0.1 ETH → ~250 USDC',\n * },\n * ],\n * });\n *\n * if (result.success) {\n * console.log('Transaction hash:', result.transactionHash);\n * }\n * ```\n */\n async sendIntent(options: SendIntentOptions): Promise<SendIntentResult> {\n const { accountAddress, targetChain } = options;\n // Cap label/sublabel up front so every downstream consumer (prepare\n // request body AND the dialog's phase-1 init payload) sees the same\n // truncated strings — keeps wire data and rendered UI in sync.\n const calls = capCallLabels(options.calls);\n const sponsor = options.sponsor !== false;\n const telemetry = this.createTelemetryOperation(\"intent\", {\n targetChain: targetChain ?? null,\n callsCount: calls?.length ?? 0,\n sponsor,\n blindSigning: this.shouldRequestBlindSigning(options),\n });\n\n if (getStoredSignerType() === \"eoa\") {\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"E_SIGNER_UNSUPPORTED\",\n errorMessage: \"Cross-chain intents are not supported for EOA sessions\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"E_SIGNER_UNSUPPORTED\",\n message:\n \"Cross-chain intents are not supported for EOA sessions. Use the connected wallet's native RPC instead.\",\n },\n };\n }\n\n if (!accountAddress) {\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"accountAddress is required\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"accountAddress is required\",\n },\n };\n }\n\n const hasCalls = !!calls?.length;\n const hasTokenRequests = !!options.tokenRequests?.length;\n if (!targetChain || (!hasCalls && !hasTokenRequests)) {\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"targetChain and calls or tokenRequests are required\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"targetChain and calls or tokenRequests are required\",\n },\n };\n }\n\n if (!this.sponsorship) {\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"MISSING_APP_CREDENTIALS\",\n errorMessage: \"No sponsorship configured on OneAuthClient\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"MISSING_APP_CREDENTIALS\",\n message:\n \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — configure `sponsorship` on the client.\",\n },\n };\n }\n\n // Convert bigint amounts to strings for API serialization\n const serializedTokenRequests = options.tokenRequests?.map((r) => ({\n token: r.token,\n amount: r.amount.toString(),\n }));\n let prepareResponse: PrepareIntentResponse;\n\n // 1. Show dialog immediately + prepare in parallel.\n //\n // Two-phase approach — why:\n // - The dialog is shown right away so the user sees a UI immediately.\n // - Access-token minting also runs behind the dialog boot. The prepare\n // request still needs the token, but the iframe/chunk load does not;\n // overlapping them removes a cold app-token round trip from the\n // perceived loading path.\n // - Intent preparation (API call to the orchestrator for a quote) can\n // take 1–3 seconds. Hiding the dialog until the quote is ready would\n // make the interaction feel sluggish.\n // - Phase 1: send a stable transaction shell with raw calls but ask the\n // dialog to hold the movement card skeleton until the quote arrives.\n // Decoded previews are useful in isolation, but here they cause noisy\n // value churn when quote-normalized token decimals replace them.\n // - Phase 2: once the quote arrives, send a narrow quote-ready update\n // instead of replaying the whole PASSKEY_INIT path.\n //\n // Fast path: if preparation finishes before the iframe signals PASSKEY_READY\n // (e.g. on a fast connection), we skip phase 1 entirely and send the full\n // payload in a single PASSKEY_INIT message.\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams();\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogOrigin = this.getDialogOrigin();\n const dialogOpenedAt = Date.now();\n let iframeReadyObserved = false;\n type EarlyDialogClose = { type: \"dialog_closed\"; ready: boolean };\n let stopEarlyCloseWatch: () => void = () => undefined;\n const earlyDialogClosePromise = new Promise<EarlyDialogClose>((resolve) => {\n let settled = false;\n const stop = () => {\n if (settled) return;\n settled = true;\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n stopEarlyCloseWatch = stop;\n\n const resolveClosed = (ready: boolean) => {\n stop();\n cleanup();\n resolve({ type: \"dialog_closed\", ready });\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n // Scope the CLOSE to *this* sign dialog's iframe. authWithModal() and\n // sendIntent() share the same dialogOrigin (passkey.1auth.app), so the\n // auth dialog's PASSKEY_CLOSE — emitted async as it tears down on a\n // successful sign-in — can still be in-flight when sendIntent attaches\n // this listener for its brand-new dialog. Without the source check it\n // gets misattributed to the sign dialog and cancels it before it's\n // ready (USER_CANCELLED). Same guard the modal auth listener already\n // applies via event.source === iframe.contentWindow.\n if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n resolveClosed(iframeReadyObserved);\n }\n };\n\n const handleClose = () => {\n resolveClosed(iframeReadyObserved);\n };\n\n // Covers the gap after PASSKEY_READY but before the full signing listener\n // is installed. Without this, closing the loading dialog during a cold\n // access-token fetch drops PASSKEY_CLOSE and lets prepare continue.\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n let dialogReadyDurationMs: number | undefined;\n const dialogReadyPromise = this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n }).then((result) => {\n dialogReadyDurationMs = Date.now() - dialogOpenedAt;\n iframeReadyObserved = result.ready;\n return result;\n });\n const dialogClosedBeforeReadyPromise = dialogReadyPromise.then((result) =>\n result.ready\n ? new Promise<never>(() => undefined)\n : ({ type: \"dialog_closed\" as const, ready: false }),\n );\n\n const accessTokenStartedAt = Date.now();\n let accessTokenDurationMs: number | undefined;\n const accessTokenPromise = this.fetchAccessToken().then((result) => {\n accessTokenDurationMs = Date.now() - accessTokenStartedAt;\n return result;\n });\n\n const accessOrClose = await Promise.race([\n accessTokenPromise.then((result) => ({ type: \"access_token\" as const, result })),\n dialogClosedBeforeReadyPromise,\n earlyDialogClosePromise,\n ]);\n if (accessOrClose.type === \"dialog_closed\") {\n stopEarlyCloseWatch();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: accessOrClose.ready\n ? \"User closed the dialog while intent setup was still loading\"\n : \"User closed the dialog before it became ready\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n },\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n\n const accessTokenResult = accessOrClose.result;\n // Access-token failures are NOT returned early: they're converted into a\n // synthetic failed PrepareResult below so the dialog's prepare-error\n // retry (\"Try Again\" → PASSKEY_RETRY_PREPARE) covers them too — the\n // retry path re-mints the token first, which is exactly the recovery a\n // transient token-endpoint failure needs.\n let accessTokenFailure: { code: string; message: string } | null = null;\n if (!accessTokenResult.ok) {\n const errorCode = accessTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\";\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode,\n errorMessage: accessTokenResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n loadingPhase: \"access_token\",\n },\n });\n accessTokenFailure = { code: errorCode, message: accessTokenResult.message };\n }\n // Mutable: a dialog-initiated prepare retry re-mints the token (the most\n // common prepare failure is an expired app JWT) and later auth bundles\n // must carry the token the successful prepare actually used.\n let accessToken = accessTokenResult.ok ? accessTokenResult.accessToken : \"\";\n\n // Define requestBody outside try block so it's accessible for quote refresh.\n const requestBody = {\n accountAddress,\n targetChain,\n calls,\n tokenRequests: serializedTokenRequests,\n sourceAssets: options.sourceAssets,\n sourceChainId: options.sourceChainId,\n auth: { accessToken },\n ...(this.config.clientId && { clientId: this.config.clientId }),\n };\n\n // Start prepare in background; track completion via mutable variable.\n // When the iframe becomes ready, earlyPrepareResult will be non-null\n // if prepare finished first (fast path), or null if still in flight.\n type PrepareResult =\n | { success: true; data: PrepareIntentResponse; tier: string | null }\n | { success: false; error: { code: string; message: string; details?: unknown } };\n let earlyPrepareResult: PrepareResult | null = null;\n // Per-intent extension token is fetched in parallel with the signing\n // ceremony: as soon as /prepare returns `intentOp`, we kick off the\n // app-scoped callback. The fetch overlaps with iframe-ready + user\n // review + WebAuthn tap, so by the time the dialog is ready to call\n // /execute the token is already in the init payload. Empty array when\n // `sponsor: false` — the user pays from source assets instead.\n let extensionTokensPromise: Promise<ExtensionTokensFetchResult> =\n Promise.resolve({ ok: true, extensionTokens: [] });\n let extensionTokensDurationMs: number | undefined;\n this.emitTelemetry(\"intent.prepare.started\", telemetry, {\n outcome: \"started\",\n targetChain,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n },\n });\n const prepareStartedAt = Date.now();\n let prepareDurationMs: number | undefined;\n // Wrapped so dialog-initiated retries (PASSKEY_RETRY_PREPARE after a\n // prepare error) can re-run the exact same prepare + telemetry +\n // extension-token kickoff with an updated `requestBody.auth`.\n const runPrepare = () => this.prepareIntent(requestBody, telemetry).then((r) => {\n earlyPrepareResult = r;\n prepareDurationMs = Date.now() - prepareStartedAt;\n if (r.success) {\n this.emitTelemetry(\"intent.prepare.succeeded\", telemetry, {\n outcome: \"success\",\n targetChain,\n status: \"quoted\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n },\n });\n const extensionTokensStartedAt = Date.now();\n extensionTokensPromise = this.fetchExtensionTokens(\n [r.data.intentOp],\n [sponsor],\n ).then((result) => {\n extensionTokensDurationMs = Date.now() - extensionTokensStartedAt;\n return result;\n });\n } else {\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n targetChain,\n ...describeTelemetryError(r.error),\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n loadingPhase: \"prepare\",\n },\n });\n }\n return r;\n });\n // When the access token never materialised, seed the flow with a failed\n // result instead of calling /prepare with empty auth — the fast/\n // progressive retry loops below surface it in the dialog and the user's\n // retry re-mints the token before re-running prepare.\n const preparePromise = accessTokenFailure\n ? Promise.resolve<PrepareResult>({\n success: false,\n error: accessTokenFailure,\n }).then((r) => {\n earlyPrepareResult = r;\n return r;\n })\n : runPrepare();\n\n // Re-run prepare after the dialog requested a retry. Re-mints the app\n // access token first: the dominant cause of prepare failures is the app\n // JWT expiring (orchestrator 401), so retrying with the original token\n // would fail forever. Returns the new PrepareResult — failures feed back\n // into the caller's retry loop.\n const retryPrepare = async (): Promise<PrepareResult> => {\n const retryTokenResult = await this.fetchAccessToken();\n if (!retryTokenResult.ok) {\n return {\n success: false,\n error: {\n code: retryTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\",\n message: retryTokenResult.message,\n },\n };\n }\n accessToken = retryTokenResult.accessToken;\n requestBody.auth = { accessToken };\n return runPrepare();\n };\n\n // Wait for iframe to be ready\n const readyOrClose = await Promise.race([\n dialogReadyPromise.then((result) => ({ type: \"ready\" as const, result })),\n earlyDialogClosePromise,\n ]);\n if (readyOrClose.type === \"dialog_closed\") {\n stopEarlyCloseWatch();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: readyOrClose.ready\n ? \"User closed the dialog while intent setup was still loading\"\n : \"User closed the dialog before it became ready\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n },\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n const dialogResult = readyOrClose.result;\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\n stopEarlyCloseWatch();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the dialog before it became ready\",\n });\n return {\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, {\n outcome: \"started\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n },\n });\n\n // Mutable init payload — starts as early preview, upgraded to full after quote\n let currentInitPayload: Record<string, unknown>;\n const refreshQuote = async () => {\n try {\n // Re-mint the app access token for the refreshed prepare. Quote\n // refreshes happen when the user lingers on the review screen, so\n // the token captured in `requestBody` may be close to (or past) its\n // 1h expiry — the orchestrator would reject it with a 401 and the\n // refresh would fail even though the quote itself is refreshable.\n const refreshedTokenResult = await this.fetchAccessToken();\n const refreshToken = refreshedTokenResult.ok\n ? refreshedTokenResult.accessToken\n : accessToken;\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify({ ...requestBody, auth: { accessToken: refreshToken } }),\n credentials: \"include\",\n });\n\n if (!refreshResponse.ok) {\n console.error(\"[SDK] Quote refresh failed:\", await refreshResponse.text());\n return null;\n }\n\n const refreshedData = await refreshResponse.json();\n\n // Re-bind the ENTIRE auth bundle to the refreshed quote, not just the\n // refresh HTTP call. Extension grants are digest-bound to their\n // intentOp, so a grant minted for the previous quote cannot authorize\n // the refreshed one — execute would sign the new intentOp but submit\n // stale auth and fail. Block until the new grant lands so the dialog\n // can never sign a refreshed quote with mismatched auth.\n const refreshedExtensionPromise = this.fetchExtensionTokens(\n [refreshedData.intentOp],\n [sponsor],\n );\n const extensionResult = await refreshedExtensionPromise;\n if (!extensionResult.ok) {\n console.error(\n \"[SDK] Extension token refresh failed:\",\n extensionResult.message,\n );\n return null;\n }\n const refreshedAuth: SponsorshipTokens = {\n accessToken: refreshToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n\n // Keep execute (legacy SDK-submit path) aligned with the latest quote\n // the dialog is reviewing — token, grant, and quote move together.\n prepareResponse = refreshedData;\n accessToken = refreshToken;\n requestBody.auth = { accessToken: refreshToken };\n extensionTokensPromise = refreshedExtensionPromise;\n // Keep iframe-remount replays (PASSKEY_READY → PASSKEY_INIT) on the\n // refreshed quote too.\n currentInitPayload = {\n ...currentInitPayload,\n transaction: refreshedData.transaction,\n challenge: refreshedData.challenge,\n originMessages: refreshedData.originMessages,\n expiresAt: refreshedData.expiresAt,\n intentOp: refreshedData.intentOp,\n digestResult: refreshedData.digestResult,\n // A refreshed quote mints a fresh binding — it MUST replace the old\n // one, or execute would verify the new intentOp against a stale\n // binding and reject (once enforce mode is on).\n binding: refreshedData.binding,\n auth: refreshedAuth,\n };\n return {\n intentOp: refreshedData.intentOp,\n expiresAt: refreshedData.expiresAt,\n challenge: refreshedData.challenge,\n originMessages: refreshedData.originMessages,\n transaction: refreshedData.transaction,\n digestResult: refreshedData.digestResult,\n binding: refreshedData.binding,\n // Dialog-executed intents read auth from dialog state — ship the\n // rebound bundle with the refresh so PASSKEY_REFRESH_COMPLETE\n // updates it alongside the quote.\n auth: refreshedAuth,\n };\n } catch (error) {\n console.error(\"[SDK] Quote refresh error:\", error);\n return null;\n }\n };\n // Install the close/result listener before the progressive preview init is\n // sent. Otherwise a user can click Cancel while /prepare is still waiting\n // on quote or portfolio work, and the parent page drops the message.\n const signingResultPromise = this.waitForSigningWithRefresh(\n dialog,\n iframe,\n cleanup,\n dialogOrigin,\n refreshQuote,\n );\n stopEarlyCloseWatch();\n\n if (earlyPrepareResult) {\n // Fast path: prepare already finished — send full PASSKEY_INIT (no regression)\n // Type assertion needed: TS control flow doesn't track .then() mutations\n let prepareResult = earlyPrepareResult as PrepareResult;\n // Same retry contract as the progressive path below: any failure before\n // the full payload reaches the dialog surfaces as PASSKEY_PREPARE_ERROR,\n // and the dialog's \"Try Again\" re-enters via PASSKEY_RETRY_PREPARE.\n for (;;) {\n while (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n if (blindSigning) {\n // No visible dialog to host the error/retry UI — fail immediately.\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResult = await retryPrepare();\n }\n prepareResponse = prepareResult.data;\n const extensionResult = await extensionTokensPromise;\n if (extensionResult.ok) {\n const sponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n currentInitPayload = {\n mode: \"iframe\",\n calls,\n chainId: targetChain,\n transaction: prepareResponse.transaction,\n challenge: prepareResponse.challenge,\n accountAddress: prepareResponse.accountAddress,\n originMessages: prepareResponse.originMessages,\n tokenRequests: serializedTokenRequests,\n expiresAt: prepareResponse.expiresAt,\n userId: prepareResponse.userId,\n intentOp: prepareResponse.intentOp,\n digestResult: prepareResponse.digestResult,\n binding: prepareResponse.binding,\n tier: prepareResult.tier,\n auth: sponsorshipTokens,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentInitPayload);\n break;\n }\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: extensionResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n loadingPhase: \"extension_token\",\n },\n });\n this.sendPrepareError(iframe, extensionResult.message);\n if (blindSigning) {\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n // Retrying just the extension token would be unsafe — grants are\n // digest-bound to the intentOp — so re-run the full prepare.\n prepareResult = await retryPrepare();\n }\n } else {\n // Progressive path: send the raw calls up front so the dialog can\n // decode them locally (/api/decode) and reveal a fully-formed\n // transaction card the moment decode settles — without waiting on the\n // orchestrator quote. The quote follows via PASSKEY_QUOTE_READY below\n // and upgrades the fee row + any routed amounts in place. The dialog\n // gates the Sign button on that authoritative quote, so revealing the\n // decoded preview early never lets the user sign un-quoted data.\n currentInitPayload = {\n mode: \"iframe\",\n signingMode: \"transaction\",\n calls,\n chainId: targetChain,\n accountAddress: options.accountAddress,\n tokenRequests: serializedTokenRequests,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentInitPayload);\n\n // Wait for prepare to complete, then send quote data\n const prepareOrCancel = await Promise.race([\n preparePromise.then((prepareResult) => ({\n type: \"prepare\" as const,\n prepareResult,\n })),\n signingResultPromise.then((signingResult) => ({\n type: \"signing\" as const,\n signingResult,\n })),\n ]);\n let prepareResult: PrepareResult;\n if (prepareOrCancel.type === \"signing\") {\n const earlySigningResult = prepareOrCancel.signingResult;\n if (earlySigningResult.success) {\n // Signing cannot complete before the prepared challenge arrives, but\n // keep this branch total so TypeScript and future hidden flows have a\n // deterministic path to the quote data needed for execute.\n prepareResult = await preparePromise;\n } else {\n const signingError = earlySigningResult.error;\n this.emitTelemetry(\n signingError?.code === \"USER_REJECTED\"\n ? \"dialog.cancelled\"\n : \"intent.sign.failed\",\n telemetry,\n {\n outcome: signingError?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingError),\n },\n );\n if (blindSigning) cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: signingError,\n };\n }\n } else {\n prepareResult = prepareOrCancel.prepareResult;\n }\n // Drive prepare → quote-ready → extension-token to completion, looping\n // back through the dialog's \"Try Again\" (PASSKEY_RETRY_PREPARE) on any\n // failure along the way. Each retry re-runs the FULL prepare so the\n // quote and the per-intent sponsorship grant always match — a grant is\n // digest-bound to its intentOp, so retrying just the extension token\n // against a re-quoted intent would produce an unusable auth bundle.\n for (;;) {\n while (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n if (blindSigning) {\n // No visible dialog to host the error/retry UI — fail immediately.\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResult = await retryPrepare();\n }\n prepareResponse = prepareResult.data;\n const authReady =\n !sponsor\n ? ({\n accessToken,\n extensionTokens: [],\n } satisfies SponsorshipTokens)\n : undefined;\n\n // Upgrade the init payload with full quote data. For sponsored intents,\n // don't wait for the extension token here: review display needs the quote,\n // while submit auth can arrive as a small follow-up before Sign unlocks.\n currentInitPayload = {\n mode: \"iframe\",\n calls,\n chainId: targetChain,\n transaction: prepareResponse.transaction,\n challenge: prepareResponse.challenge,\n accountAddress: prepareResponse.accountAddress,\n originMessages: prepareResponse.originMessages,\n tokenRequests: serializedTokenRequests,\n expiresAt: prepareResponse.expiresAt,\n userId: prepareResponse.userId,\n intentOp: prepareResponse.intentOp,\n digestResult: prepareResponse.digestResult,\n binding: prepareResponse.binding,\n tier: prepareResult.tier,\n ...(authReady && { auth: authReady }),\n telemetry: this.telemetryPayload(telemetry),\n };\n\n // Narrow update: avoid replaying PASSKEY_INIT, which would rerun broad\n // dialog initialization and briefly replace the skeleton/preview state\n // before the authoritative quote-backed transaction lands.\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_QUOTE_READY\", ...currentInitPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n\n if (!sponsor) break;\n\n const extensionResult = await extensionTokensPromise;\n if (extensionResult.ok) {\n const sponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n currentInitPayload = {\n ...currentInitPayload,\n auth: sponsorshipTokens,\n };\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_QUOTE_READY\", auth: sponsorshipTokens, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n break;\n }\n\n this.emitTelemetry(\"intent.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: extensionResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n loadingPhase: \"extension_token\",\n },\n });\n this.sendPrepareError(iframe, extensionResult.message);\n if (blindSigning) {\n cleanup();\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n const next = await this.waitForPrepareRetryOrClose(dialog, cleanup);\n if (next === \"closed\") {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n prepareResult = await retryPrepare();\n }\n }\n\n // 2. Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n // so the sign page recovers its state. Uses currentInitPayload which is the\n // full payload after quote arrives.\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentInitPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n // 3. Wait for signing result with auto-refresh support\n // This custom handler handles both signing results AND quote refresh requests.\n const signingResult = await signingResultPromise;\n\n window.removeEventListener(\"message\", handleReReady);\n\n if (!signingResult.success) {\n this.emitTelemetry(\n signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"intent.sign.failed\",\n telemetry,\n {\n outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingResult.error),\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n },\n },\n );\n if (blindSigning) cleanup();\n return {\n success: false,\n intentId: \"\", // No intentId yet - signing was cancelled before execute\n status: \"failed\",\n error: signingResult.error,\n };\n }\n\n // Check if dialog already executed the intent (new secure flow)\n // In this case, signingResult contains intentId instead of signature\n const dialogExecutedIntent = \"intentId\" in signingResult && signingResult.intentId;\n\n // 5. Execute intent with signature (skip if dialog already executed)\n let executeResponse: ExecuteIntentResponse;\n\n if (dialogExecutedIntent) {\n // Dialog already executed - use the returned intentId\n executeResponse = {\n success: true,\n intentId: signingResult.intentId as string,\n status: \"pending\",\n };\n this.emitTelemetry(\"intent.sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n dialogExecuted: true,\n },\n });\n } else {\n // Legacy flow - execute with signature from dialog. The extension\n // token was already fetched in parallel with signing above, so this\n // just awaits the (usually already-resolved) promise. `accessToken` was\n // fetched before /prepare, overlapped with the dialog iframe boot.\n const extensionResult = await extensionTokensPromise;\n if (!extensionResult.ok) {\n this.emitTelemetry(\"intent.sign.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: extensionResult.message,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n loadingPhase: \"extension_token\",\n },\n });\n this.sendTransactionStatus(iframe, \"failed\");\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: { code: \"SPONSORSHIP_FETCH_FAILED\", message: extensionResult.message },\n };\n }\n const extensionTokens = extensionResult.extensionTokens;\n try {\n this.emitTelemetry(\"intent.sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n dialogExecuted: false,\n },\n });\n this.emitTelemetry(\"intent.execute.started\", telemetry, {\n outcome: \"started\",\n targetChain: prepareResponse.targetChain,\n attributes: {\n accessTokenDurationMs,\n dialogReadyDurationMs,\n prepareDurationMs,\n extensionTokensDurationMs,\n },\n });\n const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...this.telemetryHeaders(telemetry),\n },\n body: JSON.stringify({\n // Data from prepare response (no intentId yet - created on execute)\n intentOp: prepareResponse.intentOp,\n userId: prepareResponse.userId,\n targetChain: prepareResponse.targetChain,\n calls: prepareResponse.calls,\n expiresAt: prepareResponse.expiresAt,\n digestResult: prepareResponse.digestResult,\n // Opaque prepare->execute binding, forwarded unchanged.\n binding: prepareResponse.binding,\n // Signature from dialog\n signature: signingResult.signature,\n passkey: signingResult.passkey, // Include passkey info for signature encoding\n // App JWT — `accessToken` is always present. `extensionToken` is\n // only included when sponsorship was requested (sponsor !== false).\n auth: {\n accessToken,\n ...(extensionTokens.length > 0 && {\n extensionToken: extensionTokens[0],\n }),\n },\n }),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n // Send failure status to dialog\n this.sendTransactionStatus(iframe, \"failed\");\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.emitTelemetry(\"intent.execute.failed\", telemetry, {\n outcome: \"failure\",\n targetChain: prepareResponse.targetChain,\n errorCode: \"EXECUTE_FAILED\",\n errorMessage: errorData.error || \"Failed to execute intent\",\n });\n return {\n success: false,\n intentId: \"\", // No intentId - execute failed before creation\n status: \"failed\",\n error: {\n code: \"EXECUTE_FAILED\",\n message: errorData.error || \"Failed to execute intent\",\n },\n };\n }\n\n executeResponse = await response.json();\n this.emitTelemetry(\"intent.execute.succeeded\", telemetry, {\n outcome: \"success\",\n targetChain: prepareResponse.targetChain,\n status: executeResponse.status,\n });\n } catch (error) {\n // Send failure status to dialog\n this.sendTransactionStatus(iframe, \"failed\");\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.emitTelemetry(\"intent.execute.failed\", telemetry, {\n outcome: \"failure\",\n targetChain: prepareResponse.targetChain,\n ...describeTelemetryError(error),\n });\n return {\n success: false,\n intentId: \"\", // No intentId - network error before creation\n status: \"failed\",\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network error\",\n },\n };\n }\n }\n\n // 6. Poll for completion with status updates to dialog\n let finalStatus = executeResponse.status;\n let finalTxHash = executeResponse.transactionHash;\n\n if (finalStatus === \"pending\") {\n // Send initial pending status to dialog\n this.sendTransactionStatus(iframe, \"pending\");\n this.emitTelemetry(\"intent.status.started\", telemetry, {\n outcome: \"started\",\n status: finalStatus,\n });\n\n // Listen for early close (user clicking X) during polling.\n // Close the dialog immediately so the user gets instant feedback.\n let userClosedEarly = false;\n const dialogOrigin = this.getDialogOrigin();\n const earlyCloseHandler = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n // Scope to this dialog's iframe so a same-origin CLOSE from another\n // 1auth dialog (e.g. a queued auth-modal teardown) can't be\n // misattributed to this poll and cancel it. Mirrors the early-close\n // watcher above and the modal auth listener's source guard.\n if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n userClosedEarly = true;\n cleanup();\n }\n };\n window.addEventListener(\"message\", earlyCloseHandler);\n\n // Poll status endpoint for updates\n const maxAttempts = 120; // 3 minutes at 1.5s intervals\n const pollIntervalMs = 1500;\n let lastStatus = \"pending\";\n\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n if (userClosedEarly) break;\n\n try {\n const statusResponse = await fetch(\n `${this.config.providerUrl}/api/intent/status/${executeResponse.intentId}`,\n {\n method: \"GET\",\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n }\n );\n\n if (statusResponse.ok) {\n const statusResult = await statusResponse.json();\n finalStatus = statusResult.status;\n finalTxHash = statusResult.transactionHash;\n\n // Send status update to dialog if changed\n if (finalStatus !== lastStatus) {\n this.sendTransactionStatus(iframe, finalStatus, finalTxHash);\n lastStatus = finalStatus;\n }\n\n // Exit if terminal status reached\n // closeOn determines when to consider the intent successful (default: preconfirmed)\n const closeOn = options.closeOn || \"preconfirmed\";\n const successStatuses: Record<string, string[]> = {\n claimed: [\"claimed\", \"preconfirmed\", \"filled\", \"completed\"],\n preconfirmed: [\"preconfirmed\", \"filled\", \"completed\"],\n filled: [\"filled\", \"completed\"],\n completed: [\"completed\"],\n };\n const isTerminal = finalStatus === \"failed\" || finalStatus === \"expired\";\n const isSuccess = successStatuses[closeOn]?.includes(finalStatus) ?? false;\n if (isTerminal || isSuccess) {\n break;\n }\n }\n } catch (pollError) {\n console.error(\"Failed to poll intent status:\", pollError);\n }\n\n // Wait before next poll\n await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));\n }\n\n window.removeEventListener(\"message\", earlyCloseHandler);\n\n // If user closed during polling, clean up and return current status\n if (userClosedEarly) {\n cleanup();\n this.emitTelemetry(\"intent.status.failed\", telemetry, {\n outcome: \"cancelled\",\n status: finalStatus,\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the dialog while status polling\",\n });\n return {\n success: false,\n intentId: executeResponse.intentId,\n status: finalStatus,\n transactionHash: finalTxHash,\n operationId: executeResponse.operationId,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n };\n }\n }\n\n // 7. Send final status to dialog\n // Map successful statuses to \"confirmed\" based on closeOn setting\n const closeOn = options.closeOn || \"preconfirmed\";\n const successStatuses: Record<string, string[]> = {\n claimed: [\"claimed\", \"preconfirmed\", \"filled\", \"completed\"],\n preconfirmed: [\"preconfirmed\", \"filled\", \"completed\"],\n filled: [\"filled\", \"completed\"],\n completed: [\"completed\"],\n };\n const isSuccessStatus = successStatuses[closeOn]?.includes(finalStatus) ?? false;\n const displayStatus = isSuccessStatus ? \"confirmed\" : finalStatus;\n\n // Start listening for close BEFORE sending status to avoid race condition\n // where user clicks Done before the listener is registered\n const closePromise = this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.sendTransactionStatus(iframe, displayStatus, finalTxHash);\n\n // Wait for dialog to be closed by user\n await closePromise;\n\n if (options.waitForHash && !finalTxHash) {\n const hash = await this.waitForTransactionHash(executeResponse.intentId, {\n timeoutMs: options.hashTimeoutMs,\n intervalMs: options.hashIntervalMs,\n }, telemetry);\n if (hash) {\n finalTxHash = hash;\n finalStatus = \"completed\";\n } else {\n finalStatus = \"failed\";\n this.emitTelemetry(\"intent.status.failed\", telemetry, {\n outcome: \"failure\",\n status: finalStatus,\n errorCode: \"HASH_TIMEOUT\",\n errorMessage: \"Timed out waiting for transaction hash\",\n });\n return {\n success: false,\n intentId: executeResponse.intentId,\n status: finalStatus,\n transactionHash: finalTxHash,\n operationId: executeResponse.operationId,\n error: {\n code: \"HASH_TIMEOUT\",\n message: \"Timed out waiting for transaction hash\",\n },\n };\n }\n }\n\n this.emitTelemetry(\"intent.status.succeeded\", telemetry, {\n outcome: isSuccessStatus ? \"success\" : \"failure\",\n status: finalStatus,\n });\n this.emitTelemetry(\"intent.completed\", telemetry, {\n outcome: isSuccessStatus ? \"success\" : \"failure\",\n status: finalStatus,\n targetChain,\n });\n\n return {\n success: isSuccessStatus,\n intentId: executeResponse.intentId,\n status: finalStatus,\n transactionHash: finalTxHash,\n operationId: executeResponse.operationId,\n error: executeResponse.error,\n };\n }\n\n /**\n * Send a batch of intents for multi-chain execution with a single passkey tap.\n *\n * This method prepares multiple intents, shows a paginated review,\n * and signs all intents with a single passkey tap via a shared merkle tree.\n *\n * @example\n * ```typescript\n * const result = await client.sendBatchIntent({\n * accountAddress: '0x...',\n * intents: [\n * {\n * targetChain: 8453, // Base\n * calls: [{ to: '0x...', data: '0x...', label: 'Swap on Base' }],\n * },\n * {\n * targetChain: 42161, // Arbitrum\n * calls: [{ to: '0x...', data: '0x...', label: 'Mint on Arbitrum' }],\n * },\n * ],\n * });\n *\n * if (result.success) {\n * console.log(`${result.successCount} intents submitted`);\n * }\n * ```\n */\n async sendBatchIntent(options: SendBatchIntentOptions): Promise<SendBatchIntentResult> {\n const telemetry = this.createTelemetryOperation(\"batch_intent\", {\n intentCount: options.intents?.length ?? 0,\n blindSigning: this.shouldRequestBlindSigning(options),\n });\n if (getStoredSignerType() === \"eoa\") {\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"E_SIGNER_UNSUPPORTED\",\n errorMessage: \"Batch intents are not supported for EOA sessions\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n error:\n \"Batch intents are not supported for EOA sessions. Use the connected wallet's native RPC instead.\",\n };\n }\n\n if (!options.accountAddress) {\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"accountAddress is required\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n if (!options.intents?.length) {\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"INVALID_OPTIONS\",\n errorMessage: \"At least one intent is required\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n if (!this.sponsorship) {\n this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"MISSING_APP_CREDENTIALS\",\n errorMessage: \"No sponsorship configured on OneAuthClient\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n error:\n \"No sponsorship configured on OneAuthClient. Every user intent must carry the app's JWT — configure `sponsorship` on the client.\",\n };\n }\n\n const sponsorFlags = options.intents.map((intent) => intent.sponsor !== false);\n\n // Fetch the app's access token up front — /api/intent/batch-prepare\n // requires it so the passkey server can authenticate its orchestrator\n // quote calls with the app's JWT instead of a service-level API key.\n const accessTokenResult = await this.fetchAccessToken();\n if (!accessTokenResult.ok) {\n this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: accessTokenResult.code ?? \"SPONSORSHIP_FETCH_FAILED\",\n errorMessage: accessTokenResult.message,\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n error: accessTokenResult.message,\n };\n }\n // Mutable: a quote refresh re-mints the token and must keep the execute\n // path's auth aligned with the refreshed quotes.\n let accessToken = accessTokenResult.accessToken;\n\n // Serialize token request amounts to strings for API. Each intent's\n // labels are capped via capCallLabels() so the dialog's phase-1 preview\n // (which reads from serializedIntents below) and the prepare request\n // both ship the same truncated strings.\n const serializedIntents = options.intents.map((intent) => ({\n targetChain: intent.targetChain,\n calls: capCallLabels(intent.calls),\n tokenRequests: intent.tokenRequests?.map((r) => ({\n token: r.token,\n amount: r.amount.toString(),\n })),\n sourceAssets: intent.sourceAssets,\n sourceChainId: intent.sourceChainId,\n moduleInstall: intent.moduleInstall,\n }));\n\n const requestBody = {\n ...(options.accountAddress && { accountAddress: options.accountAddress }),\n intents: serializedIntents,\n auth: { accessToken },\n ...(this.config.clientId && { clientId: this.config.clientId }),\n };\n\n // 1. Show dialog immediately + prepare batch in parallel.\n //\n // Same two-phase approach as sendIntent: open the dialog right away with\n // raw call data so the user sees something immediately, then upgrade to the\n // full quote payload once batch-prepare completes. See sendIntent for the\n // full rationale.\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams();\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n intentCount: options.intents.length,\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogOrigin = this.getDialogOrigin();\n\n // Start batch-prepare in background; track completion via mutable variable\n type BatchPrepareResult =\n | { success: true; data: PrepareBatchIntentResponse; tier: string | null }\n | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> };\n let earlyBatchResult: BatchPrepareResult | null = null;\n // Pre-fetch one extension token per intent in parallel with the signing\n // ceremony. Rhinestone's `getIntentExtensionToken(intentInput)` is\n // per-intent, so the passkey server needs a token aligned with each\n // intent's position in the batch.\n let batchExtensionTokensPromise: Promise<ExtensionTokensFetchResult> =\n Promise.resolve({ ok: true, extensionTokens: [] });\n this.emitTelemetry(\"batch.prepare.started\", telemetry, {\n outcome: \"started\",\n intentCount: options.intents.length,\n targetChains: serializedIntents.map((intent) => intent.targetChain),\n });\n const preparePromise = this.prepareBatchIntent(requestBody, telemetry).then((r) => {\n earlyBatchResult = r;\n if (r.success) {\n this.emitTelemetry(\"batch.prepare.succeeded\", telemetry, {\n outcome: \"success\",\n intentCount: r.data.intents.length,\n targetChains: serializedIntents.map((intent) => intent.targetChain),\n });\n batchExtensionTokensPromise = this.fetchExtensionTokens(\n r.data.intents.map((intent) => intent.intentOp),\n sponsorFlags,\n );\n } else {\n this.emitTelemetry(\"batch.prepare.failed\", telemetry, {\n outcome: \"failure\",\n errorMessage: r.error,\n intentCount: options.intents.length,\n });\n }\n return r;\n });\n\n // Wait for iframe to be ready\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the dialog before it became ready\",\n });\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n // Mutable init payload — starts as early preview, upgraded to full after quote\n let currentBatchPayload: Record<string, unknown>;\n\n // Helper to handle batch prepare failure\n const handleBatchPrepareFailure = async (\n prepareResult: Extract<BatchPrepareResult, { success: false }>,\n ) => {\n const failedIntents = prepareResult.failedIntents;\n const failureResults: import(\"./types\").BatchIntentItemResult[] = failedIntents?.map((f) => ({\n index: f.index,\n success: false,\n intentId: \"\",\n status: \"failed\" as import(\"./types\").IntentStatus,\n error: { message: f.error, code: \"PREPARE_FAILED\" },\n })) ?? [];\n\n this.sendPrepareError(iframe, prepareResult.error);\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n return {\n success: false as const,\n results: failureResults,\n successCount: 0,\n failureCount: failureResults.length,\n error: prepareResult.error,\n };\n };\n\n // Helper to handle sponsorship-fetch failure after batch prepare succeeded.\n // The passkey server cannot submit a sponsored batch without tokens, so\n // tear the dialog down and surface the error as a uniform batch failure.\n const handleSponsorshipFailure = async (message: string) => {\n this.sendPrepareError(iframe, message);\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n return {\n success: false as const,\n results: [],\n successCount: 0,\n failureCount: 0,\n error: `Sponsorship token fetch failed: ${message}`,\n };\n };\n\n let prepareResponse: PrepareBatchIntentResponse;\n\n if (earlyBatchResult) {\n // Fast path: batch-prepare already finished — send full PASSKEY_INIT\n const prepareResult = earlyBatchResult as BatchPrepareResult;\n if (!prepareResult.success) {\n return handleBatchPrepareFailure(prepareResult);\n }\n prepareResponse = prepareResult.data;\n const batchExtensionResult = await batchExtensionTokensPromise;\n if (!batchExtensionResult.ok) {\n return handleSponsorshipFailure(batchExtensionResult.message);\n }\n const batchSponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: batchExtensionResult.extensionTokens,\n };\n currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: prepareResponse.intents,\n batchFailedIntents: prepareResponse.failedIntents,\n challenge: prepareResponse.challenge,\n binding: prepareResponse.binding,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\n auth: batchSponsorshipTokens,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentBatchPayload);\n } else {\n // Progressive path: send early preview with raw intent calls\n currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: serializedIntents.map((intent, idx) => ({\n index: idx,\n targetChain: intent.targetChain,\n calls: JSON.stringify(intent.calls),\n // No: transaction, intentOp, expiresAt, originMessages\n })),\n accountAddress: options.accountAddress,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(currentBatchPayload);\n\n // Wait for batch-prepare to complete, then send quote data\n const prepareResult = await preparePromise;\n if (!prepareResult.success) {\n return handleBatchPrepareFailure(prepareResult);\n }\n prepareResponse = prepareResult.data;\n const batchExtensionResult = await batchExtensionTokensPromise;\n if (!batchExtensionResult.ok) {\n return handleSponsorshipFailure(batchExtensionResult.message);\n }\n const batchSponsorshipTokens: SponsorshipTokens = {\n accessToken,\n extensionTokens: batchExtensionResult.extensionTokens,\n };\n\n // Upgrade the payload with full quote data\n currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: prepareResponse.intents,\n batchFailedIntents: prepareResponse.failedIntents,\n challenge: prepareResponse.challenge,\n binding: prepareResponse.binding,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\n auth: batchSponsorshipTokens,\n telemetry: this.telemetryPayload(telemetry),\n };\n\n // Re-send as PASSKEY_INIT so all dialog versions handle it\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentBatchPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n\n // 2. Handle iframe remount: resend PASSKEY_INIT on subsequent PASSKEY_READY\n const handleBatchReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentBatchPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleBatchReReady);\n\n // 3. Wait for batch signing result with auto-refresh support\n const batchResult = await new Promise<SendBatchIntentResult>((resolve) => {\n const handleMessage = async (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n\n // Handle quote refresh request\n if (message?.type === \"PASSKEY_REFRESH_QUOTE\") {\n try {\n // Re-mint the app access token — refreshes fire after the user\n // lingered on review, so the token in `requestBody` may have\n // crossed its 1h expiry (orchestrator would 401 the re-quote).\n const refreshedTokenResult = await this.fetchAccessToken();\n const refreshToken = refreshedTokenResult.ok\n ? refreshedTokenResult.accessToken\n : accessToken;\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify({ ...requestBody, auth: { accessToken: refreshToken } }),\n });\n\n if (refreshResponse.ok) {\n const refreshed: PrepareBatchIntentResponse = await refreshResponse.json();\n\n // Re-bind the auth bundle to the refreshed intentOps — same\n // contract as the single-intent refresh: extension grants are\n // digest-bound, so grants minted for the previous quotes\n // cannot authorize the refreshed ones at execute. Mirrors the\n // initial batch fetch (returned-intent order × sponsorFlags).\n const refreshedExtensionPromise = this.fetchExtensionTokens(\n refreshed.intents.map((intent) => intent.intentOp),\n sponsorFlags,\n );\n const extensionResult = await refreshedExtensionPromise;\n if (!extensionResult.ok) {\n console.error(\n \"[SDK] Batch extension token refresh failed:\",\n extensionResult.message,\n );\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh batch quotes\",\n }, dialogOrigin);\n return;\n }\n const refreshedAuth: SponsorshipTokens = {\n accessToken: refreshToken,\n extensionTokens: extensionResult.extensionTokens,\n };\n\n prepareResponse = refreshed;\n accessToken = refreshToken;\n requestBody.auth = { accessToken: refreshToken };\n batchExtensionTokensPromise = refreshedExtensionPromise;\n // Keep iframe-remount replays on the refreshed quotes + auth.\n currentBatchPayload = {\n ...currentBatchPayload,\n batchIntents: refreshed.intents,\n batchFailedIntents: refreshed.failedIntents,\n challenge: refreshed.challenge,\n binding: refreshed.binding,\n expiresAt: refreshed.expiresAt,\n auth: refreshedAuth,\n };\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_COMPLETE\",\n batchIntents: refreshed.intents,\n challenge: refreshed.challenge,\n binding: refreshed.binding,\n expiresAt: refreshed.expiresAt,\n auth: refreshedAuth,\n }, dialogOrigin);\n } else {\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh batch quotes\",\n }, dialogOrigin);\n }\n } catch {\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh batch quotes\",\n }, dialogOrigin);\n }\n return;\n }\n\n // Handle signing result with batch results\n if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n\n if (message.success && message.data?.batchResults) {\n const rawResults: Array<{\n index: number;\n operationId?: string;\n intentId?: string;\n status: string;\n error?: string;\n success?: boolean;\n }> = message.data.batchResults;\n\n const results: BatchIntentItemResult[] = rawResults.map((r) => ({\n index: r.index,\n success: r.success ?? r.status !== \"FAILED\",\n intentId: r.intentId || r.operationId || \"\",\n status: r.status === \"FAILED\" ? \"failed\" : \"pending\",\n error: r.error ? { code: \"EXECUTE_FAILED\", message: r.error } : undefined,\n }));\n\n // Merge in prepare-phase failures (e.g. account not deployed on chain).\n // These intents never reached the dialog (they were filtered out before\n // the signing screen), so we re-attach them here to give callers a\n // complete, index-sorted result set covering every input intent.\n const prepareFailures: BatchIntentItemResult[] = (prepareResponse.failedIntents ?? []).map((f) => ({\n index: f.index,\n success: false,\n intentId: \"\",\n status: \"failed\" as const,\n error: { code: \"PREPARE_FAILED\", message: f.error },\n }));\n const allResults = [...results, ...prepareFailures].sort((a, b) => a.index - b.index);\n\n const successCount = allResults.filter((r) => r.success).length;\n\n await this.waitForDialogCloseUnlessBlind(blindSigning, dialog, cleanup);\n this.emitTelemetry(\"batch.sign.succeeded\", telemetry, {\n outcome: \"success\",\n intentCount: allResults.length,\n });\n\n resolve({\n success: successCount === allResults.length,\n results: allResults,\n successCount,\n failureCount: allResults.length - successCount,\n });\n } else {\n // Signing failed or was cancelled\n cleanup();\n this.emitTelemetry(\"batch.sign.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"SIGNING_FAILED\",\n errorMessage: \"Batch signing failed or was cancelled\",\n });\n resolve({\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n });\n }\n }\n\n // Handle dialog close\n if (message?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_CANCELLED\",\n errorMessage: \"User closed the batch dialog\",\n });\n resolve({\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n\n window.removeEventListener(\"message\", handleBatchReReady);\n\n this.emitTelemetry(\"batch.completed\", telemetry, {\n outcome: batchResult.success ? \"success\" : \"failure\",\n intentCount: batchResult.results.length,\n attributes: {\n successCount: batchResult.successCount,\n failureCount: batchResult.failureCount,\n },\n ...(batchResult.error ? { errorMessage: batchResult.error } : {}),\n });\n\n return batchResult;\n }\n\n /**\n * Send transaction status to the dialog iframe\n */\n private sendTransactionStatus(\n iframe: HTMLIFrameElement,\n status: string,\n transactionHash?: string\n ): void {\n const dialogOrigin = this.getDialogOrigin();\n iframe.contentWindow?.postMessage(\n {\n type: \"TRANSACTION_STATUS\",\n status,\n transactionHash,\n },\n dialogOrigin\n );\n }\n\n /**\n * Listen for a signing result that belongs to a specific `requestId`.\n *\n * Used by legacy server-side signing request flows (popup/embed/modal) where\n * the dialog was pre-loaded with a signing request created via the API. The\n * `requestId` filter is needed because multiple dialogs may be open or there\n * may be stale messages from a previous dialog in the queue.\n *\n * Resolves on `PASSKEY_SIGNING_RESULT` matching `requestId`, or on\n * `PASSKEY_CLOSE` (user dismissed the dialog).\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param dialog - The `<dialog>` element (opened before this call) used to\n * `showModal()` so the dialog becomes interactive.\n * @param _iframe - Unused; kept for signature consistency with other wait helpers.\n * @param cleanup - Idempotent teardown function that closes and removes the dialog.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForIntentSigningResponse(\n requestId: string,\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature; passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string } } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\" && payload?.requestId === requestId) {\n window.removeEventListener(\"message\", handleMessage);\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n passkey: payload.passkey, // Include passkey info for signature encoding\n });\n } else {\n resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (\n message?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // User clicked X button to close/reject. Cross-frame guard: ignore a\n // stray PASSKEY_CLOSE from a sibling same-origin dialog so it can't\n // forge a rejection of this signing request.\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n dialog.showModal();\n });\n }\n\n /**\n * Listen for a signing result from the currently open modal dialog.\n *\n * Unlike `waitForIntentSigningResponse`, this variant does not filter by\n * `requestId` because the inline intent flow (sendIntent / signMessage /\n * signTypedData) owns the dialog exclusively — there is no risk of collisions\n * from other dialogs.\n *\n * Handles two result shapes:\n * - New \"secure flow\": dialog executed the intent server-side and returns\n * only an `intentId` (no signature exposed to the SDK).\n * - Legacy flow: dialog returns a raw `WebAuthnSignature` for the SDK to\n * forward to the execute endpoint.\n *\n * @param dialog - The `<dialog>` element wrapping the signing iframe.\n * @param iframe - The signing iframe; used to authenticate the source of\n * `PASSKEY_CLOSE` so a sibling same-origin dialog can't forge a rejection.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @returns A `SigningResult` extended with an optional `signedHash` field\n * populated when the dialog performs message signing.\n */\n private waitForSigningResponse(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult & { signedHash?: string }> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n const payload = message?.data as { signature?: WebAuthnSignature; passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string }; signedHash?: string; intentId?: string } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n\n // Check if dialog already executed the intent (new secure flow)\n if (message.success && payload?.intentId) {\n resolve({\n success: true,\n intentId: payload.intentId,\n } as SigningResult & { signedHash?: string; intentId?: string });\n } else if (message.success && payload?.signature) {\n // Legacy flow - dialog returns signature for SDK to execute\n resolve({\n success: true,\n signature: payload.signature,\n passkey: payload.passkey,\n signedHash: payload.signedHash,\n });\n } else {\n // Failure path: tear the iframe down here. The passkey app\n // sends `PASSKEY_SIGNING_RESULT(false)` then `PASSKEY_CLOSE`\n // back-to-back on cancel, but we've just removed the\n // listener so the follow-up CLOSE would be dropped, leaving\n // the dialog stuck open.\n cleanup();\n resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (\n message?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Cross-frame guard: ignore a stray PASSKEY_CLOSE from a sibling\n // same-origin dialog (e.g. an auth modal tearing down) so it can't\n // forge a rejection of this signing request.\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for a signing result while also handling quote-refresh requests.\n *\n * Quotes from the Rhinestone orchestrator have a short TTL (typically ~60 s).\n * When the user takes too long to review and the quote expires, the dialog\n * sends `PASSKEY_REFRESH_QUOTE`. This method intercepts that message, calls\n * the provided `onRefresh` callback to fetch a new quote, and replies with\n * either `PASSKEY_REFRESH_COMPLETE` (success) or `PASSKEY_REFRESH_ERROR`\n * (failure) — allowing the dialog to stay open and show the updated fees\n * without requiring a full restart.\n *\n * Once the user confirms or rejects, the promise resolves with the signing\n * result exactly as `waitForSigningResponse` would.\n *\n * @param dialog - The `<dialog>` element wrapping the signing iframe.\n * @param iframe - The iframe element; used to post refresh messages back.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @param dialogOrigin - Trusted origin for message validation (passed in to\n * avoid redundant `getDialogOrigin()` calls from the hot path).\n * @param onRefresh - Async callback that fetches a fresh quote and returns the\n * updated intent fields, or `null` if the refresh failed.\n * @returns A `SigningResult` extended with an optional `signedHash`.\n */\n private waitForSigningWithRefresh(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n dialogOrigin: string,\n onRefresh: () => Promise<{\n intentOp: string;\n expiresAt: string;\n challenge: string;\n originMessages?: Array<{ chainId: number; hash: string }>;\n transaction?: unknown;\n digestResult?: unknown;\n /** Fresh prepare->execute binding for the refreshed quote (opaque). */\n binding?: string;\n /** Auth bundle re-bound to the refreshed intentOp — extension grants\n are digest-bound, so the dialog must swap auth with the quote. */\n auth?: SponsorshipTokens;\n } | null>\n ): Promise<SigningResult & { signedHash?: string }> {\n return new Promise((resolve) => {\n const handleMessage = async (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n\n // Handle quote refresh request from dialog\n if (message?.type === \"PASSKEY_REFRESH_QUOTE\") {\n const refreshedData = await onRefresh();\n\n if (refreshedData) {\n // Send refreshed quote data to dialog\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_COMPLETE\",\n ...refreshedData,\n }, dialogOrigin);\n } else {\n // Send error if refresh failed\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_ERROR\",\n error: \"Failed to refresh quote\",\n }, dialogOrigin);\n }\n return;\n }\n\n const payload = message?.data as {\n signature?: WebAuthnSignature;\n passkey?: { credentialId: string; publicKeyX: string; publicKeyY: string };\n signedHash?: string;\n intentId?: string;\n } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n\n // Check if dialog already executed the intent (new secure flow)\n if (message.success && payload?.intentId) {\n resolve({\n success: true,\n intentId: payload.intentId,\n } as SigningResult & { signedHash?: string; intentId?: string });\n } else if (message.success && payload?.signature) {\n // Legacy flow - dialog returns signature for SDK to execute\n resolve({\n success: true,\n signature: payload.signature,\n passkey: payload.passkey,\n signedHash: payload.signedHash,\n });\n } else {\n // Failure path: close the iframe. The passkey app sends the\n // follow-up `PASSKEY_CLOSE` after this `RESULT`, but we've just\n // removed the listener so it would be dropped on the floor —\n // tear down here so the user isn't stuck staring at a dialog\n // that's already done.\n cleanup();\n resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (\n message?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Cross-frame guard: ignore a stray PASSKEY_CLOSE from a sibling\n // same-origin dialog so it can't forge a rejection of this signing\n // request mid-refresh.\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Wait for the dialog to be explicitly closed by the user or the iframe.\n *\n * Resolves on either:\n * - `PASSKEY_CLOSE` postMessage from the iframe (user clicked the X button\n * or the dialog programmatically closed itself after showing a result).\n * - The native `<dialog> close` event (escape key or `dialog.close()` call).\n *\n * Calling `cleanup()` before awaiting this is safe — both resolution paths\n * call `cleanup()` internally but it is idempotent. The primary use case is\n * keeping the dialog open while the SDK polls for a transaction hash, then\n * showing the final success/error state before letting the user dismiss.\n *\n * @param dialog - The `<dialog>` element to watch.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n */\n private waitForDialogClose(\n dialog: HTMLDialogElement,\n cleanup: () => void\n ): Promise<void> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n if (event.data?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve();\n }\n };\n\n // Also handle dialog close via escape key or clicking outside\n const handleClose = () => {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n cleanup();\n resolve();\n };\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Hidden blind-signing iframes have no user-visible Done or Close button.\n * Once the SDK has the result it needs, tear them down immediately instead\n * of waiting for an iframe close event that can never be clicked.\n */\n private async waitForDialogCloseUnlessBlind(\n blindSigning: boolean,\n dialog: HTMLDialogElement,\n cleanup: () => void,\n ): Promise<void> {\n if (blindSigning) {\n cleanup();\n return;\n }\n await this.waitForDialogClose(dialog, cleanup);\n }\n\n /**\n * After a prepare error has been surfaced in the dialog, wait for the user\n * to either close the dialog (give up) or click \"Try Again\", which the\n * dialog forwards as `PASSKEY_RETRY_PREPARE`.\n *\n * On `\"closed\"` the dialog has been cleaned up; on `\"retry\"` it stays open\n * (showing its loading skeleton) while the caller re-runs prepare. Without\n * this, \"Try Again\" after a prepare failure was a dead end: the dialog\n * reset its local state but the SDK had already given up, so the quote\n * never arrived and the Sign button stayed disabled forever.\n */\n private waitForPrepareRetryOrClose(\n dialog: HTMLDialogElement,\n cleanup: () => void,\n ): Promise<\"retry\" | \"closed\"> {\n const dialogOrigin = this.getDialogOrigin();\n\n return new Promise((resolve) => {\n const stop = () => {\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_RETRY_PREPARE\") {\n stop();\n resolve(\"retry\");\n } else if (event.data?.type === \"PASSKEY_CLOSE\") {\n stop();\n cleanup();\n resolve(\"closed\");\n }\n };\n\n // Also handle dialog close via escape key or clicking outside\n const handleClose = () => {\n stop();\n cleanup();\n resolve(\"closed\");\n };\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Inject a `<link rel=\"preconnect\">` tag for the given URL's origin.\n *\n * Browsers use preconnect hints to resolve DNS, perform the TCP handshake,\n * and negotiate TLS before a resource is actually requested, reducing\n * time-to-first-byte when the dialog iframe loads. The tag is deduplicated —\n * if one already exists for the same origin it will not be added again.\n *\n * Only called in browser environments (guarded by `typeof document` in the\n * constructor). Invalid URLs are silently ignored.\n *\n * @param url - Any URL whose origin should be preconnected to.\n */\n private injectPreconnect(url: string): void {\n try {\n const origin = new URL(url).origin;\n if (document.querySelector(`link[rel=\"preconnect\"][href=\"${origin}\"]`)) return;\n const link = document.createElement(\"link\");\n link.rel = \"preconnect\";\n link.href = origin;\n link.crossOrigin = \"anonymous\";\n document.head.appendChild(link);\n } catch {\n // Invalid URL, skip\n }\n }\n\n /**\n * Warm the dialog ahead of the first user interaction.\n *\n * `preconnect` (run in the constructor) only warms DNS/TLS. This goes\n * further: it loads the dialog into a hidden, off-screen iframe so the\n * browser downloads and parses the dialog HTML + JS bundle and the font, and\n * keeps the cross-origin connection alive. When the user later opens a real\n * auth/sign dialog, the fresh iframe serves those bytes from cache over the\n * warm connection and paints far sooner — so the SDK preload overlay is shown\n * only briefly (or imperceptibly) instead of covering a full cold load.\n *\n * It loads a dedicated `/dialog/warm` route, NOT a real flow route. That\n * matters for two reasons:\n * - **No side effects.** The real `/dialog/auth` route runs the signup\n * flow on mount (identity probe → `POST /api/auth/register?step=start`),\n * which writes an `AuthChallenge` row and counts against the register\n * rate limiter. Warming must never create backend auth state for a user\n * who hasn't acted, so the warm route renders nothing and runs no flow.\n * - **No message cross-talk.** The warm route posts no `PASSKEY_READY` /\n * `PASSKEY_RENDERED`, so a slow warm can never satisfy a visible modal's\n * readiness listener and drive it to `PASSKEY_INIT` at the wrong moment.\n * The warm route still pulls the shared Next.js framework + main + dialog\n * layout chunks (the bulk of every flow's bundle), so the real open is fast.\n *\n * Best called on a *likely-intent* signal — `pointerenter`/`focus` of your\n * \"Sign in\" / \"Pay\" button — rather than on page load, so visitors who never\n * authenticate don't pay for a cross-origin iframe. Pass `prewarm: true` in\n * the client config to have the SDK schedule this once on an idle callback.\n *\n * Idempotent: repeated calls return the same in-flight/settled promise.\n * Resolves `true` once the hidden iframe's document has loaded, `false` on\n * timeout or failure. Never throws and never blocks a real dialog open — a\n * failed prewarm just means the next open does a normal (cold) load.\n *\n * @returns Whether the dialog became warm.\n */\n async prewarm(): Promise<boolean> {\n if (typeof document === \"undefined\") return false;\n // Idempotent: a second call (e.g. hover after an idle-scheduled warm)\n // rides the first one's load instead of opening another iframe.\n if (this.prewarmState) return this.prewarmState.ready;\n\n // Dedicated warm route — silent and side-effect-free (see method doc). No\n // theme/flow params needed: it renders nothing, and query strings don't\n // affect caching of the hashed JS chunks the real open reuses.\n const warmUrl = `${this.getDialogUrl()}/dialog/warm`;\n\n // A bare hidden iframe — deliberately NOT the full createModalDialog\n // chrome (no <dialog>, overlay, Escape handler or showModal). We only need\n // the browser to fetch + run the bundle; none of the modal lifecycle\n // applies to a frame the user never sees.\n const iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\"aria-hidden\", \"true\");\n iframe.setAttribute(\"tabindex\", \"-1\");\n iframe.title = \"1auth dialog prewarm\";\n // Off-screen + inert so it can never intercept clicks or take focus, while\n // still being \"rendered\" (display:none would let some browsers defer the\n // load we are trying to trigger).\n iframe.style.cssText =\n \"position:fixed;left:-9999px;top:0;width:1px;height:1px;opacity:0;border:0;pointer-events:none;\";\n\n // Resolve on the iframe `load` event rather than a postMessage. The warm\n // route is intentionally message-silent, and `load` fires for cross-origin\n // frames too (we never touch contentDocument), so it is the right\n // signal — and one a stray frame's messages can never spoof.\n const ready = new Promise<boolean>((resolve) => {\n let settled = false;\n const finish = (value: boolean) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n resolve(value);\n };\n iframe.onload = () => finish(true);\n iframe.onerror = () => finish(false);\n // Failsafe so the promise always settles even if `load` is missed.\n const timer = setTimeout(() => finish(false), 10000);\n });\n iframe.src = warmUrl;\n document.body.appendChild(iframe);\n\n this.prewarmState = { iframe, ready };\n return ready;\n }\n\n /**\n * Tear down the hidden prewarm iframe created by {@link prewarm}.\n *\n * The HTTP cache that prewarm populated survives teardown, so a subsequent\n * open is still bundle-warm; this only releases the parked frame (and its\n * keep-alive connection). Call it when auth is no longer likely on the\n * current view. Safe to call when nothing is warmed.\n */\n destroyPrewarm(): void {\n const state = this.prewarmState;\n if (!state) return;\n this.prewarmState = null;\n state.iframe.remove();\n }\n\n /**\n * Wait for the dialog iframe to signal ready, but defer sending `PASSKEY_INIT`\n * until the caller decides the time is right.\n *\n * This is the deferred variant of `waitForDialogReady`, used by flows that run\n * the dialog and a background API call in parallel (the \"two-phase\" approach).\n * Rather than blocking until both the iframe is ready AND the API call is done,\n * this method resolves as soon as `PASSKEY_READY` arrives and returns a\n * `sendInit` callback. The caller invokes `sendInit` once prepare data is\n * available, which may happen before or after the iframe is ready.\n *\n * Timeout: if the iframe never signals ready within 10 seconds (e.g. network\n * error, origin mismatch), resolves with `{ ready: false }` and calls cleanup.\n *\n * @param dialog - The `<dialog>` element wrapping the iframe.\n * @param iframe - The iframe element that will receive `PASSKEY_INIT`.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @returns `{ ready: true, sendInit }` when the iframe is ready, or\n * `{ ready: false }` if the dialog was closed or timed out first.\n */\n private waitForDialogReadyDeferred(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n options: { blindSigning?: boolean; reveal?: () => void } = {},\n ): Promise<\n | { ready: true; blindSigning: boolean; sendInit: (initMessage: Record<string, unknown>) => void }\n | { ready: false }\n > {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let settled = false;\n\n const teardown = () => {\n if (settled) return;\n settled = true;\n clearTimeout(readyTimeout);\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n const blindSigning = options.blindSigning === true;\n teardown();\n resolve({\n ready: true,\n blindSigning,\n sendInit: (initMessage: Record<string, unknown>) => {\n if (blindSigning) iframe.focus({ preventScroll: true });\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initMessage, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n },\n });\n } else if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Match by source, not just origin: the auth dialog (authWithModal)\n // emits a stray PASSKEY_CLOSE from the SAME origin as it tears down.\n // Without the source check, that close resolves the sign dialog's\n // ready-promise as { ready: false } → dialogClosedBeforeReadyPromise\n // → a spurious USER_CANCELLED (\"closed before it became ready\").\n // Identical guard to the earlyDialogClosePromise fix.\n teardown();\n cleanup();\n resolve({ ready: false });\n }\n };\n\n const handleClose = () => {\n teardown();\n resolve({ ready: false });\n };\n\n const readyTimeout = setTimeout(() => {\n teardown();\n cleanup();\n resolve({ ready: false });\n }, 10000);\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Call the passkey service to obtain a Rhinestone orchestrator quote for an\n * intent (a single target-chain transaction or swap).\n *\n * The service contacts the Rhinestone orchestrator, which returns a signed\n * `intentOp` structure containing the quote, fees, and a WebAuthn challenge\n * the user must sign to authorize execution.\n *\n * The `X-Origin-Tier` response header is forwarded to the dialog so it can\n * display tier-specific UI (e.g. \"Free\" vs \"Premium\" badge).\n *\n * Side effect: if the server returns \"User not found\", the cached user entry\n * is removed from `localStorage` to force re-authentication.\n *\n * @param requestBody - Serialized intent options (bigint amounts converted to\n * strings before this call).\n * @returns On success: `{ success: true, data: PrepareIntentResponse, tier }`.\n * On failure: `{ success: false, error: { code, message, details? } }`.\n */\n private async prepareIntent(\n requestBody: Record<string, unknown>,\n telemetry?: TelemetryOperation,\n ): Promise<\n | { success: true; data: PrepareIntentResponse; tier: string | null }\n | { success: false; error: { code: string; message: string; details?: unknown } }\n > {\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error || \"Failed to prepare intent\";\n\n if (errorMessage.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n }\n\n return {\n success: false,\n error: {\n code: errorMessage.includes(\"User not found\") ? \"USER_NOT_FOUND\" : \"PREPARE_FAILED\",\n message: errorMessage,\n details: errorData.details ?? errorData.candidateErrors ?? errorData,\n },\n };\n }\n\n const tier = response.headers.get(\"X-Origin-Tier\");\n return { success: true, data: await response.json(), tier };\n } catch (error) {\n return {\n success: false,\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network error\",\n },\n };\n }\n }\n\n /**\n * Call the passkey service to obtain orchestrator quotes for all intents in a\n * batch, returning a single shared WebAuthn challenge.\n *\n * The service prepares each intent independently and assembles a merkle tree\n * whose root becomes the challenge. Signing that root once authorizes every\n * intent in the batch. Partially-failed batches are supported: the response\n * includes both `intents` (succeeded) and `failedIntents` (per-intent errors),\n * so the dialog can still show the successful subset for signing.\n *\n * Side effect: same \"User not found\" localStorage cleanup as `prepareIntent`.\n *\n * @param requestBody - Serialized batch options (bigint amounts converted to\n * strings before this call).\n * @returns On success: `{ success: true, data: PrepareBatchIntentResponse, tier }`.\n * On failure: `{ success: false, error, failedIntents? }`.\n */\n private async prepareBatchIntent(\n requestBody: Record<string, unknown>,\n telemetry?: TelemetryOperation,\n ): Promise<\n | { success: true; data: PrepareBatchIntentResponse; tier: string | null }\n | { success: false; error: string; failedIntents?: Array<{ index: number; targetChain: number; error: string }> }\n > {\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...this.telemetryHeaders(telemetry) },\n body: JSON.stringify(requestBody),\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n const errorMessage = errorData.error || \"Failed to prepare batch intent\";\n\n if (errorMessage.includes(\"User not found\")) {\n localStorage.removeItem(\"1auth-user\");\n }\n\n return {\n success: false,\n error: errorMessage,\n failedIntents: errorData.failedIntents,\n };\n }\n\n const tier = response.headers.get(\"X-Origin-Tier\");\n return { success: true, data: await response.json(), tier };\n } catch {\n return { success: false, error: \"Network error\" };\n }\n }\n\n /**\n * Forward a prepare-phase error to the dialog iframe so it can display a\n * human-readable failure message instead of hanging on the loading state.\n *\n * The dialog listens for `PASSKEY_PREPARE_ERROR` and transitions to an error\n * view. The user can then dismiss the dialog, at which point\n * `waitForDialogClose` resolves and the SDK returns the error to the caller.\n *\n * @param iframe - The iframe element to post the error to.\n * @param error - Human-readable error message from the prepare response.\n */\n private sendPrepareError(iframe: HTMLIFrameElement, error: string): void {\n const dialogOrigin = this.getDialogOrigin();\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_PREPARE_ERROR\", error },\n dialogOrigin,\n );\n }\n\n /**\n * Poll for intent status\n *\n * Use this to check on the status of a submitted intent\n * that hasn't completed yet.\n */\n async getIntentStatus(intentId: string): Promise<SendIntentResult> {\n const telemetry = this.createTelemetryOperation(\"status\");\n this.emitTelemetry(\"intent.status.started\", telemetry, {\n outcome: \"started\",\n attributes: { directStatusCheck: true },\n });\n try {\n const response = await fetch(\n `${this.config.providerUrl}/api/intent/status/${intentId}`,\n {\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n this.emitTelemetry(\"status.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"STATUS_FAILED\",\n errorMessage: errorData.error || \"Failed to get intent status\",\n });\n return {\n success: false,\n intentId,\n status: \"failed\",\n error: {\n code: \"STATUS_FAILED\",\n message: errorData.error || \"Failed to get intent status\",\n },\n };\n }\n\n const data = await response.json();\n this.emitTelemetry(\"status.succeeded\", telemetry, {\n outcome: data.status === \"completed\" ? \"success\" : \"started\",\n status: data.status,\n });\n return {\n success: data.status === \"completed\",\n intentId,\n status: data.status,\n transactionHash: data.transactionHash,\n operationId: data.operationId,\n };\n } catch (error) {\n this.emitTelemetry(\"status.failed\", telemetry, {\n outcome: \"failure\",\n ...describeTelemetryError(error),\n });\n return {\n success: false,\n intentId,\n status: \"failed\",\n error: {\n code: \"NETWORK_ERROR\",\n message: error instanceof Error ? error.message : \"Network error\",\n },\n };\n }\n }\n\n /**\n * Get the history of intents for the authenticated user.\n *\n * Requires an active session (user must be logged in).\n *\n * @example\n * ```typescript\n * // Get recent intents\n * const history = await client.getIntentHistory({ limit: 10 });\n *\n * // Filter by status\n * const pending = await client.getIntentHistory({ status: 'pending' });\n *\n * // Filter by date range\n * const lastWeek = await client.getIntentHistory({\n * from: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString(),\n * });\n * ```\n */\n async getIntentHistory(\n options?: IntentHistoryOptions\n ): Promise<IntentHistoryResult> {\n const telemetry = this.createTelemetryOperation(\"history\", {\n hasStatusFilter: !!options?.status,\n });\n const queryParams = new URLSearchParams();\n if (options?.limit) queryParams.set(\"limit\", String(options.limit));\n if (options?.offset) queryParams.set(\"offset\", String(options.offset));\n if (options?.status) queryParams.set(\"status\", options.status);\n if (options?.from) queryParams.set(\"from\", options.from);\n if (options?.to) queryParams.set(\"to\", options.to);\n\n const url = `${this.config.providerUrl}/api/intent/history${\n queryParams.toString() ? `?${queryParams}` : \"\"\n }`;\n\n const response = await fetch(url, {\n headers: {\n ...this.telemetryHeaders(telemetry),\n ...(this.config.clientId ? { \"x-client-id\": this.config.clientId } : {}),\n },\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n this.emitTelemetry(\"history.failed\", telemetry, {\n outcome: \"failure\",\n errorCode: \"HISTORY_FAILED\",\n errorMessage: errorData.error || \"Failed to get intent history\",\n });\n throw new Error(errorData.error || \"Failed to get intent history\");\n }\n\n const result = await response.json();\n this.emitTelemetry(\"history.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: {\n total: result.total,\n returned: result.intents?.length ?? 0,\n },\n });\n return result;\n }\n\n /**\n * Forward a raw EIP-1193 request to the iframe so the active EOA connector\n * can handle it (wallet-connect session or injected wallet). Opens\n * `/dialog/sign-eoa`, which looks up the wagmi connector and delegates to\n * `connector.getProvider().request({ method, params })`. The wallet's own\n * UI is the review screen; the dialog just transports the request.\n */\n async requestWithWallet(options: {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n expectedAddress?: `0x${string}`;\n theme?: ThemeConfig;\n }): Promise<\n | { success: true; result: unknown }\n | { success: false; error: { code: string; message: string } }\n > {\n // Serialise concurrent calls: the EOA iframe is a single shared resource\n // and the iframe's view + classifyInit state assume one in-flight\n // request at a time.\n const job = this.eoaSerialQueue.then(\n () => this.doRequestWithWallet(options),\n () => this.doRequestWithWallet(options),\n );\n this.eoaSerialQueue = job.then(\n () => undefined,\n () => undefined,\n );\n return job;\n }\n\n private async doRequestWithWallet(options: {\n method: string;\n params?: unknown[] | Record<string, unknown>;\n expectedAddress?: `0x${string}`;\n theme?: ThemeConfig;\n }): Promise<\n | { success: true; result: unknown }\n | { success: false; error: { code: string; message: string } }\n > {\n const dialogOrigin = this.getDialogOrigin();\n const ensureResult = await this.ensureEoaDialog(options?.theme);\n if (!ensureResult.ok) {\n return {\n success: false,\n error: { code: \"USER_REJECTED\", message: \"User closed the dialog\" },\n };\n }\n const { dialog, iframe } = ensureResult;\n\n // requestId binds the SDK call to its dialog instance. Required for\n // every subsequent message: the dialog echoes it on PASSKEY_EOA_RESULT\n // and PASSKEY_EOA_CLOSE so stale messages from a previous flow cannot\n // cross-resolve this promise.\n const requestId =\n typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\"\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n const hideDialog = () => {\n if (dialog.open) dialog.close();\n };\n\n // Install the result listener BEFORE PASSKEY_INIT is sent. Fast methods\n // like wallet_getCallsStatus can resolve in the same task as the init\n // and emit PASSKEY_EOA_RESULT before a listener attached afterward\n // would see it.\n const responsePromise = this.waitForEoaResponse(\n iframe,\n hideDialog,\n requestId,\n dialogOrigin,\n );\n\n const initPayload = {\n mode: \"iframe\",\n method: options.method,\n params: options.params,\n expectedAddress: options.expectedAddress,\n requestId,\n };\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n dialogOrigin,\n );\n\n // The iframe may re-emit PASSKEY_READY if its React tree remounts\n // (HMR, Suspense). Re-send PASSKEY_INIT so it picks the current\n // request up — keyed on the same requestId, which the iframe dedupes.\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n const result = await responsePromise;\n window.removeEventListener(\"message\", handleReReady);\n hideDialog();\n return result;\n }\n\n /**\n * Lazily create the persistent `/dialog/sign-eoa` iframe and reveal it.\n * Subsequent calls just re-open the existing `<dialog>` so the iframe's\n * in-page state (notably the WalletConnect SignClient) is preserved\n * between transactions.\n */\n private async ensureEoaDialog(theme: ThemeConfig | undefined): Promise<\n | { ok: true; dialog: HTMLDialogElement; iframe: HTMLIFrameElement }\n | { ok: false }\n > {\n if (this.eoaDialogState) {\n const { dialog, iframe } = this.eoaDialogState;\n if (!dialog.open) {\n // dialog.showModal() throws if already open — guarded above.\n dialog.showModal();\n }\n return { ok: true, dialog, iframe };\n }\n\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n // Keep the persistent EOA iframe on the same parent-origin hint path as\n // the other dialog routes; the passkey app still authenticates the caller\n // from browser-provided referrer/event.origin before trusting it.\n appendParentOriginParam(params);\n const themeParams = this.getThemeParams(theme);\n if (themeParams) {\n new URLSearchParams(themeParams).forEach((value, key) => {\n params.set(key, value);\n });\n }\n const signingUrl = `${dialogUrl}/dialog/sign-eoa?${params.toString()}`;\n\n const { dialog, iframe, destroy } = this.createModalDialog(signingUrl, {\n persistent: true,\n });\n\n const ready = await this.waitForEoaIframeReady(iframe);\n if (!ready) {\n // Iframe never came up — fully tear down and surface as a rejection.\n // Next call will retry from scratch.\n destroy();\n return { ok: false };\n }\n\n this.eoaDialogState = { dialog, iframe };\n return { ok: true, dialog, iframe };\n }\n\n private waitForEoaIframeReady(iframe: HTMLIFrameElement): Promise<boolean> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let timeoutId: ReturnType<typeof setTimeout> | null = null;\n const cleanup = () => {\n if (timeoutId !== null) clearTimeout(timeoutId);\n window.removeEventListener(\"message\", handler);\n };\n const handler = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n cleanup();\n resolve(true);\n }\n };\n window.addEventListener(\"message\", handler);\n timeoutId = setTimeout(() => {\n cleanup();\n resolve(false);\n }, 10000);\n });\n }\n\n private waitForEoaResponse(\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n requestId: string,\n dialogOrigin: string,\n ): Promise<\n | { success: true; result: unknown }\n | { success: false; error: { code: string; message: string } }\n > {\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n // Three trust checks before reading any payload:\n // 1. event.origin pinned to the dialog origin\n // 2. event.source pinned to this iframe's contentWindow (rejects\n // messages from sibling frames or popups that grabbed a window\n // reference)\n // 3. requestId echoed by the dialog matches ours (rejects stale\n // messages from a prior remount or a concurrent dialog)\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n const message = event.data;\n if (\n message?.type === \"PASSKEY_EOA_RESULT\" ||\n message?.type === \"PASSKEY_EOA_CLOSE\"\n ) {\n if (message.requestId !== requestId) return;\n } else {\n return;\n }\n window.removeEventListener(\"message\", handleMessage);\n if (message.type === \"PASSKEY_EOA_CLOSE\") {\n cleanup();\n resolve({\n success: false,\n error: { code: \"USER_REJECTED\", message: \"User closed the dialog\" },\n });\n return;\n }\n if (message.success) {\n resolve({ success: true, result: message.data?.result });\n } else {\n resolve({\n success: false,\n error: message.error || {\n code: \"EOA_REQUEST_FAILED\",\n message: \"Wallet request failed\",\n },\n });\n }\n };\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Sign an arbitrary message with the user's passkey\n *\n * This is for off-chain message signing (e.g., authentication challenges,\n * terms acceptance, login signatures), NOT for transaction signing.\n * The message is displayed to the user and signed with their passkey.\n *\n * @example\n * ```typescript\n * // Sign a login challenge\n * const result = await client.signMessage({\n * accountAddress: '0x...',\n * message: `Sign in to MyApp\\nTimestamp: ${Date.now()}\\nNonce: ${crypto.randomUUID()}`,\n * description: 'Verify your identity to continue',\n * });\n *\n * if (result.success) {\n * // Send signature to your backend for verification\n * await fetch('/api/verify', {\n * method: 'POST',\n * body: JSON.stringify({\n * signature: result.signature,\n * message: result.signedMessage,\n * }),\n * });\n * }\n * ```\n */\n async signMessage(options: SignMessageOptions): Promise<SignMessageResult> {\n const telemetry = this.createTelemetryOperation(\"sign\", {\n signingMode: \"message\",\n hasAccountAddress: !!options.accountAddress,\n });\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n if (!dialogResult.ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_REJECTED\",\n errorMessage: \"User closed the dialog before signing\",\n });\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n\n const initPayload = {\n mode: \"iframe\",\n message: options.message,\n challenge: options.challenge || options.message,\n accountAddress: options.accountAddress,\n description: options.description,\n metadata: options.metadata,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(initPayload);\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n // Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n // so the sign page recovers its state.\n const dialogOrigin = this.getDialogOrigin();\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);\n\n window.removeEventListener(\"message\", handleReReady);\n cleanup();\n\n if (signingResult.success) {\n this.emitTelemetry(\"sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { signingMode: \"message\" },\n });\n return {\n success: true,\n signature: signingResult.signature,\n signedMessage: options.message,\n signedHash: signingResult.signedHash as `0x${string}` | undefined,\n passkey: signingResult.passkey,\n };\n }\n\n this.emitTelemetry(\n signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n telemetry,\n {\n outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingResult.error),\n attributes: { signingMode: \"message\" },\n },\n );\n return {\n success: false,\n error: signingResult.error,\n };\n }\n\n /**\n * Sign EIP-712 typed data with the user's passkey\n *\n * This method allows signing structured data following the EIP-712 standard.\n * The typed data is displayed to the user in a human-readable format before signing.\n *\n * @example\n * ```typescript\n * // Sign an ERC-2612 Permit\n * const result = await client.signTypedData({\n * accountAddress: '0x...',\n * domain: {\n * name: 'Dai Stablecoin',\n * version: '1',\n * chainId: 1,\n * verifyingContract: '0x6B175474E89094C44Da98b954EecdeCB5BE3830F',\n * },\n * types: {\n * Permit: [\n * { name: 'owner', type: 'address' },\n * { name: 'spender', type: 'address' },\n * { name: 'value', type: 'uint256' },\n * { name: 'nonce', type: 'uint256' },\n * { name: 'deadline', type: 'uint256' },\n * ],\n * },\n * primaryType: 'Permit',\n * message: {\n * owner: '0xabc...',\n * spender: '0xdef...',\n * value: 1000000000000000000n,\n * nonce: 0n,\n * deadline: 1735689600n,\n * },\n * });\n *\n * if (result.success) {\n * console.log('Signed hash:', result.signedHash);\n * }\n * ```\n */\n async signTypedData(options: SignTypedDataOptions): Promise<SignTypedDataResult> {\n const telemetry = this.createTelemetryOperation(\"sign\", {\n signingMode: \"typedData\",\n primaryType: options.primaryType,\n hasAccountAddress: !!options.accountAddress,\n });\n // Compute the EIP-712 hash using viem\n // Use unknown cast to work around viem's strict template literal type requirements\n const signedHash = hashTypedData({\n domain: options.domain,\n types: options.types,\n primaryType: options.primaryType,\n message: options.message,\n } as unknown as TypedDataDefinition);\n\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({ mode: \"iframe\" });\n appendParentOriginParam(params);\n this.appendTelemetryParams(params, telemetry);\n const themeParams = this.getThemeParams(options?.theme);\n if (themeParams) {\n const themeParsed = new URLSearchParams(themeParams);\n themeParsed.forEach((value, key) => params.set(key, value));\n }\n const signingUrl = `${dialogUrl}/dialog/sign?${params.toString()}`;\n const requestedBlindSigning = this.shouldRequestBlindSigning(options);\n\n const { dialog, iframe, cleanup, reveal } = this.createModalDialog(signingUrl, {\n hidden: requestedBlindSigning,\n });\n this.emitTelemetry(\"dialog.opened\", telemetry, {\n outcome: \"started\",\n attributes: { blindSigning: requestedBlindSigning },\n });\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup, {\n blindSigning: requestedBlindSigning,\n reveal,\n });\n if (!dialogResult.ready) {\n this.emitTelemetry(\"dialog.cancelled\", telemetry, {\n outcome: \"cancelled\",\n errorCode: \"USER_REJECTED\",\n errorMessage: \"User closed the dialog before signing\",\n });\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n\n const initPayload = {\n mode: \"iframe\",\n signingMode: \"typedData\",\n typedData: {\n domain: options.domain,\n types: options.types,\n primaryType: options.primaryType,\n message: options.message,\n },\n challenge: signedHash,\n accountAddress: options.accountAddress,\n description: options.description,\n telemetry: this.telemetryPayload(telemetry),\n };\n dialogResult.sendInit(initPayload);\n const blindSigning = dialogResult.blindSigning;\n this.emitTelemetry(\"dialog.ready\", telemetry, { outcome: \"started\" });\n\n // Handle iframe remount: if the dialog re-sends PASSKEY_READY (e.g. due to\n // React strict mode, Next.js Suspense, or code-splitting), resend PASSKEY_INIT\n // so the sign page recovers its state.\n const dialogOrigin = this.getDialogOrigin();\n const handleReReady = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true, blindSigning },\n dialogOrigin,\n );\n }\n };\n window.addEventListener(\"message\", handleReReady);\n\n const signingResult = await this.waitForSigningResponse(dialog, iframe, cleanup);\n\n window.removeEventListener(\"message\", handleReReady);\n cleanup();\n\n if (signingResult.success) {\n this.emitTelemetry(\"sign.succeeded\", telemetry, {\n outcome: \"success\",\n attributes: { signingMode: \"typedData\", primaryType: options.primaryType },\n });\n return {\n success: true,\n signature: signingResult.signature,\n signedHash,\n passkey: signingResult.passkey,\n };\n }\n\n this.emitTelemetry(\n signingResult.error?.code === \"USER_REJECTED\" ? \"dialog.cancelled\" : \"sign.failed\",\n telemetry,\n {\n outcome: signingResult.error?.code === \"USER_REJECTED\" ? \"cancelled\" : \"failure\",\n ...describeTelemetryError(signingResult.error),\n attributes: { signingMode: \"typedData\", primaryType: options.primaryType },\n },\n );\n return {\n success: false,\n error: signingResult.error,\n };\n }\n\n async signWithPopup(options: SigningRequestOptions): Promise<SigningResult> {\n const request = await this.createSigningRequest(options, \"popup\");\n\n // Use dialogUrl to construct the signing URL (override server's URL)\n const dialogUrl = this.getDialogUrl();\n const signingUrl = `${dialogUrl}/dialog/sign/${request.requestId}?mode=popup`;\n\n const popup = this.openPopup(signingUrl);\n if (!popup) {\n return {\n success: false,\n error: {\n code: \"POPUP_BLOCKED\",\n message:\n \"Popup was blocked by the browser. Please allow popups for this site.\",\n },\n };\n }\n\n return this.waitForPopupResponse(request.requestId, popup);\n }\n\n async signWithRedirect(\n options: SigningRequestOptions,\n redirectUrl?: string\n ): Promise<void> {\n const finalRedirectUrl = redirectUrl || this.config.redirectUrl;\n if (!finalRedirectUrl) {\n throw new Error(\n \"redirectUrl is required for redirect flow. Pass it to signWithRedirect() or set it in the constructor.\"\n );\n }\n\n const request = await this.createSigningRequest(\n options,\n \"redirect\",\n finalRedirectUrl\n );\n\n // Use dialogUrl to construct the signing URL (override server's URL)\n const dialogUrl = this.getDialogUrl();\n const signingUrl = `${dialogUrl}/dialog/sign/${request.requestId}?mode=redirect&redirectUrl=${encodeURIComponent(finalRedirectUrl)}`;\n\n window.location.href = signingUrl;\n }\n\n async signWithEmbed(\n options: SigningRequestOptions,\n embedOptions: EmbedOptions\n ): Promise<SigningResult> {\n const request = await this.createSigningRequest(options, \"embed\");\n\n const iframe = this.createEmbed(request.requestId, embedOptions);\n\n return this.waitForEmbedResponse(request.requestId, iframe, embedOptions);\n }\n\n /**\n * Create and append a signing iframe to a caller-supplied container element.\n *\n * Used by the `signWithEmbed` flow where the integrator wants the signing UI\n * to appear inline on their page rather than in a modal overlay. The iframe\n * loads a pre-created signing request URL and fires `options.onReady` once\n * the page has loaded.\n *\n * @param requestId - The signing request ID; used to construct the iframe src\n * and give it a stable DOM id for later removal via `removeEmbed`.\n * @param options - Embed configuration including the container element,\n * optional dimensions, and lifecycle callbacks.\n * @returns The created `<iframe>` element (already appended to the container).\n */\n private createEmbed(\n requestId: string,\n options: EmbedOptions\n ): HTMLIFrameElement {\n const dialogUrl = this.getDialogUrl();\n const iframe = document.createElement(\"iframe\");\n iframe.src = `${dialogUrl}/dialog/sign/${requestId}?mode=iframe`;\n iframe.style.width = options.width || DEFAULT_EMBED_WIDTH;\n iframe.style.height = options.height || DEFAULT_EMBED_HEIGHT;\n iframe.style.border = \"none\";\n iframe.style.borderRadius = \"12px\";\n iframe.style.boxShadow = \"0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)\";\n iframe.id = `passkey-embed-${requestId}`;\n iframe.allow = \"publickey-credentials-get *; publickey-credentials-create *; identity-credentials-get\";\n\n iframe.onload = () => {\n options.onReady?.();\n };\n\n options.container.appendChild(iframe);\n\n // Tell the dialog about the parent's viewport so DialogCard can\n // cap itself at 75% of the user's screen instead of auto-growing\n // for long sign flows (e.g. a 20-action transaction). Without\n // this, the dialog falls back to its old infinite-growth\n // behaviour and the scroll-gated Sign button never fires.\n this.wireViewportInfo(iframe);\n\n // Auto-resize the iframe to the dialog's natural content height.\n // Without this, taller screens (e.g. signup with the email field\n // ~552px) get clipped against the fixed `DEFAULT_EMBED_HEIGHT`, and\n // shorter screens leave dead space below. The dialog measures its\n // card via ResizeObserver and posts `PASSKEY_RESIZE` on every change.\n const host = new URL(dialogUrl);\n const onResize = (event: MessageEvent) => {\n if (event.source !== iframe.contentWindow) return;\n if (event.origin !== host.origin) return;\n if (event.data?.type !== \"PASSKEY_RESIZE\") return;\n const h = Number(event.data.height);\n if (Number.isFinite(h) && h > 0) {\n iframe.style.height = `${h}px`;\n }\n };\n window.addEventListener(\"message\", onResize);\n // ResizeObserver in the iframe keeps firing for the dialog's\n // lifetime; we leave the listener attached until the iframe is\n // removed via `removeEmbed`. No cleanup hook is exposed by\n // `createEmbed`; document a follow-up here if leak becomes an issue.\n\n return iframe;\n }\n\n /**\n * Post `PASSKEY_VIEWPORT_INFO` with the parent's\n * `window.innerHeight` to the iframe whenever it signals\n * `PASSKEY_READY`, and re-post on `window.resize` (rAF-debounced)\n * so the dialog's internal max-height cap follows the user's\n * actual screen.\n *\n * Inside the iframe, `vh`/`dvh` units refer to the iframe's own\n * height (recursive when the iframe auto-sizes), so the parent is\n * the only reliable source of \"what 75% of the user's screen is\".\n * The dialog stores the value in `dialog-context` and falls back\n * to auto-grow when the value is absent — so it's safe to call\n * this even for embedders that don't actually cap (modal mode\n * uses `fullViewport` which has its own outer cap).\n */\n private wireViewportInfo(iframe: HTMLIFrameElement): () => void {\n const dialogOrigin = this.getDialogOrigin();\n\n const post = () => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_VIEWPORT_INFO\", height: window.innerHeight },\n dialogOrigin,\n );\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.source !== iframe.contentWindow) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n post();\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // rAF-debounced resize. Coalesces drag-resize bursts to one post\n // per animation frame so we don't spam the iframe with messages.\n let raf: number | null = null;\n const onResize = () => {\n if (raf !== null) return;\n raf = requestAnimationFrame(() => {\n raf = null;\n post();\n });\n };\n window.addEventListener(\"resize\", onResize);\n\n return () => {\n window.removeEventListener(\"message\", handleMessage);\n window.removeEventListener(\"resize\", onResize);\n if (raf !== null) cancelAnimationFrame(raf);\n };\n }\n\n /**\n * Listen for a signing result from an embedded (inline) signing iframe.\n *\n * Matches incoming `PASSKEY_SIGNING_RESULT` messages against `requestId`\n * to avoid reacting to messages from other iframes on the page. On resolution\n * (success or failure), the iframe is removed from the DOM and\n * `embedOptions.onClose` is invoked.\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param iframe - The embedded signing iframe.\n * @param embedOptions - Embed configuration; `onClose` is called after cleanup.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForEmbedResponse(\n requestId: string,\n iframe: HTMLIFrameElement,\n embedOptions: EmbedOptions\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const cleanup = () => {\n window.removeEventListener(\"message\", handleMessage);\n iframe.remove();\n embedOptions.onClose?.();\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) {\n return;\n }\n\n const message = event.data;\n // The Messenger sends: { type, success, data: { requestId, signature }, error }\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n if (\n message?.type === \"PASSKEY_SIGNING_RESULT\" &&\n payload?.requestId === requestId\n ) {\n cleanup();\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n });\n } else {\n resolve({\n success: false,\n requestId,\n error: message.error,\n });\n }\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n removeEmbed(requestId: string): void {\n const iframe = document.getElementById(`passkey-embed-${requestId}`);\n if (iframe) {\n iframe.remove();\n }\n }\n\n async handleRedirectCallback(): Promise<SigningResult> {\n const params = new URLSearchParams(window.location.search);\n const requestId = params.get(\"request_id\");\n const status = params.get(\"status\");\n const error = params.get(\"error\");\n const errorMessage = params.get(\"error_message\");\n\n if (error) {\n return {\n success: false,\n requestId: requestId || undefined,\n error: {\n code: error as SigningResult extends { success: false }\n ? SigningResult[\"error\"][\"code\"]\n : never,\n message: errorMessage || \"Unknown error\",\n },\n };\n }\n\n if (!requestId) {\n return {\n success: false,\n error: {\n code: \"INVALID_REQUEST\",\n message: \"No request_id found in callback URL\",\n },\n };\n }\n\n if (status !== \"completed\") {\n return {\n success: false,\n requestId,\n error: {\n code: \"UNKNOWN\",\n message: `Unexpected status: ${status}`,\n },\n };\n }\n\n return this.fetchSigningResult(requestId);\n }\n\n /**\n * Fetch passkeys for a user from the auth provider.\n *\n * The account address is the sole identity; the backend `resolveUserWhere`\n * accepts an address as a globally-unique path identifier.\n */\n async getPasskeys(accountAddress: string): Promise<PasskeyCredential[]> {\n const response = await fetch(\n `${this.config.providerUrl}/api/users/${encodeURIComponent(accountAddress)}/passkeys`,\n {\n headers: this.config.clientId\n ? { \"x-client-id\": this.config.clientId }\n : {},\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || errorData.message || \"Failed to fetch passkeys\");\n }\n\n const data: UserPasskeysResponse = await response.json();\n return data.passkeys;\n }\n\n /**\n * Register a signing request with the passkey service and receive a\n * short-lived `requestId`.\n *\n * Used by the legacy popup, redirect, and embed flows. The passkey service\n * stores the challenge and metadata server-side so the dialog page can fetch\n * them by `requestId` without relying on URL parameters alone. This avoids\n * exposing potentially large challenge payloads in query strings.\n *\n * @param options - The signing options (challenge, accountAddress, description, etc.).\n * @param mode - How the dialog will be opened (`\"popup\"`, `\"redirect\"`, or `\"embed\"`).\n * @param redirectUrl - Only required for `\"redirect\"` mode; the URL the dialog\n * will navigate back to after signing.\n * @returns The created signing request with its unique `requestId`.\n * @throws If the API call fails.\n */\n private async createSigningRequest(\n options: SigningRequestOptions,\n mode: \"popup\" | \"redirect\" | \"embed\",\n redirectUrl?: string\n ): Promise<CreateSigningRequestResponse> {\n const response = await fetch(\n `${this.config.providerUrl}/api/sign/request`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n ...(this.config.clientId && { clientId: this.config.clientId }),\n accountAddress: options.accountAddress,\n challenge: options.challenge,\n description: options.description,\n metadata: options.metadata,\n transaction: options.transaction,\n mode,\n redirectUrl,\n }),\n }\n );\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || errorData.message || \"Failed to create signing request\");\n }\n\n return response.json();\n }\n\n /**\n * Open a centered popup window for the signing or auth dialog.\n *\n * Positions the popup near the top of the current window (50px from the top)\n * and horizontally centered relative to the browser window. Uses `popup=true`\n * to request a minimal chrome popup (no address bar) on browsers that support\n * the Window Management API.\n *\n * @param url - The full URL to open in the popup.\n * @returns The popup `Window` reference, or `null` if the browser blocked it.\n */\n private openPopup(url: string): Window | null {\n const left = window.screenX + (window.outerWidth - POPUP_WIDTH) / 2;\n const top = window.screenY + 50; // Near top of window\n\n return window.open(\n url,\n \"passkey-signing\",\n `width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top},popup=true`\n );\n }\n\n /**\n * Wait for the dialog iframe to signal ready, then immediately send init data.\n *\n * This is the synchronous-init variant: `initMessage` is available at call\n * time, so it can be posted as soon as `PASSKEY_READY` arrives. Use\n * `waitForDialogReadyDeferred` when init data depends on an in-flight API call.\n *\n * Also handles early close (X button, escape key, backdrop click) during the\n * ready phase so those paths resolve cleanly without leaking event listeners.\n *\n * Timeout: resolves `false` after 10 seconds if the iframe never signals ready\n * (e.g. origin mismatch or network error loading the dialog app).\n *\n * @param dialog - The `<dialog>` element wrapping the iframe.\n * @param iframe - The iframe element that will receive `PASSKEY_INIT`.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @param initMessage - The `PASSKEY_INIT` payload to send when ready.\n * @returns `true` if the dialog is ready and init was sent; `false` if the\n * dialog was closed or timed out before becoming ready.\n */\n private waitForDialogReady(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n initMessage: Record<string, unknown>,\n options: { blindSigning?: boolean; reveal?: () => void } = {},\n ): Promise<boolean> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let settled = false;\n\n const teardown = () => {\n if (settled) return;\n settled = true;\n clearTimeout(readyTimeout);\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n if (event.data?.type === \"PASSKEY_READY\") {\n const blindSigning = options.blindSigning === true;\n teardown();\n if (blindSigning) iframe.focus({ preventScroll: true });\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n ...initMessage,\n fullViewport: true,\n blindSigning,\n }, dialogOrigin);\n resolve(true);\n } else if (\n event.data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Cross-frame guard (same as waitForDialogReadyDeferred): a stray\n // PASSKEY_CLOSE from a sibling same-origin dialog must not resolve\n // this dialog's ready phase as closed-before-ready.\n teardown();\n cleanup();\n resolve(false);\n }\n };\n\n // Handle escape key / backdrop click which call cleanup() -> dialog.close()\n const handleClose = () => {\n teardown();\n resolve(false);\n };\n\n // Timeout: if dialog never signals ready (e.g. origin mismatch), clean up\n const readyTimeout = setTimeout(() => {\n teardown();\n cleanup();\n resolve(false);\n }, 10000);\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Create and open a full-viewport `<dialog>` containing a passkey iframe.\n *\n * The SDK owns the browser `<dialog>` plus a minimal generic preload shell\n * that appears immediately on click. The passkey iframe owns all branded and\n * origin-specific UI (TitleBar, trust icon, action cards); the shell is\n * removed as soon as the iframe reports that its centered card has painted.\n *\n * Lifecycle:\n * 1. A themed generic preload shell is injected and shown immediately\n * while the iframe loads. It intentionally contains no TitleBar or\n * origin chrome so that UI has a single implementation in apps/passkey.\n * 2. When the iframe sends `PASSKEY_RENDERED`, the overlay is removed and\n * the iframe becomes fully visible in the same frame.\n * 3. The returned `cleanup` function tears down all event listeners,\n * disconnects the MutationObserver, closes the `<dialog>`, and removes\n * it from the DOM. It is idempotent — safe to call multiple times.\n *\n * Browser quirks handled:\n * - The 1Password extension sets `inert` on the `<dialog>`, making it\n * non-interactive. A MutationObserver removes the attribute immediately.\n * - Password managers may also set `inert` on dialog siblings; cleanup\n * restores those as well.\n * - The iframe sandbox includes `allow-popups-to-escape-sandbox` so that\n * 1Password's popup UI can render outside the sandboxed context.\n * - `allow-downloads` lets the passkey iframe trigger the recovery-key\n * JSON fallback download without sending sensitive data to the parent.\n *\n * @param url - The full URL (including query params) to load in the iframe.\n * @returns References to the dialog, iframe, and a cleanup function.\n */\n private createModalDialog(url: string, options?: { persistent?: boolean; hidden?: boolean }): {\n dialog: HTMLDialogElement;\n iframe: HTMLIFrameElement;\n cleanup: () => void;\n destroy: () => void;\n reveal: () => void;\n } {\n const dialogUrl = this.getDialogUrl();\n const hostUrl = new URL(dialogUrl);\n\n const urlParams = new URL(url, window.location.href).searchParams;\n const { background: backdropBackground, blur: backdropBlur } =\n resolveBackdropStyle(urlParams);\n const themeMode = urlParams.get(\"theme\") || \"light\";\n const isDark =\n themeMode === \"dark\" ||\n (themeMode !== \"light\" &&\n window.matchMedia(\"(prefers-color-scheme: dark)\").matches);\n const theme = isDark ? DARK_TOKENS : LIGHT_TOKENS;\n\n const dialog = document.createElement(\"dialog\");\n dialog.dataset.passkey = \"\";\n if (options?.hidden) {\n dialog.dataset.passkeyHidden = \"\";\n }\n dialog.style.opacity = \"1\";\n dialog.style.background = \"transparent\";\n document.body.appendChild(dialog);\n\n const style = document.createElement(\"style\");\n style.textContent = `\n dialog[data-passkey] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100vw;\n height: 100vh;\n height: 100dvh;\n max-width: none;\n max-height: none;\n margin: 0;\n padding: 0;\n border: none;\n background: transparent;\n color-scheme: normal;\n outline: none;\n overflow: hidden;\n pointer-events: auto;\n }\n dialog[data-passkey]::backdrop {\n background: transparent !important;\n }\n dialog[data-passkey][data-passkey-hidden] {\n width: 1px;\n height: 1px;\n max-width: 1px;\n max-height: 1px;\n opacity: 0;\n pointer-events: none;\n }\n dialog[data-passkey][data-passkey-hidden] iframe {\n width: 1px;\n height: 1px;\n opacity: 0 !important;\n pointer-events: none;\n backdrop-filter: none;\n -webkit-backdrop-filter: none;\n }\n dialog[data-passkey] [data-passkey-overlay] {\n position: fixed;\n inset: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n background: ${backdropBackground};\n backdrop-filter: blur(${backdropBlur}px);\n -webkit-backdrop-filter: blur(${backdropBlur}px);\n z-index: 1;\n pointer-events: none;\n }\n dialog[data-passkey][data-passkey-hidden] [data-passkey-overlay] {\n display: none;\n }\n dialog[data-passkey] [data-passkey-preload-card] {\n width: ${LOADING_MODAL_WIDTH}px;\n max-width: 100%;\n overflow: hidden;\n border-radius: ${LOADING_MODAL_RADIUS}px;\n background: ${theme.bgPrimary};\n box-shadow: 0 24px 80px rgba(0, 0, 0, 0.24), 0 2px 12px rgba(0, 0, 0, 0.12);\n font-family: ${LOADING_FONT_FAMILY};\n line-height: ${LOADING_LINE_HEIGHT};\n -webkit-font-smoothing: antialiased;\n -moz-osx-font-smoothing: grayscale;\n }\n dialog[data-passkey] [data-passkey-preload-body] {\n box-sizing: border-box;\n display: flex;\n width: 100%;\n flex-direction: column;\n align-items: center;\n gap: ${LOADING_BODY_GAP}px;\n padding: ${LOADING_MODAL_PADDING}px;\n border-radius: ${LOADING_MODAL_RADIUS}px;\n background: ${theme.bgPrimary};\n }\n dialog[data-passkey] [data-passkey-preload-spinner-wrap] {\n display: flex;\n align-items: center;\n padding: ${LOADING_ICON_PADDING}px;\n }\n dialog[data-passkey] [data-passkey-preload-spinner] {\n position: relative;\n width: ${SPINNER_SIZE}px;\n height: ${SPINNER_SIZE}px;\n }\n dialog[data-passkey] [data-passkey-preload-spinner] svg {\n position: absolute;\n inset: 0;\n width: 100%;\n height: 100%;\n color: ${BRAND_PURPLE};\n animation: _1auth-spin ${SPINNER_SPIN_DURATION_MS}ms linear infinite;\n }\n dialog[data-passkey] [data-passkey-preload-copy] {\n display: flex;\n width: 100%;\n flex-direction: column;\n align-items: center;\n gap: ${LOADING_TITLE_BLOCK_GAP}px;\n text-align: center;\n }\n dialog[data-passkey] [data-passkey-preload-title] {\n margin: 0;\n color: ${theme.textPrimary};\n font-size: ${LOADING_TITLE_FONT_SIZE}px;\n font-weight: ${LOADING_TITLE_FONT_WEIGHT};\n line-height: ${LOADING_LINE_HEIGHT};\n }\n dialog[data-passkey] [data-passkey-preload-subtitle] {\n margin: 0;\n color: ${theme.textSecondary};\n font-size: ${LOADING_SUBTITLE_FONT_SIZE}px;\n font-weight: ${LOADING_SUBTITLE_FONT_WEIGHT};\n line-height: ${LOADING_LINE_HEIGHT};\n }\n @media (max-width: 639px) {\n dialog[data-passkey] [data-passkey-overlay] {\n align-items: flex-end;\n }\n dialog[data-passkey] [data-passkey-preload-card] {\n width: 100%;\n border-bottom-right-radius: 0;\n border-bottom-left-radius: 0;\n }\n dialog[data-passkey] [data-passkey-preload-body] {\n padding-bottom: calc(${LOADING_MODAL_PADDING}px + env(safe-area-inset-bottom));\n }\n }\n @keyframes _1auth-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n dialog[data-passkey] iframe {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n border: 0;\n background-color: transparent;\n color-scheme: normal;\n pointer-events: auto;\n backdrop-filter: blur(${backdropBlur}px);\n -webkit-backdrop-filter: blur(${backdropBlur}px);\n transition: none;\n }\n `;\n dialog.appendChild(style);\n\n const overlay = document.createElement(\"div\");\n overlay.dataset.passkeyOverlay = \"\";\n\n const preloadCard = document.createElement(\"div\");\n preloadCard.dataset.passkeyPreloadCard = \"\";\n\n const preloadBody = document.createElement(\"div\");\n preloadBody.dataset.passkeyPreloadBody = \"\";\n const spinnerWrap = document.createElement(\"div\");\n spinnerWrap.dataset.passkeyPreloadSpinnerWrap = \"\";\n const spinner = document.createElement(\"div\");\n spinner.dataset.passkeyPreloadSpinner = \"\";\n const spinnerCenter = SPINNER_SIZE / 2;\n const spinnerGap = SPINNER_CIRCUMFERENCE - SPINNER_ARC;\n spinner.innerHTML =\n `<svg viewBox=\"0 0 ${SPINNER_SIZE} ${SPINNER_SIZE}\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" aria-hidden=\"true\">` +\n `<circle cx=\"${spinnerCenter}\" cy=\"${spinnerCenter}\" r=\"${SPINNER_RADIUS}\" stroke=\"currentColor\" opacity=\"0.3\" stroke-width=\"${SPINNER_STROKE}\"/>` +\n `<circle cx=\"${spinnerCenter}\" cy=\"${spinnerCenter}\" r=\"${SPINNER_RADIUS}\" stroke=\"currentColor\" stroke-width=\"${SPINNER_STROKE}\" stroke-linecap=\"round\" stroke-dasharray=\"${SPINNER_ARC} ${spinnerGap}\" transform=\"rotate(-90 ${spinnerCenter} ${spinnerCenter})\"/>` +\n `</svg>`;\n spinnerWrap.appendChild(spinner);\n\n const preloadCopy = document.createElement(\"div\");\n preloadCopy.dataset.passkeyPreloadCopy = \"\";\n const preloadTitle = document.createElement(\"p\");\n preloadTitle.dataset.passkeyPreloadTitle = \"\";\n preloadTitle.textContent = LOADING_TITLE;\n const preloadSubtitle = document.createElement(\"p\");\n preloadSubtitle.dataset.passkeyPreloadSubtitle = \"\";\n preloadSubtitle.textContent = LOADING_SUBTITLE;\n preloadCopy.append(preloadTitle, preloadSubtitle);\n preloadBody.append(spinnerWrap, preloadCopy);\n preloadCard.appendChild(preloadBody);\n overlay.appendChild(preloadCard);\n dialog.appendChild(overlay);\n\n // Create full-viewport iframe\n const iframe = document.createElement(\"iframe\");\n iframe.setAttribute(\n \"allow\",\n [\n \"payment\",\n `publickey-credentials-get ${hostUrl.origin}`,\n `publickey-credentials-create ${hostUrl.origin}`,\n \"clipboard-write\",\n \"identity-credentials-get\",\n ].join(\"; \"),\n );\n iframe.setAttribute(\"aria-label\", \"Passkey Authentication\");\n iframe.setAttribute(\"tabindex\", \"0\");\n // Sandbox with allow-same-origin preserves the iframe's real origin for\n // WebAuthn and cookies. allow-popups-to-escape-sandbox lets 1Password's\n // browser extension render its popup UI outside the sandboxed context.\n // allow-downloads permits same-iframe recovery JSON export.\n iframe.setAttribute(\n \"sandbox\",\n \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox allow-downloads\",\n );\n iframe.setAttribute(\"title\", \"Passkey\");\n // The SDK shell above is visible immediately. Keep the iframe at opacity 0\n // until PASSKEY_RENDERED so the user never sees the pre-layout first paint\n // (the dialog page SSRs with fullViewport=false, so its very first client\n // paint can be the embedded full-width card before the URL-seeded\n // re-render centres it).\n iframe.style.opacity = \"0\";\n\n // Reveal the iframe once it has painted and drop the SDK shell in the same\n // frame. The shell exists only to make click-to-visual immediate while the\n // cross-origin iframe boots; once PASSKEY_RENDERED lands, the iframe owns\n // all visible UI.\n // Register the message listener before assigning `src`: warmed auth\n // routes can render and post PASSKEY_RENDERED very quickly, and missing\n // that one-shot signal would leave the iframe invisible indefinitely.\n let revealed = false;\n // Armed when PASSKEY_READY arrives but PASSKEY_RENDERED hasn't yet — see\n // the handler below. Cleared on reveal so a late RENDERED / teardown\n // doesn't leave a dangling timer.\n let readyFailsafe: ReturnType<typeof setTimeout> | undefined;\n const revealIframe = () => {\n if (revealed) return;\n revealed = true;\n clearTimeout(readyFailsafe);\n iframe.style.opacity = \"1\";\n overlay.style.display = \"none\";\n };\n // Failsafe: if PASSKEY_RENDERED never arrives (redirect race, message\n // dropped, iframe crash) we don't want the iframe stuck invisible forever.\n // After 8s the iframe has either rendered something the user can interact\n // with or is broken in a way that staying hidden can't help with — either\n // way, revealing is strictly better than a blank modal. 8s is well above\n // the normal sub-second iframe-load path so it never preempts the real\n // PASSKEY_RENDERED signal in healthy flows.\n const revealFailsafe = setTimeout(revealIframe, 8000);\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== hostUrl.origin) return;\n // Pin to THIS modal's iframe. Origin alone isn't enough: other\n // same-origin dialog frames can exist on the page (a parked `prewarm()`\n // frame, a second SDK instance, the persistent sign-eoa iframe). Without\n // this, a stray RENDERED/READY from one of them could reveal this modal's\n // iframe before its own content has painted, flashing a blank or\n // half-rendered dialog. (`prewarm`'s warm route is message-silent, so\n // this is defense in depth rather than its only guard.)\n if (event.source !== iframe.contentWindow) return;\n // PASSKEY_RENDERED is the ONLY signal that the iframe has painted its\n // final, correct layout: DialogShell / DialogCard post it after a\n // double-rAF, i.e. once the centered fullViewport card is on screen.\n if (event.data?.type === \"PASSKEY_RENDERED\") {\n revealIframe();\n }\n // PASSKEY_READY fires on mount, BEFORE the iframe has painted the\n // fullViewport layout. The dialog page server-renders with\n // `fullViewport=false` (no `window` on the server), so its first client\n // paint is the embedded, full-width Loading card; the centered layout\n // only lands after the URL-seeded client re-render. Revealing the\n // iframe on READY therefore flashes that full-width card for a frame or\n // two — the exact \"loading screen flash\" we're avoiding. So READY does\n // NOT reveal directly; it only arms a short fallback in case RENDERED is\n // lost (redirect remount, dropped frame). By the time this fires the\n // layout has long settled, so we still never expose the full-width card —\n // and we recover far faster than the 8s `revealFailsafe`. Every modal\n // route (auth/connect/account/grant-permission/sign/sign-eoa) reliably\n // posts RENDERED in fullViewport mode, so in healthy flows this never\n // fires.\n else if (\n event.data?.type === \"PASSKEY_READY\" &&\n !revealed &&\n readyFailsafe === undefined\n ) {\n readyFailsafe = setTimeout(revealIframe, 1000);\n }\n if (event.data?.type === \"PASSKEY_DISCONNECT\") {\n localStorage.removeItem(\"1auth-user\");\n }\n };\n window.addEventListener(\"message\", handleMessage);\n\n // Append `fullViewport=1` so the iframe's DialogProvider can seed its\n // initial state synchronously. Without this, `fullViewport` defaults to\n // false until PASSKEY_INIT arrives by postMessage — and on slow runs the\n // first paint of Loading.tsx renders as an embedded (full-width, top-of-\n // iframe) card before the message corrects it. Since we reveal the iframe\n // on PASSKEY_RENDERED, that wrong layout would be briefly visible.\n // Reading the flag from the URL eliminates the race.\n const iframeUrl = new URL(url, window.location.href);\n iframeUrl.searchParams.set(\"fullViewport\", \"1\");\n iframe.setAttribute(\"src\", iframeUrl.toString());\n dialog.appendChild(iframe);\n\n // Tell the dialog about the parent viewport so its DialogCard can\n // cap at 75% of screen height. Modal flow sets `fullViewport:\n // true` (which uses its own `calc(100dvh - 100px)` outer cap and\n // makes this no-op), but we wire it up defensively so any future\n // non-fullViewport modal route picks up the same gating without\n // a separate SDK change.\n const viewportInfoCleanup = this.wireViewportInfo(iframe);\n\n // 1Password extension adds `inert` attribute to <dialog>, making it\n // non-interactive. Watch for this and remove it immediately.\n const inertObserver = new MutationObserver((mutations) => {\n for (const mutation of mutations) {\n if (mutation.attributeName === \"inert\") {\n dialog.removeAttribute(\"inert\");\n }\n }\n });\n inertObserver.observe(dialog, { attributes: true });\n\n // Handle escape key\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n cleanup();\n }\n };\n document.addEventListener(\"keydown\", handleEscape);\n\n const reveal = () => {\n delete dialog.dataset.passkeyHidden;\n if (!revealed) {\n revealed = true;\n clearTimeout(readyFailsafe);\n clearTimeout(revealFailsafe);\n }\n iframe.style.opacity = \"1\";\n overlay.style.display = \"none\";\n };\n\n // Hidden blind-signing requests must not make the host page inert. They\n // still need a rendered iframe so the passkey origin can run WebAuthn.\n if (options?.hidden) {\n dialog.show();\n } else {\n dialog.showModal();\n }\n\n let cleanedUp = false;\n const destroy = () => {\n if (cleanedUp) return;\n cleanedUp = true;\n clearTimeout(revealFailsafe);\n clearTimeout(readyFailsafe);\n inertObserver.disconnect();\n viewportInfoCleanup();\n window.removeEventListener(\"message\", handleMessage);\n document.removeEventListener(\"keydown\", handleEscape);\n dialog.close();\n // Clean up 1Password inert attributes left on dialog siblings\n if (dialog.parentNode) {\n for (const sibling of Array.from(dialog.parentNode.children)) {\n if (sibling !== dialog && sibling instanceof HTMLElement && sibling.hasAttribute(\"inert\")) {\n sibling.removeAttribute(\"inert\");\n }\n }\n }\n dialog.remove();\n };\n\n // In persistent mode the iframe lives across many open/close cycles\n // (used by `requestWithWallet` so the WalletConnect SignClient inside\n // the iframe is not recreated for every EOA request). `cleanup` here\n // just hides the dialog; full teardown is reachable via `destroy`.\n const cleanup = options?.persistent\n ? () => {\n if (dialog.open) dialog.close();\n }\n : destroy;\n\n return { dialog, iframe, cleanup, destroy, reveal };\n }\n\n /**\n * Listen for the auth result from the modal dialog.\n *\n * Each modal call generates a per-session nonce that the iframe must\n * echo back in `PASSKEY_CLOSE` / `PASSKEY_LOGIN_RESULT` /\n * `PASSKEY_RETRY_POPUP` messages. Without an echo, a queued CLOSE\n * from the previous iframe could be dispatched to the new modal's\n * listener (postMessage events tagged with `event.source` from a now-\n * destroyed iframe still reach the parent's message handler) and\n * silently cancel the fresh auth attempt. The nonce makes that race\n * harmless: a stale message that doesn't carry the current modal's\n * nonce is ignored.\n *\n * Also handles the `PASSKEY_RETRY_POPUP` message: sent by the dialog when a\n * password manager (e.g. Bitwarden) intercepts the WebAuthn call inside the\n * iframe. In that case the SDK seamlessly re-opens a standalone popup window,\n * where WebAuthn works without cross-origin iframe restrictions, and waits\n * for the result from there instead.\n *\n * @param _dialog - Unused; kept for signature consistency.\n * @param iframe - The iframe element; used to send `PASSKEY_INIT` on ready.\n * @param cleanup - Idempotent teardown for the modal dialog.\n * @returns An `AuthResult` discriminated union.\n */\n private waitForModalAuthResponse(\n _dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n requestId?: string\n ): Promise<AuthResult> {\n const dialogOrigin = this.getDialogOrigin();\n // Per-modal nonce so stale messages from a previous iframe can't\n // cancel a fresh auth attempt. The dialog echoes this back on every\n // result-bearing message; messages without the matching nonce are\n // ignored.\n const modalNonce = generateModalNonce();\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n const data = event.data;\n\n const matchesSource = event.source === iframe.contentWindow;\n const matchesRequest =\n typeof requestId === \"string\" && data?.requestId === requestId;\n const matchesNonce = data?.modalNonce === modalNonce;\n const isCurrentFrameClose =\n data?.type === \"PASSKEY_CLOSE\" && matchesSource;\n\n if (\n data?.type === \"PASSKEY_CLOSE\" &&\n (matchesRequest || matchesNonce || isCurrentFrameClose)\n ) {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n return;\n }\n\n // Send init message once the dialog signals it's ready to receive\n // it; many entry routes fire this from their first useEffect.\n // The nonce travels with INIT and the dialog stores it for later\n // echo on CLOSE / RESULT messages.\n if (data?.type === \"PASSKEY_READY\") {\n\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n mode: \"iframe\",\n fullViewport: true,\n modalNonce,\n }, dialogOrigin);\n return;\n }\n\n const hasModalNonce = typeof data?.modalNonce === \"string\";\n const isCurrentDialogMessage =\n matchesSource || matchesNonce || !hasModalNonce;\n if (!isCurrentDialogMessage) return;\n\n // Result-bearing messages without the current modal's nonce are\n // late-arriving CLOSE / RESULT events from a previously cleaned-\n // up iframe (postMessage queue, tab-throttling, etc.). Drop them\n // so they can't cancel or hijack the fresh modal.\n if (data?.modalNonce && data.modalNonce !== modalNonce) return;\n\n if (data?.type === \"PASSKEY_LOGIN_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (data.success) {\n resolve({\n success: true,\n user: {\n id: data.data?.user?.id,\n address: data.data?.address as `0x${string}`,\n },\n signerType: data.data?.signerType ?? \"passkey\",\n });\n } else {\n resolve({\n success: false,\n error: data.error,\n });\n }\n } else if (data?.type === \"PASSKEY_RETRY_POPUP\") {\n // Password manager (e.g. Bitwarden) interfered with WebAuthn in iframe\n // Retry in popup mode where WebAuthn works without cross-origin restrictions\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n // Get the current dialog URL and switch to popup mode\n const popupUrl = data.data?.url?.replace(\"mode=iframe\", \"mode=popup\")\n || `${this.getDialogUrl()}/dialog/auth?mode=popup${this.config.clientId ? `&clientId=${this.config.clientId}` : ''}`;\n\n // Open popup and wait for result\n this.waitForPopupAuthResponse(popupUrl).then(resolve);\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Open a popup for auth and wait for the result.\n * Used when iframe mode fails (e.g., due to password manager interference).\n */\n private waitForPopupAuthResponse(url: string): Promise<AuthResult> {\n const dialogOrigin = this.getDialogOrigin();\n const popup = this.openPopup(url);\n\n return new Promise((resolve) => {\n // Poll to check if popup was closed\n const pollTimer = setInterval(() => {\n if (popup?.closed) {\n clearInterval(pollTimer);\n window.removeEventListener(\"message\", handleMessage);\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n }\n }, 500);\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n if (data?.type === \"PASSKEY_LOGIN_RESULT\") {\n clearInterval(pollTimer);\n window.removeEventListener(\"message\", handleMessage);\n popup?.close();\n\n if (data.success) {\n resolve({\n success: true,\n user: {\n id: data.data?.user?.id,\n address: data.data?.address as `0x${string}`,\n },\n signerType: data.data?.signerType ?? \"passkey\",\n });\n } else {\n resolve({\n success: false,\n error: data.error,\n });\n }\n } else if (data?.type === \"PASSKEY_CLOSE\") {\n clearInterval(pollTimer);\n window.removeEventListener(\"message\", handleMessage);\n popup?.close();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for the connect result from the connect dialog.\n *\n * The connect flow is a lightweight \"are you still you?\" confirmation that\n * does not require a new passkey ceremony. On success, the dialog returns the\n * user's address and an `autoConnected` flag indicating whether the\n * user had previously enabled auto-connect (in which case no UI was shown).\n *\n * On failure with `action: \"switch\"`, the caller should redirect to the full\n * auth flow because the user has no cached session to confirm.\n *\n * @param _dialog - Unused; kept for signature consistency.\n * @param _iframe - Unused; kept for signature consistency.\n * @param cleanup - Idempotent teardown for the modal dialog.\n * @returns A `ConnectResult` discriminated union.\n */\n private waitForConnectResponse(\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<ConnectResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n if (data?.type === \"PASSKEY_CONNECT_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (data.success) {\n resolve({\n success: true,\n user: {\n address: data.data?.address as `0x${string}`,\n },\n // Carry the signer type through so the SDK/provider can route EOA\n // sessions to the connected wallet (plain tx, no intents) instead\n // of defaulting to passkey intents. Absent = legacy passkey.\n signerType: data.data?.signerType ?? \"passkey\",\n autoConnected: data.data?.autoConnected,\n });\n } else {\n resolve({\n success: false,\n action: data.data?.action,\n error: data.error,\n });\n }\n } else if (data?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n action: \"cancel\",\n error: {\n code: \"USER_CANCELLED\",\n message: \"Connection was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for grant-permission results and bridge sponsorship token requests.\n *\n * The grant iframe owns the passkey ceremony and install intent submission.\n * Extension-token minting stays in the app origin, so the SDK exposes a\n * narrow postMessage round-trip that never gives the iframe app secrets.\n *\n * @param _dialog - Unused; kept for signature consistency.\n * @param iframe - The grant iframe that receives extension-token responses.\n * @param cleanup - Idempotent teardown for the modal dialog.\n * @param sponsor - Whether this grant flow should request an extension token.\n * @returns A `GrantPermissionsResult` discriminated union.\n */\n private waitForGrantPermissionResponse(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n sponsor: boolean,\n initPayload: Record<string, unknown>\n ): Promise<GrantPermissionsResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n let readySeen = false;\n\n const teardown = () => {\n clearTimeout(readyTimeout);\n window.removeEventListener(\"message\", handleMessage);\n dialog.removeEventListener(\"close\", handleClose);\n };\n\n const postInit = () => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initPayload, fullViewport: true },\n dialogOrigin,\n );\n };\n\n const handleClose = () => {\n teardown();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n });\n };\n\n const handleMessage = async (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n\n if (data?.type === \"PASSKEY_READY\") {\n readySeen = true;\n clearTimeout(readyTimeout);\n // Grant iframe routes can remount in dev/HMR and after Suspense\n // boundaries. Re-send init on every READY so the review page never\n // gets stranded on its initial loading state.\n postInit();\n return;\n }\n\n if (data?.type === \"PASSKEY_GRANT_EXTENSION_TOKEN_REQUEST\") {\n const requestId = data.requestId as string | undefined;\n const intentOp = data.intentOp as string | undefined;\n const postResponse = (payload: Record<string, unknown>) => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_GRANT_EXTENSION_TOKEN_RESPONSE\", requestId, ...payload },\n dialogOrigin\n );\n };\n\n if (!requestId || !intentOp) {\n postResponse({ success: false, error: \"Invalid extension token request\" });\n return;\n }\n\n if (!sponsor) {\n postResponse({ success: true });\n return;\n }\n\n if (!this.sponsorship) {\n postResponse({ success: false, error: MISSING_APP_CREDENTIALS_MESSAGE });\n return;\n }\n\n try {\n const token = await this.sponsorship.getExtensionToken(intentOp);\n postResponse({ success: true, token });\n } catch (err) {\n postResponse({\n success: false,\n error: err instanceof Error ? err.message : String(err),\n });\n }\n return;\n }\n\n if (data?.type === \"PASSKEY_GRANT_PERMISSION_RESULT\") {\n if (data.success) {\n // Resolve the grant result but DELIBERATELY keep the dialog open.\n // The grant dialog's `success` state renders a \"Permission granted\"\n // confirmation with a green Done button (mirroring the sign flow's\n // `confirmed` screen). Calling cleanup() here — as we still do on\n // the failure path — would destroy that iframe before it paints, so\n // the user would never see a success screen. Instead we just stop\n // listening for grant messages; grantPermissions() then awaits\n // waitForDialogClose() so the confirmation stays up until the user\n // clicks Done (PASSKEY_CLOSE). This matches sendIntent, where\n // waitForSigningResponse resolves on success without cleanup and the\n // caller awaits the dialog close.\n teardown();\n resolve({ success: true, ...(data.data ?? {}) });\n return;\n }\n\n // Failure: there's no success screen to preserve, and the passkey app\n // sends PASSKEY_CLOSE right after this RESULT — but teardown() removes\n // the listener, so that follow-up would be dropped. Close here, the\n // same way the sign failure path does.\n teardown();\n cleanup();\n resolve({\n success: false,\n error: data.error ?? data.data?.error ?? {\n code: \"GRANT_PERMISSION_FAILED\",\n message: \"Permission grant failed\",\n },\n });\n } else if (\n data?.type === \"PASSKEY_CLOSE\" &&\n event.source === iframe.contentWindow\n ) {\n // Same cross-frame guard as the sign/ready paths: a stray\n // PASSKEY_CLOSE from another same-origin dialog (e.g. an auth modal\n // tearing down) must not cancel an in-flight grant. Only honor the\n // close from THIS grant iframe.\n teardown();\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n });\n }\n };\n\n const readyTimeout = setTimeout(() => {\n if (readySeen) return;\n teardown();\n cleanup();\n resolve({\n success: false,\n error: {\n code: \"USER_CANCELLED\",\n message: \"User closed the dialog\",\n },\n });\n }, 10000);\n\n window.addEventListener(\"message\", handleMessage);\n dialog.addEventListener(\"close\", handleClose);\n });\n }\n\n /**\n * Listen for a signing result from a server-request-based modal dialog.\n *\n * Similar to `waitForIntentSigningResponse` but intended for the older\n * `signWithModal` path that pre-creates a signing request via the API (rather\n * than inlining all data in `PASSKEY_INIT`). Filters by `requestId` to handle\n * the case where stale messages from a previous dialog may still be in flight.\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param _dialog - Unused; kept for signature consistency.\n * @param _iframe - Unused; kept for signature consistency.\n * @param cleanup - Idempotent teardown that closes and removes the dialog.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForModalSigningResponse(\n requestId: string,\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const message = event.data;\n // The Messenger sends: { type, success, data: { requestId, signature }, error }\n // So we need to check message.data.requestId, not message.requestId\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n if (message?.type === \"PASSKEY_SIGNING_RESULT\" && payload?.requestId === requestId) {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n });\n } else {\n resolve({\n success: false,\n requestId,\n error: message.error,\n });\n }\n } else if (message?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n resolve({\n success: false,\n requestId,\n error: {\n code: \"USER_REJECTED\",\n message: \"Signing was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Listen for a signing result from a popup window.\n *\n * Polls for popup closure every 500 ms as a fallback to detect when the user\n * closes the popup without completing the signing flow (no `PASSKEY_CLOSE`\n * message is fired in that case because the popup's unload event cannot\n * reliably postMessage to the opener on all browsers).\n *\n * On success or cancellation, the popup is programmatically closed and the\n * interval is cleared.\n *\n * @param requestId - The signing request ID to match against incoming messages.\n * @param popup - The popup `Window` reference returned by `openPopup`.\n * @returns A `SigningResult` discriminated union.\n */\n private waitForPopupResponse(\n requestId: string,\n popup: Window\n ): Promise<SigningResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n const checkClosed = setInterval(() => {\n if (popup.closed) {\n clearInterval(checkClosed);\n window.removeEventListener(\"message\", handleMessage);\n resolve({\n success: false,\n requestId,\n error: {\n code: \"USER_REJECTED\",\n message: \"Popup was closed without completing\",\n },\n });\n }\n }, 500);\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) {\n return;\n }\n\n const message = event.data;\n // The Messenger sends: { type, success, data: { requestId, signature }, error }\n const payload = message?.data as { requestId?: string; signature?: WebAuthnSignature } | undefined;\n\n if (\n message?.type === \"PASSKEY_SIGNING_RESULT\" &&\n payload?.requestId === requestId\n ) {\n clearInterval(checkClosed);\n window.removeEventListener(\"message\", handleMessage);\n popup.close();\n\n if (message.success && payload.signature) {\n resolve({\n success: true,\n requestId,\n signature: payload.signature,\n });\n } else {\n resolve({\n success: false,\n requestId,\n error: message.error,\n });\n }\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\n\n /**\n * Fetch the completed signing result from the passkey service by request ID.\n *\n * Used by the redirect flow: after the passkey service redirects back to\n * `redirectUrl`, the integrator calls `handleRedirectCallback()`, which\n * extracts `requestId` from the URL query params and delegates here to\n * retrieve the full signature from the server.\n *\n * @param requestId - The signing request ID from the redirect callback URL.\n * @returns A `SigningResult` discriminated union.\n */\n private async fetchSigningResult(requestId: string): Promise<SigningResult> {\n const response = await fetch(\n `${this.config.providerUrl}/api/sign/request/${requestId}`,\n {\n headers: this.config.clientId\n ? { \"x-client-id\": this.config.clientId }\n : {},\n }\n );\n\n if (!response.ok) {\n return {\n success: false,\n requestId,\n error: {\n code: \"NETWORK_ERROR\",\n message: \"Failed to fetch signing result\",\n },\n };\n }\n\n const data: SigningRequestStatus = await response.json();\n\n if (data.status === \"COMPLETED\" && data.signature) {\n return {\n success: true,\n requestId,\n signature: data.signature,\n };\n }\n\n const errorCode: SigningErrorCode = data.error?.code || \"UNKNOWN\";\n return {\n success: false,\n requestId,\n error: {\n code: errorCode,\n message: data.error?.message || `Request status: ${data.status}`,\n },\n };\n }\n}\n","import { isTestnet } from \"./registry\";\nimport type { AssetBalance, AssetsResponse } from \"./types\";\n\ntype PortfolioChainBalance = {\n chainId?: number;\n chain?: number;\n address?: string;\n token?: string;\n balance?: string;\n amount?: string;\n decimals?: number;\n isTestnet?: boolean;\n};\n\ntype PortfolioAsset = {\n symbol?: string;\n decimals?: number;\n balance?: string;\n amount?: string;\n address?: string;\n token?: string;\n usdValue?: number;\n chains?: PortfolioChainBalance[];\n};\n\ntype FetchAssetsResponseOptions = {\n providerUrl: string;\n identifier: string;\n clientId?: string;\n accessToken?: string;\n headers?: Record<string, string>;\n};\n\n/**\n * Mark a normalized portfolio row with a stable network bucket flag.\n */\nfunction withNetworkBucket(balance: AssetBalance): AssetBalance {\n return {\n ...balance,\n isTestnet: balance.isTestnet ?? isTestnet(balance.chainId),\n };\n}\n\n/**\n * Split normalized balances into explicit mainnet and testnet buckets.\n */\nfunction bucketAssetBalances(balances: AssetBalance[]): Pick<\n AssetsResponse,\n \"mainnets\" | \"testnets\"\n> {\n const mainnetBalances: AssetBalance[] = [];\n const testnetBalances: AssetBalance[] = [];\n\n for (const balance of balances) {\n const normalized = withNetworkBucket(balance);\n if (normalized.isTestnet) {\n testnetBalances.push(normalized);\n } else {\n mainnetBalances.push(normalized);\n }\n }\n\n return {\n mainnets: { balances: mainnetBalances },\n testnets: { balances: testnetBalances },\n };\n}\n\n/**\n * Convert passkey portfolio responses into the documented assets response.\n */\nexport function normalizeAssetsResponse(payload: unknown): AssetsResponse {\n const data = payload && typeof payload === \"object\"\n ? (payload as Record<string, unknown>)\n : {};\n if (Array.isArray(data.balances)) {\n const balances = (data.balances as AssetBalance[]).map(withNetworkBucket);\n const buckets = bucketAssetBalances(balances);\n return { ...data, balances, ...buckets };\n }\n\n const balances: AssetBalance[] = [];\n const assets = Array.isArray(data.assets) ? (data.assets as PortfolioAsset[]) : [];\n for (const asset of assets) {\n const symbol = asset.symbol ?? \"UNKNOWN\";\n const decimals = asset.decimals ?? 18;\n const chains = Array.isArray(asset.chains) ? asset.chains : [];\n\n if (chains.length === 0) {\n const token = asset.token ?? asset.address;\n if (token) {\n balances.push(withNetworkBucket({\n chainId: 0,\n token,\n symbol,\n decimals,\n balance: asset.balance ?? asset.amount ?? \"0\",\n ...(asset.usdValue !== undefined && { usdValue: asset.usdValue }),\n }));\n }\n continue;\n }\n\n for (const chain of chains) {\n const chainId = chain.chainId ?? chain.chain;\n const token = chain.token ?? chain.address;\n if (typeof chainId !== \"number\" || !token) continue;\n balances.push(withNetworkBucket({\n chainId,\n token,\n symbol,\n decimals: chain.decimals ?? decimals,\n balance: chain.balance ?? chain.amount ?? \"0\",\n ...(asset.usdValue !== undefined && { usdValue: asset.usdValue }),\n ...(chain.isTestnet !== undefined && { isTestnet: chain.isTestnet }),\n }));\n }\n }\n\n return { ...data, balances, ...bucketAssetBalances(balances) };\n}\n\n/**\n * Fetch the unified passkey portfolio and return normalized wallet assets.\n */\nexport async function fetchAssetsResponse(\n options: FetchAssetsResponseOptions,\n): Promise<AssetsResponse> {\n const portfolioUrl = new URL(\n `/api/users/${encodeURIComponent(options.identifier)}/portfolio`,\n options.providerUrl,\n );\n // `all=true` keeps the SDK from silently hiding testnet balances when the\n // caller is using a mixed mainnet/testnet account during dogfooding.\n portfolioUrl.searchParams.set(\"all\", \"true\");\n\n const response = await fetch(portfolioUrl.toString(), {\n headers: {\n ...options.headers,\n ...(options.accessToken ? { Authorization: `Bearer ${options.accessToken}` } : {}),\n ...(options.clientId ? { \"x-client-id\": options.clientId } : {}),\n },\n });\n if (!response.ok) {\n const data = await response.json().catch(() => ({}));\n throw new Error(data.error || \"Failed to get assets\");\n }\n return normalizeAssetsResponse(await response.json());\n}\n","// Shared constants for the loading screen that's rendered in two places:\n// 1. packages/sdk/src/client.ts — host-page overlay (vanilla DOM, before\n// the passkey iframe paints).\n// 2. apps/passkey/src/components/dialog/screens/Loading.tsx — same screen\n// drawn by the iframe via React + DialogShell + IconWithStatus.\n//\n// The handoff between the two is a crossfade on `PASSKEY_RENDERED`, so any\n// drift in geometry / colour / copy produces a visible flash. SDK-side\n// values live here instead of being inlined; the iframe side imports from\n// here too. If a value isn't in this file, BOTH sides duplicated it inline\n// — drift is now likely.\n//\n// Theme tokens are mirrored from apps/passkey/src/app/globals.css. If the\n// CSS values change there, update the LIGHT/DARK pairs below in the same PR.\n\n// === Spinner geometry =====================================================\n// 82×82 SVG with two concentric circles; the foreground arc covers 17 % of\n// the circumference and rotates via CSS `animate-spin`.\nexport const SPINNER_SIZE = 82;\nexport const SPINNER_STROKE = 2.4118;\nexport const SPINNER_RADIUS = (SPINNER_SIZE - SPINNER_STROKE) / 2;\nexport const SPINNER_CIRCUMFERENCE = 2 * Math.PI * SPINNER_RADIUS;\nexport const SPINNER_ARC_FRACTION = 0.17;\nexport const SPINNER_ARC = SPINNER_CIRCUMFERENCE * SPINNER_ARC_FRACTION;\n// One full rotation, in ms. Shared so the SDK host-page overlay and the\n// iframe's `IconWithStatus` spinner rotate at the SAME rate — otherwise the\n// arc visibly changes speed at the PASSKEY_RENDERED crossfade and the two\n// loading screens read as different. The iframe side previously inherited\n// Tailwind's `animate-spin` default (1s) while the SDK hardcoded 0.8s.\nexport const SPINNER_SPIN_DURATION_MS = 800;\n\n// === Modal geometry =======================================================\n// Mirrors apps/passkey DialogShell's full-viewport iframe placement:\n// centered desktop card at Tailwind's `sm` breakpoint, bottom sheet below it.\n// Source of truth: Figma \"Sizing changes\" frame (3036:9897) — Modal width\n// is 380px on desktop. Must stay in sync with `--spacing-modal-width` /\n// `--spacing-modal-padding` in apps/passkey/src/app/globals.css and with\n// the SDK's POPUP_WIDTH / DEFAULT_EMBED_WIDTH in packages/sdk/src/client.ts.\nexport const LOADING_MODAL_WIDTH = 380;\nexport const LOADING_MODAL_PADDING = 12;\nexport const LOADING_MODAL_RADIUS = 16;\nexport const LOADING_MOBILE_BREAKPOINT = 640;\n\n// === Spacing (inside the card) ============================================\n// Vertical rhythm between body and footer, and within the body block.\n// 16px between body and footer is the same value DialogShell uses for the\n// outer column gap; we keep them in lockstep so embedded dialogs share the\n// rhythm too.\nexport const LOADING_CARD_GAP = 16;\nexport const LOADING_BODY_GAP = 12;\nexport const LOADING_ICON_PADDING = 12;\nexport const LOADING_TITLE_BLOCK_GAP = 4;\nexport const LOADING_FOOTER_GAP = 4;\n\n// === Typography ===========================================================\n// Title + subtitle + footer. `line-height: normal` is critical: the host\n// page may set a different value on <body> (Tailwind preflight 1.5, etc)\n// and inheritance would otherwise blow up the card height.\nexport const LOADING_TITLE_FONT_SIZE = 20;\nexport const LOADING_TITLE_FONT_WEIGHT = 700;\nexport const LOADING_SUBTITLE_FONT_SIZE = 12;\nexport const LOADING_SUBTITLE_FONT_WEIGHT = 500;\nexport const LOADING_FOOTER_FONT_SIZE = 11;\nexport const LOADING_FOOTER_FONT_WEIGHT = 500;\nexport const LOADING_LINE_HEIGHT = \"normal\" as const;\n// Font stack matches `data-connect-v2` in apps/passkey globals.css. Inter\n// is loaded by the host app; the rest are safe fallbacks. Includes emoji\n// stack for screens that render copy with emoji characters.\nexport const LOADING_FONT_FAMILY =\n \"'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji'\";\n\n// === Rhinestone wordmark ==================================================\n// Footer \"Powered by [logo]\". Source SVG is 72×16; both consumers render\n// at native size.\nexport const LOGO_WIDTH = 72;\nexport const LOGO_HEIGHT = 16;\n\n// === Brand colour =========================================================\n// Mirrors `--color-primary-500` in apps/passkey globals.css.\nexport const BRAND_PURPLE = \"#685bff\";\n\n// === Theme tokens =========================================================\n// Hex pairs mirroring the iframe's `light-dark()` CSS custom properties.\n// The host-page SDK overlay can't read those custom properties (different\n// document), so it picks light/dark from the `theme` URL param and falls\n// back to `prefers-color-scheme`.\nexport type LoadingThemeTokens = {\n /** `--color-modal-bg` */\n bgPrimary: string;\n /** `--color-modal-border` */\n borderColor: string;\n /** `--color-view-text-primary` */\n textPrimary: string;\n /** `--color-view-text-secondary` */\n textSecondary: string;\n};\n\nexport const LIGHT_TOKENS: LoadingThemeTokens = {\n bgPrimary: \"#ffffff\",\n borderColor: \"#f4f4f5\",\n textPrimary: \"#27272a\",\n textSecondary: \"#71717b\",\n};\n\nexport const DARK_TOKENS: LoadingThemeTokens = {\n bgPrimary: \"#0a0a0a\",\n borderColor: \"#18181b\",\n textPrimary: \"#e4e4e7\",\n textSecondary: \"#9f9fa9\",\n};\n\n// `--color-modal-text-footer` — a single value across both themes.\nexport const FOOTER_TEXT_COLOR = \"#71717b\";\n\n// === Copy =================================================================\nexport const LOADING_TITLE = \"Loading...\";\nexport const LOADING_SUBTITLE =\n \"This will only take a few moments, do not close the window.\";\n","import type { Abi, Address } from \"viem\";\nimport type { Permission } from \"@rhinestone/sdk\";\n\nexport type DefinePermissionsConfig<TAbi extends Abi> = Permission<TAbi> & {\n /** Optional human-readable name surfaced in the review UI. */\n name?: string;\n};\n\nexport interface DefinedPermissions<TAbi extends Abi = Abi> {\n /**\n * v2 SmartSession permissions, ready to pass to\n * `OneAuthClient.grantPermissions({ ...definePermissions(...) })`.\n *\n * Always a single-element array so the `...spread` pattern works cleanly\n * with `grantPermissions`, which accepts `permissions: Permission[]`.\n *\n * Widened to `Permission<Abi>` (rather than `Permission<TAbi>`) so the\n * spread composes with `GrantPermissionsOptions.permissions: Permission<Abi>[]`.\n * The SDK's v2 `Permission<TAbi>` includes conditional `SpendingLimitField<TFn>` /\n * `ValueLimitField<TFn>` types that break covariance over `TAbi`, so an inferred\n * narrow `Permission<erc20Abi>` is no longer assignable to `Permission<Abi>`.\n * We keep `TAbi` on the type parameter so `contracts[].abi` retains its\n * narrow shape for the review UI.\n */\n permissions: [Permission<Abi>];\n /**\n * Contract metadata for the permission review UI. The address and ABI\n * here mirror the entry in `permissions[0]`; `name` is optional and\n * purely cosmetic (it's never sent to a contract).\n */\n contracts: Array<{\n address: Address;\n name?: string;\n abi: TAbi;\n }>;\n}\n\n/**\n * Build a v2 SmartSession `Permission` from an ABI + function map.\n *\n * The Rhinestone SDK derives function selectors and universal-action\n * calldata offsets from the ABI internally, so app code no longer needs\n * to spell out raw 4-byte selectors or parameter indices. The accepted\n * shape is the SDK's own `Permission<TAbi>` plus an optional `name` for\n * the review UI.\n *\n * @example\n * const permissions = definePermissions({\n * address: USDC,\n * abi: erc20Abi,\n * name: \"USDC\",\n * functions: {\n * transfer: {\n * params: { to: { condition: \"equal\", value: RECIPIENT } },\n * },\n * },\n * });\n *\n * await oneAuth.grantPermissions({ ...permissions, sessionKeyAddress });\n */\nexport function definePermissions<const TAbi extends Abi>(\n config: DefinePermissionsConfig<TAbi>,\n): DefinedPermissions<TAbi> {\n const { name, ...permission } = config;\n return {\n permissions: [permission as unknown as Permission<Abi>],\n contracts: [\n {\n address: config.address,\n name,\n abi: config.abi,\n },\n ],\n };\n}\n","import { isAddress, type Address, type Chain } from \"viem\";\n\nimport { getTokenAddress } from \"./registry\";\n\nexport type CrossChainSettlementLayer = \"SAME_CHAIN\" | \"ECO\" | \"ACROSS\";\n\nexport interface CrossChainPermit {\n /** Allowed source legs: chain + token, with an optional amount cap. */\n from: Array<{ chain: Chain; token: Address; maxAmount?: bigint }>;\n /** Allowed destination legs: chain + token, with an optional recipient pin. */\n to: Array<{ chain: Chain; token: Address; recipient?: Address | \"any\" }>;\n /** Upper bound on the Permit2 deadline, expressed as Unix seconds. */\n validUntil?: bigint;\n /** Lower bound on the Permit2 deadline, expressed as Unix seconds. */\n validAfter?: bigint;\n /** Per-destination fill-deadline windows, expressed as Unix seconds. */\n fillDeadline?: Array<{ chain: Chain; min?: bigint; max?: bigint }>;\n /** When true, the destination recipient must be the smart account. */\n recipientIsAccount?: boolean;\n /** Allowed settlement layers. Omit or pass an empty array to allow any supported layer. */\n settlementLayers?: CrossChainSettlementLayer[];\n}\n\ninterface FromLeg {\n chain: Chain;\n token: Address | string;\n maxAmount?: bigint;\n}\n\ninterface ToLeg {\n chain: Chain;\n token: Address | string;\n recipient?: Address | \"any\";\n}\n\nexport interface CreateCrossChainPermissionInput {\n /** Source chain + token, with an optional amount cap. Pass an array for multi-leg permits. */\n from: FromLeg | FromLeg[];\n /** Destination chain + token, with an optional recipient pin. Pass an array for fan-out destinations. */\n to: ToLeg | ToLeg[];\n /** Upper bound on the Permit2 deadline. Accepts Unix-seconds bigint or Date. */\n validUntil?: bigint | Date;\n /** Lower bound on the Permit2 deadline. Accepts Unix-seconds bigint or Date. */\n validAfter?: bigint | Date;\n /** Per-destination fill-deadline windows, expressed as Unix seconds. */\n fillDeadline?: Array<{ chain: Chain; min?: bigint; max?: bigint }>;\n /**\n * Allow the destination recipient to differ from the smart account.\n * Defaults to false so bridge permissions are bridge-to-self unless the\n * caller explicitly broadens the grant.\n */\n allowRecipientNotAccount?: boolean;\n /** Settlement layers this session is permitted to use. */\n settlementLayers?: CrossChainSettlementLayer[];\n}\n\nfunction toUnixSecondsBigint(input: bigint | Date): bigint {\n if (typeof input === \"bigint\") return input;\n // Permit2 deadlines are Unix seconds; Date stores milliseconds.\n return BigInt(Math.floor(input.getTime() / 1000));\n}\n\nfunction resolveTokenForChain(token: Address | string, chainId: number): Address {\n return isAddress(token, { strict: false }) ? token : getTokenAddress(token, chainId);\n}\n\n/**\n * Build a CrossChainPermit for Permit2-backed bridge settlement.\n *\n * The returned object is JSON-safe after callers stringify bigint fields at\n * the iframe/API boundary and can be passed as\n * `grantPermissions({ crossChainPermits: [...] })`.\n */\nexport function createCrossChainPermission(\n input: CreateCrossChainPermissionInput,\n): CrossChainPermit {\n const fromLegs = Array.isArray(input.from) ? input.from : [input.from];\n const toLegs = Array.isArray(input.to) ? input.to : [input.to];\n\n if (fromLegs.length === 0) {\n throw new Error(\"createCrossChainPermission: `from` must contain at least one leg\");\n }\n if (toLegs.length === 0) {\n throw new Error(\"createCrossChainPermission: `to` must contain at least one leg\");\n }\n\n const validUntil =\n input.validUntil !== undefined ? toUnixSecondsBigint(input.validUntil) : undefined;\n const validAfter =\n input.validAfter !== undefined ? toUnixSecondsBigint(input.validAfter) : undefined;\n\n // Catch a broken time window before the user reaches the passkey dialog.\n if (validUntil !== undefined && validAfter !== undefined && validAfter > validUntil) {\n throw new Error(\n `createCrossChainPermission: validAfter (${validAfter}) is greater than validUntil (${validUntil})`,\n );\n }\n\n return {\n from: fromLegs.map((leg) => ({\n chain: leg.chain,\n token: resolveTokenForChain(leg.token, leg.chain.id),\n maxAmount: leg.maxAmount,\n })),\n to: toLegs.map((leg) => ({\n chain: leg.chain,\n token: resolveTokenForChain(leg.token, leg.chain.id),\n recipient: leg.recipient,\n })),\n validUntil,\n validAfter,\n fillDeadline: input.fillDeadline,\n recipientIsAccount: !input.allowRecipientNotAccount,\n settlementLayers: input.settlementLayers,\n };\n}\n","/**\n * One-call connect entry point for 1auth.\n *\n * `createOneAuthConnection` is the ergonomic front door for integrators who\n * want a single function that:\n * 1. opens the 1auth dialog so the user picks **1auth passkey** *or* a\n * **traditional wallet** (WalletConnect / injected), and\n * 2. hands back a ready-to-use EIP-1193 provider plus the connected\n * `{ address, signerType }`.\n *\n * When the user picks a traditional wallet (an EOA), the returned provider\n * forwards `eth_sendTransaction` / `personal_sign` / `signTypedData` /\n * `wallet_sendCalls` straight to that wallet's native RPC — **no Rhinestone\n * intents**. When they pick a passkey, transactions route through 1auth intents\n * exactly as before. The app writes one downstream code path either way.\n *\n * This is purely additive: `OneAuthClient.connect()` and\n * `createOneAuthProvider()` are unchanged and remain the lower-level building\n * blocks this factory composes.\n *\n * @module\n */\n\nimport { OneAuthClient } from \"./client\";\nimport { createOneAuthProvider, type OneAuthProvider } from \"./provider\";\nimport type {\n CloseOnStatus,\n PasskeyProviderConfig,\n SignerType,\n ThemeConfig,\n} from \"./types\";\n\n/**\n * Default chain the returned provider reports and uses as the intent target\n * when a send omits an explicit chain. Base mainnet.\n */\nconst DEFAULT_CHAIN_ID = 8453;\n\n/**\n * Provider-shaping options that apply on top of the passkey client config.\n * Mirrors the relevant {@link createOneAuthProvider} options.\n */\nexport interface OneAuthConnectionOptions {\n /**\n * Chain the returned provider reports via `eth_chainId` and uses as the\n * default intent target. Defaults to `8453` (Base). Ignored for EOA sessions\n * beyond the reported chain id — an EOA transacts on whatever chain its\n * wallet is on.\n */\n defaultChainId?: number;\n /**\n * localStorage key the session is persisted under. Defaults to `\"1auth-user\"`.\n * Override only to run multiple independent connections on one origin.\n */\n storageKey?: string;\n /** Forwarded to the provider for passkey intent sends. */\n closeOn?: CloseOnStatus;\n waitForHash?: boolean;\n hashTimeoutMs?: number;\n hashIntervalMs?: number;\n /**\n * Opt in to offering a **traditional wallet as the account signer**. When\n * `true`, the dialog's wallet path connects the chosen EOA as the signer (a\n * `signerType: \"eoa\"` session whose transactions bypass Rhinestone intents).\n *\n * **Defaults to `false`** — by default the app gets 1auth smart accounts +\n * intents, and the wallet path (if the user picks it) still bootstraps a\n * passkey account. Passkey selection is unaffected either way. Can be\n * overridden per call via {@link OneAuthConnectOptions.eoaConnect}.\n */\n eoaConnect?: boolean;\n}\n\n/** Full config form: constructs the client for you. Only `clientId` is practically required. */\nexport type OneAuthConnectionConfig = PasskeyProviderConfig &\n OneAuthConnectionOptions;\n\n/** Reuse form: bring your own configured {@link OneAuthClient}. */\nexport type OneAuthConnectionConfigWithClient = {\n client: OneAuthClient;\n} & OneAuthConnectionOptions;\n\n/** Options accepted by {@link OneAuthConnection.connect}. */\nexport interface OneAuthConnectOptions {\n theme?: ThemeConfig;\n /** Applies only to the auth-modal fallback path (email/OAuth entry). */\n oauthEnabled?: boolean;\n /**\n * Per-call override of {@link OneAuthConnectionOptions.eoaConnect}. Defaults\n * to the connection's config value (which itself defaults to `false`).\n */\n eoaConnect?: boolean;\n}\n\n/**\n * The resolved session. Discriminated on `signerType` so callers can branch on\n * EOA vs passkey with full type safety.\n */\nexport interface OneAuthSession {\n /** `\"eoa\"` = traditional wallet (plain tx, no intents). `\"passkey\"` = 1auth smart account (intents). */\n signerType: SignerType;\n address: `0x${string}`;\n /** The same {@link OneAuthProvider} instance exposed on the connection. */\n provider: OneAuthProvider;\n /** Chain id the provider reports (see {@link OneAuthConnectionOptions.defaultChainId}). */\n chainId: number;\n /** True when a returning user was reconnected with no visible UI. */\n autoConnected: boolean;\n}\n\n/** Error thrown by {@link OneAuthConnection.connect} when the user cancels or auth fails. */\nexport interface OneAuthConnectError {\n code: string;\n message: string;\n}\n\n/** The handle returned by {@link createOneAuthConnection}. */\nexport interface OneAuthConnection {\n /** The underlying client — escape hatch for `signMessage`, history, the account dialog, etc. */\n client: OneAuthClient;\n /** Ready-to-use EIP-1193 provider. Stable across reconnects. */\n provider: OneAuthProvider;\n /**\n * Open the 1auth dialog so the user picks passkey OR a traditional wallet.\n * Binds the resulting session to {@link OneAuthConnection.provider} before it\n * resolves, so a send issued immediately after routes correctly.\n *\n * @throws {@link OneAuthConnectError} shape (`{ code, message }`) on cancel/failure.\n */\n connect: (options?: OneAuthConnectOptions) => Promise<OneAuthSession>;\n /** Current session read from persisted state, or `null`. Never opens a dialog. */\n getSession: () => OneAuthSession | null;\n /** Clear the session and emit `accountsChanged([])` / `disconnect`. */\n disconnect: () => Promise<void>;\n /**\n * Subscribe to session changes (connect/disconnect). Returns an unsubscribe\n * function. Sugar over `provider.on(\"accountsChanged\", …)`.\n */\n subscribe: (listener: (session: OneAuthSession | null) => void) => () => void;\n}\n\n/**\n * Reads the persisted session for this connection's storage key. Kept in this\n * module (rather than reaching into the provider) so `getSession` works without\n * a prior `connect()` — e.g. on a page reload where the app rehydrates.\n */\nfunction readStoredSession(\n storageKey: string,\n provider: OneAuthProvider,\n chainId: number,\n): OneAuthSession | null {\n if (typeof window === \"undefined\") return null;\n try {\n // Bare `localStorage` (not `window.localStorage`) to match provider.ts and\n // client.ts — in a browser they are identical, and it keeps the storage\n // access consistent across the SDK.\n const raw = localStorage.getItem(storageKey);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as {\n address?: `0x${string}`;\n signerType?: SignerType;\n };\n if (!parsed?.address) return null;\n return {\n // Absent signerType = legacy passkey session (backwards compatible).\n signerType: parsed.signerType === \"eoa\" ? \"eoa\" : \"passkey\",\n address: parsed.address,\n provider,\n chainId,\n autoConnected: false,\n };\n } catch {\n return null;\n }\n}\n\n/**\n * Create a one-call 1auth connection.\n *\n * @example Zero-boilerplate\n * ```typescript\n * import { createOneAuthConnection } from \"@rhinestone/1auth\";\n * import { createWalletClient, custom } from \"viem\";\n * import { base } from \"viem/chains\";\n *\n * const conn = createOneAuthConnection({ clientId: \"my-app\" });\n * const session = await conn.connect(); // user picks passkey OR wallet\n *\n * const walletClient = createWalletClient({\n * account: session.address,\n * chain: base,\n * transport: custom(session.provider),\n * });\n * // Same call for both signer types; EOA bypasses intents, passkey uses them.\n * await walletClient.sendTransaction({ to: \"0x…\", value: 1n });\n * ```\n *\n * @example Reuse an existing client\n * ```typescript\n * const client = new OneAuthClient({ clientId: \"my-app\", sponsorship });\n * const conn = createOneAuthConnection({ client, defaultChainId: 8453 });\n * const { address, signerType, provider } = await conn.connect();\n * ```\n */\nexport function createOneAuthConnection(\n config: OneAuthConnectionConfig,\n): OneAuthConnection;\nexport function createOneAuthConnection(\n config: OneAuthConnectionConfigWithClient,\n): OneAuthConnection;\nexport function createOneAuthConnection(\n config: OneAuthConnectionConfig | OneAuthConnectionConfigWithClient,\n): OneAuthConnection {\n const {\n defaultChainId,\n storageKey: storageKeyOption,\n closeOn,\n waitForHash,\n hashTimeoutMs,\n hashIntervalMs,\n eoaConnect: eoaConnectConfig,\n ...clientConfig\n } = config as OneAuthConnectionConfig & OneAuthConnectionConfigWithClient;\n\n // Reuse a supplied client, or construct one from the passkey config.\n const client =\n \"client\" in config && config.client\n ? config.client\n : new OneAuthClient(clientConfig as PasskeyProviderConfig);\n\n const chainId = defaultChainId ?? DEFAULT_CHAIN_ID;\n const storageKey = storageKeyOption ?? \"1auth-user\";\n\n const provider = createOneAuthProvider({\n client,\n chainId,\n storageKey,\n closeOn,\n waitForHash,\n hashTimeoutMs,\n hashIntervalMs,\n });\n\n const getSession = (): OneAuthSession | null =>\n readStoredSession(storageKey, provider, chainId);\n\n const connect = async (\n options?: OneAuthConnectOptions,\n ): Promise<OneAuthSession> => {\n // Wallet-as-signer is opt-in (default false → smart accounts + intents).\n // Per-call option wins over the connection's config default.\n const eoaConnect = options?.eoaConnect ?? eoaConnectConfig ?? false;\n const result = await client.connect({ ...options, eoaConnect });\n if (!result.success || !result.user?.address) {\n const error: OneAuthConnectError = result.error ?? {\n code: \"USER_CANCELLED\",\n message: \"Connection was cancelled\",\n };\n throw Object.assign(new Error(error.message), { code: error.code });\n }\n\n const signerType: SignerType =\n result.signerType === \"eoa\" ? \"eoa\" : \"passkey\";\n\n // Bind before returning so a transaction issued in the same tick routes to\n // the wallet (EOA) rather than falling back to passkey intents.\n provider.setSession({ address: result.user.address, signerType });\n\n return {\n signerType,\n address: result.user.address,\n provider,\n chainId,\n autoConnected: result.autoConnected ?? false,\n };\n };\n\n const disconnect = async (): Promise<void> => {\n await provider.disconnect();\n };\n\n const subscribe = (\n listener: (session: OneAuthSession | null) => void,\n ): (() => void) => {\n const onAccountsChanged = (...args: unknown[]) => {\n const accounts = args[0] as unknown[] | undefined;\n listener(\n accounts && accounts.length > 0 ? getSession() : null,\n );\n };\n provider.on(\"accountsChanged\", onAccountsChanged);\n return () => provider.removeListener(\"accountsChanged\", onAccountsChanged);\n };\n\n return { client, provider, connect, getSession, disconnect, subscribe };\n}\n","/**\n * viem LocalAccount adapter for 1auth passkey-controlled smart accounts.\n *\n * Bridges viem's `LocalAccount` interface to the 1auth passkey service so that\n * any viem-based library (e.g. permissionless, viem itself) can use a passkey\n * account without handling WebAuthn directly. All cryptographic operations are\n * delegated to the passkey service via `OneAuthClient`.\n *\n * @module\n */\n\nimport {\n bytesToString,\n hexToString,\n isHex,\n type Address,\n type LocalAccount,\n type SignableMessage,\n type TypedData,\n type TypedDataDefinition,\n} from \"viem\";\nimport { toAccount } from \"viem/accounts\";\nimport { OneAuthClient } from \"./client\";\nimport type { EIP712Domain, EIP712Types } from \"./types\";\nimport { encodeWebAuthnSignature } from \"./walletClient/utils\";\n\nexport type PasskeyAccount = LocalAccount<\"1auth\"> & {\n /** Smart account address used as the canonical signer identity. */\n accountAddress: Address;\n};\n\n/**\n * Creates a viem `LocalAccount` that delegates signing to the 1auth passkey service.\n *\n * The returned account satisfies the `LocalAccount` interface expected by viem's\n * `createWalletClient` and similar APIs. `signTransaction` is explicitly unsupported\n * because 1auth uses the intent/bundler model instead of raw signed transactions —\n * callers should use `sendIntent` (via `eth_sendTransaction` on the provider) instead.\n *\n * All signing operations encode the resulting WebAuthn signature with\n * `encodeWebAuthnSignature` so the output is directly usable with ERC-1271\n * on-chain verification.\n *\n * @param client - A configured `OneAuthClient` instance\n * @param params.address - The EVM address of the user's smart account\n * @returns A `PasskeyAccount` extending `LocalAccount<\"1auth\">`\n *\n * @example\n * ```typescript\n * import { createWalletClient, http } from \"viem\";\n * import { base } from \"viem/chains\";\n * import { OneAuthClient, createPasskeyAccount } from \"@rhinestone/1auth\";\n *\n * const client = new OneAuthClient({ clientId: \"my-app\" });\n * const account = createPasskeyAccount(client, {\n * address: \"0xYourSmartAccountAddress\",\n * });\n *\n * const walletClient = createWalletClient({\n * account,\n * chain: base,\n * transport: http(),\n * });\n *\n * const signature = await walletClient.signMessage({ message: \"Hello\" });\n * ```\n */\nexport function createPasskeyAccount(\n client: OneAuthClient,\n params: { address: Address }\n): PasskeyAccount {\n const { address } = params;\n\n /**\n * Converts viem's polymorphic `SignableMessage` type to a plain string.\n *\n * viem allows messages to be passed as a plain string, a hex-encoded string under\n * the `{ raw: Hex }` form, or raw bytes under the `{ raw: Uint8Array }` form. The\n * passkey service only accepts plain strings, so this helper normalises all three\n * variants. Hex values are decoded to their UTF-8 representation; if decoding fails\n * (e.g. the hex is not valid UTF-8) the raw hex string is passed through unchanged.\n *\n * @param message - viem `SignableMessage` in any of its supported forms\n * @returns Plain string representation of the message\n */\n const normalizeMessage = (message: SignableMessage): string => {\n if (typeof message === \"string\") return message;\n const raw = message.raw;\n if (isHex(raw)) {\n try {\n return hexToString(raw);\n } catch {\n return raw;\n }\n }\n return bytesToString(raw);\n };\n\n const account = toAccount({\n address,\n signMessage: async ({ message }: { message: SignableMessage }) => {\n const result = await client.signMessage({\n accountAddress: address,\n message: normalizeMessage(message),\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n },\n signTransaction: async () => {\n throw new Error(\"signTransaction not supported; use sendIntent\");\n },\n signTypedData: async <\n const typedData extends TypedData | Record<string, unknown>,\n primaryType extends keyof typedData | \"EIP712Domain\" = keyof typedData\n >(\n typedData: TypedDataDefinition<typedData, primaryType>\n ) => {\n if (!typedData.domain || !typedData.types || !typedData.primaryType) {\n throw new Error(\"Invalid typed data\");\n }\n const domainInput = typedData.domain as Partial<EIP712Domain>;\n if (!domainInput.name || !domainInput.version) {\n throw new Error(\"Typed data domain must include name and version\");\n }\n const domain: EIP712Domain = {\n name: domainInput.name,\n version: domainInput.version,\n // viem uses bigint for chainId in typed data; the passkey service expects number\n chainId:\n typeof domainInput.chainId === \"bigint\"\n ? Number(domainInput.chainId)\n : domainInput.chainId,\n verifyingContract: domainInput.verifyingContract,\n salt: domainInput.salt,\n };\n const rawTypes =\n typedData.types as Record<string, readonly { name: string; type: string }[]>;\n // Strip any extra fields (e.g. readonly markers) that viem attaches to type\n // entries — the passkey service expects plain { name, type } objects.\n const normalizedTypes = Object.fromEntries(\n Object.entries(rawTypes).map(([key, fields]) => [\n key,\n fields.map((field) => ({ name: field.name, type: field.type })),\n ])\n ) as EIP712Types;\n const result = await client.signTypedData({\n accountAddress: address,\n domain,\n types: normalizedTypes,\n primaryType: typedData.primaryType as string,\n message: typedData.message as Record<string, unknown>,\n });\n if (!result.success || !result.signature) {\n throw new Error(result.error?.message || \"Signing failed\");\n }\n return encodeWebAuthnSignature(result.signature);\n },\n });\n\n return {\n ...(account as LocalAccount<\"1auth\">),\n accountAddress: address,\n };\n}\n","/**\n * @file viem WalletClient factory backed by passkey signing.\n *\n * {@link createPasskeyWalletClient} returns a standard viem `WalletClient`\n * augmented with a `sendCalls` method for batched ERC-4337 intents. All\n * signing operations open the 1auth passkey modal so that private keys never\n * leave the secure enclave on the user's device.\n *\n * The factory is framework-agnostic — it works in any environment that can\n * run viem (React, Vue, plain Node.js scripts, etc.).\n */\n\nimport {\n createWalletClient,\n hashTypedData,\n toHex,\n type WalletClient,\n type Hash,\n type SignableMessage,\n type TypedDataDefinition,\n} from 'viem';\nimport { toAccount } from 'viem/accounts';\nimport { OneAuthClient } from '../client';\nimport type { IntentCall, IntentTokenRequest } from '../types';\nimport type {\n PasskeyWalletClientConfig,\n SendCallsParams,\n TransactionCall,\n} from './types';\nimport {\n encodeWebAuthnSignature,\n hashCalls,\n buildTransactionReview,\n} from './utils';\n\nexport type { PasskeyWalletClientConfig, TransactionCall, SendCallsParams } from './types';\nexport { encodeWebAuthnSignature, hashCalls } from './utils';\n\n/**\n * Extended WalletClient with passkey signing and batch transaction support\n */\nexport type PasskeyWalletClient = WalletClient & {\n /**\n * Send multiple calls as a single batched transaction\n * Opens the passkey modal for user approval\n */\n sendCalls: (params: SendCallsParams) => Promise<Hash>;\n};\n\n/**\n * Convert viem's message union into the string-only SDK message surface.\n */\nfunction formatSignableMessage(message: SignableMessage): string {\n if (typeof message === 'string') return message;\n return typeof message.raw === 'string' ? message.raw : toHex(message.raw);\n}\n\n/**\n * Create a viem-compatible WalletClient that uses passkeys for signing\n *\n * @example\n * ```typescript\n * import { createPasskeyWalletClient } from '@rhinestone/1auth';\n * import { baseSepolia } from 'viem/chains';\n * import { http } from 'viem';\n *\n * const walletClient = createPasskeyWalletClient({\n * accountAddress: '0x...',\n * providerUrl: 'https://passkey.1auth.app',\n * clientId: 'my-dapp',\n * chain: baseSepolia,\n * transport: http(),\n * });\n *\n * // Standard viem API\n * const hash = await walletClient.sendTransaction({\n * to: '0x...',\n * data: '0x...',\n * value: 0n,\n * });\n *\n * // Batched transactions\n * const batchHash = await walletClient.sendCalls({\n * calls: [\n * { to: '0x...', data: '0x...' },\n * { to: '0x...', data: '0x...' },\n * ],\n * });\n * ```\n */\nexport function createPasskeyWalletClient(\n config: PasskeyWalletClientConfig\n): PasskeyWalletClient {\n const identity = {\n accountAddress: config.accountAddress,\n };\n\n const provider = new OneAuthClient({\n providerUrl: config.providerUrl,\n clientId: config.clientId,\n dialogUrl: config.dialogUrl,\n theme: config.theme,\n blind_signing: config.blind_signing,\n testnets: config.testnets,\n sponsorship: config.sponsorship,\n });\n\n /**\n * Sign an arbitrary message using the passkey modal.\n *\n * Hashes the message with EIP-191 (`hashMessage`) before passing it to the\n * modal as the WebAuthn challenge so the on-chain verifier receives a\n * deterministic, typed hash rather than raw user data.\n *\n * @param message - A plain string or a `{ raw: Hex | Uint8Array }` object\n * as accepted by viem's `SignableMessage`.\n * @returns ABI-encoded WebAuthn signature as a `0x`-prefixed hex string.\n */\n const signMessageImpl = async (message: SignableMessage): Promise<`0x${string}`> => {\n const result = await provider.signMessage({\n ...identity,\n message: formatSignableMessage(message),\n description: 'Sign message',\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Signing failed');\n }\n\n if (!result.signature) {\n throw new Error('No signature received');\n }\n\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Sign a single transaction object using the passkey modal.\n *\n * Normalises the transaction into a `TransactionCall` array, computes a\n * deterministic hash over the calls with {@link hashCalls}, then presents\n * the transaction for user approval before encoding the resulting WebAuthn\n * signature.\n *\n * @param transaction - A viem transaction request object containing at least\n * `to`, and optionally `data` and `value`.\n * @returns ABI-encoded WebAuthn signature as a `0x`-prefixed hex string.\n */\n const signTransactionImpl = async (transaction: any): Promise<`0x${string}`> => {\n const calls: TransactionCall[] = [\n {\n to: transaction.to!,\n data: transaction.data,\n value: transaction.value,\n },\n ];\n\n const hash = hashCalls(calls);\n\n const result = await provider.signWithModal({\n challenge: hash,\n ...identity,\n description: 'Sign transaction',\n transaction: buildTransactionReview(calls),\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Signing failed');\n }\n\n if (!result.signature) {\n throw new Error('No signature received');\n }\n\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Sign EIP-712 typed data using the passkey modal.\n *\n * Hashes the structured data with viem's `hashTypedData` (which applies the\n * EIP-712 domain separator and struct hashing) and presents the primary type\n * name to the user as a human-readable label inside the signing dialog.\n *\n * @param typedData - EIP-712 typed data definition including `domain`,\n * `types`, `primaryType`, and `message`.\n * @returns ABI-encoded WebAuthn signature as a `0x`-prefixed hex string.\n */\n const signTypedDataImpl = async (typedData: any): Promise<`0x${string}`> => {\n const hash = hashTypedData(typedData as TypedDataDefinition);\n\n const result = await provider.signWithModal({\n challenge: hash,\n ...identity,\n description: 'Sign typed data',\n transaction: {\n actions: [\n {\n type: 'custom',\n label: 'Sign Data',\n sublabel: typedData.primaryType || 'Typed Data',\n },\n ],\n },\n });\n\n if (!result.success) {\n throw new Error(result.error?.message || 'Signing failed');\n }\n\n if (!result.signature) {\n throw new Error('No signature received');\n }\n\n return encodeWebAuthnSignature(result.signature);\n };\n\n /**\n * Build the intent payload shared by `sendTransaction` and `sendCalls`.\n *\n * Converts `TransactionCall` objects (viem-style, with bigint values) into\n * `IntentCall` objects (serialisable, with string values) expected by the\n * passkey service. The target chain defaults to `config.chain.id` when no\n * override is provided.\n *\n * @param calls - One or more transaction calls to include in the intent.\n * @param targetChainOverride - Optional chain ID; overrides `config.chain.id`\n * when the intent should execute on a chain different from the client's\n * default (e.g. cross-chain intent routing).\n * @param extra - Optional token request and source asset metadata forwarded\n * to the Rhinestone orchestrator for cross-chain bridging intents.\n * @returns A plain object ready to spread into `provider.sendIntent(...)`.\n */\n const buildIntentPayload = async (\n calls: TransactionCall[],\n targetChainOverride?: number,\n extra?: { tokenRequests?: IntentTokenRequest[]; sourceAssets?: string[] },\n ) => {\n const targetChain = targetChainOverride ?? config.chain.id;\n const intentCalls: IntentCall[] = calls.map((call) => ({\n to: call.to,\n data: call.data || \"0x\",\n value: call.value !== undefined ? call.value.toString() : \"0\",\n label: call.label,\n sublabel: call.sublabel,\n icon: call.icon,\n abi: call.abi,\n }));\n\n return {\n accountAddress: config.accountAddress,\n targetChain,\n calls: intentCalls,\n };\n };\n\n // toAccount returns a generic LocalAccount<string> but viem's WalletClient\n // constructor expects LocalAccount<\"custom\"> — the type assertion satisfies\n // this constraint without changing runtime behaviour.\n const account = toAccount({\n address: config.accountAddress,\n signMessage: ({ message }) => signMessageImpl(message),\n signTransaction: signTransactionImpl,\n signTypedData: signTypedDataImpl as any,\n });\n\n // Create the base wallet client\n const client = createWalletClient({\n account,\n chain: config.chain,\n transport: config.transport,\n });\n\n // Extend with sendCalls for batched transactions\n const extendedClient = Object.assign(client, {\n /**\n * Send a single transaction via intent flow\n */\n async sendTransaction(transaction: any): Promise<Hash> {\n const targetChain =\n typeof transaction.chainId === \"number\"\n ? transaction.chainId\n : transaction.chain?.id;\n const calls: TransactionCall[] = [\n {\n to: transaction.to!,\n data: transaction.data || \"0x\",\n value: transaction.value,\n },\n ];\n\n const intentPayload = await buildIntentPayload(calls, targetChain);\n const result = await provider.sendIntent({\n ...intentPayload,\n waitForHash: config.waitForHash ?? true,\n hashTimeoutMs: config.hashTimeoutMs,\n hashIntervalMs: config.hashIntervalMs,\n });\n\n if (!result.success || !result.transactionHash) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n return result.transactionHash as Hash;\n },\n /**\n * Send multiple calls as a single batched transaction\n */\n async sendCalls(params: SendCallsParams): Promise<Hash> {\n const { calls, chainId: targetChain, tokenRequests, sourceAssets, sourceChainId } = params;\n const intentPayload = await buildIntentPayload(calls, targetChain, { tokenRequests, sourceAssets });\n const result = await provider.sendIntent({\n ...intentPayload,\n tokenRequests,\n sourceAssets,\n sourceChainId,\n waitForHash: config.waitForHash ?? true,\n hashTimeoutMs: config.hashTimeoutMs,\n hashIntervalMs: config.hashIntervalMs,\n });\n\n if (!result.success || !result.transactionHash) {\n throw new Error(result.error?.message || \"Transaction failed\");\n }\n\n return result.transactionHash as Hash;\n },\n });\n\n return extendedClient as PasskeyWalletClient;\n}\n","import * as React from \"react\";\nimport type { OneAuthClient } from \"../client\";\nimport type { IntentCall, SendIntentResult } from \"../types\";\nimport { getChainName as getRegistryChainName } from \"../registry\";\n\n/** Identity used to sign a queued batch. Account address is the sole identity. */\nexport interface BatchQueueIdentity {\n /** Smart account address of the signer. */\n accountAddress: string;\n}\n\n/**\n * A batched call in the queue\n */\nexport interface BatchedCall {\n /** Unique ID for removal */\n id: string;\n /** The actual call data */\n call: IntentCall;\n /** Chain ID for execution */\n targetChain: number;\n /** Timestamp when added */\n addedAt: number;\n}\n\nexport function getChainName(chainId: number): string {\n return getRegistryChainName(chainId);\n}\n\n/**\n * Batch queue context value\n */\nexport interface BatchQueueContextValue {\n /** Current queue of batched calls */\n queue: BatchedCall[];\n /** Chain ID of the current batch (from first call) */\n batchChainId: number | null;\n /** Add a call to the batch */\n addToBatch: (call: IntentCall, targetChain: number) => { success: boolean; error?: string };\n /** Remove a call from the batch */\n removeFromBatch: (id: string) => void;\n /** Clear all calls from the batch */\n clearBatch: () => void;\n /** Sign and execute all batched calls. A bare string is treated as the account address. */\n signAll: (identity?: string | BatchQueueIdentity) => Promise<SendIntentResult>;\n /** Whether the widget is expanded */\n isExpanded: boolean;\n /** Set widget expanded state */\n setExpanded: (expanded: boolean) => void;\n /** Whether signing is in progress */\n isSigning: boolean;\n /** Animation trigger for bounce effect */\n animationTrigger: number;\n}\n\nconst BatchQueueContext = React.createContext<BatchQueueContextValue | null>(null);\n\n/**\n * Hook to access the batch queue context\n */\nexport function useBatchQueue(): BatchQueueContextValue {\n const context = React.useContext(BatchQueueContext);\n if (!context) {\n throw new Error(\"useBatchQueue must be used within a BatchQueueProvider\");\n }\n return context;\n}\n\n/**\n * Generate a unique ID for a batched call\n */\nfunction generateId(): string {\n return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n}\n\n/**\n * localStorage key for persisting the batch queue.\n *\n * Queues are keyed by account address — the sole account identity.\n */\nfunction getStorageKey(identity?: { accountAddress?: string }): string {\n const key = identity?.accountAddress;\n return key ? `1auth_batch_queue_${key.toLowerCase()}` : \"1auth_batch_queue_anonymous\";\n}\n\n/** Normalize a `signAll(address)` string or identity object against provider props into one shape. */\nfunction resolveIdentity(\n passedIdentity: string | BatchQueueIdentity | undefined,\n providerIdentity: { accountAddress?: string },\n): { accountAddress?: string } {\n if (typeof passedIdentity === \"string\") {\n // A bare string is the account address — the canonical (and only) identity.\n return { accountAddress: passedIdentity };\n }\n return {\n accountAddress: passedIdentity?.accountAddress ?? providerIdentity.accountAddress,\n };\n}\n\nexport interface BatchQueueProviderProps {\n /** The OneAuthClient instance */\n client: OneAuthClient;\n /** Account address for localStorage persistence and account lookup. */\n accountAddress?: string;\n /** Children to render */\n children: React.ReactNode;\n}\n\n/**\n * Provider component for the batch queue\n */\nexport function BatchQueueProvider({\n client,\n accountAddress,\n children,\n}: BatchQueueProviderProps) {\n const [queue, setQueue] = React.useState<BatchedCall[]>([]);\n const [isExpanded, setExpanded] = React.useState(false);\n const [isSigning, setIsSigning] = React.useState(false);\n const [animationTrigger, setAnimationTrigger] = React.useState(0);\n\n const providerIdentity = React.useMemo(\n () => ({ accountAddress }),\n [accountAddress],\n );\n\n // Derive batch chain from first call in queue\n const batchChainId = queue.length > 0 ? queue[0].targetChain : null;\n\n // Load queue from localStorage on mount\n React.useEffect(() => {\n const storageKey = getStorageKey(providerIdentity);\n try {\n const stored = localStorage.getItem(storageKey);\n if (stored) {\n const parsed = JSON.parse(stored) as BatchedCall[];\n // Validate the structure\n if (Array.isArray(parsed) && parsed.every(item =>\n typeof item.id === 'string' &&\n typeof item.call === 'object' &&\n typeof item.targetChain === 'number'\n )) {\n setQueue(parsed);\n }\n }\n } catch {\n // Ignore localStorage errors\n }\n }, [providerIdentity]);\n\n // Save queue to localStorage when it changes\n React.useEffect(() => {\n const storageKey = getStorageKey(providerIdentity);\n try {\n if (queue.length > 0) {\n localStorage.setItem(storageKey, JSON.stringify(queue));\n } else {\n localStorage.removeItem(storageKey);\n }\n } catch {\n // Ignore localStorage errors\n }\n }, [queue, providerIdentity]);\n\n const addToBatch = React.useCallback((call: IntentCall, targetChain: number): { success: boolean; error?: string } => {\n // Check if trying to add to a batch with a different chain\n if (batchChainId !== null && batchChainId !== targetChain) {\n return {\n success: false,\n error: `Batch is set to ${getChainName(batchChainId)}. Sign current batch first or clear it.`,\n };\n }\n\n const batchedCall: BatchedCall = {\n id: generateId(),\n call,\n targetChain,\n addedAt: Date.now(),\n };\n\n setQueue(prev => [...prev, batchedCall]);\n setAnimationTrigger(prev => prev + 1);\n\n return { success: true };\n }, [batchChainId]);\n\n const removeFromBatch = React.useCallback((id: string) => {\n setQueue(prev => prev.filter(item => item.id !== id));\n }, []);\n\n const clearBatch = React.useCallback(() => {\n setQueue([]);\n setExpanded(false);\n }, []);\n\n const signAll = React.useCallback(async (\n identity?: string | BatchQueueIdentity,\n ): Promise<SendIntentResult> => {\n if (queue.length === 0) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"EMPTY_BATCH\",\n message: \"No calls in batch to sign\",\n },\n };\n }\n\n const signer = resolveIdentity(identity, providerIdentity);\n if (!signer.accountAddress) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"MISSING_IDENTITY\",\n message: \"Batch signing requires an accountAddress\",\n },\n };\n }\n\n const targetChain = queue[0].targetChain;\n const calls = queue.map(item => item.call);\n\n setIsSigning(true);\n\n try {\n const result = await client.sendIntent({\n accountAddress: signer.accountAddress,\n targetChain,\n calls,\n });\n\n if (result.success) {\n // Clear the batch on success\n clearBatch();\n }\n\n return result;\n } finally {\n setIsSigning(false);\n }\n }, [queue, client, clearBatch, providerIdentity]);\n\n const value: BatchQueueContextValue = {\n queue,\n batchChainId,\n addToBatch,\n removeFromBatch,\n clearBatch,\n signAll,\n isExpanded,\n setExpanded,\n isSigning,\n animationTrigger,\n };\n\n return (\n <BatchQueueContext.Provider value={value}>\n {children}\n </BatchQueueContext.Provider>\n );\n}\n","/**\n * @file Floating UI widget for the 1auth batch transaction queue.\n *\n * Renders a fixed-position card anchored to the bottom-right of the viewport\n * that shows how many calls are queued and on which chain. The widget is\n * invisible while the queue is empty and mounts itself into the React tree\n * wherever `BatchQueueProvider` wraps the application.\n *\n * CSS keyframe animations are injected into `document.head` once on mount\n * via {@link injectStyles} so that no stylesheet import is required from the\n * consumer's bundler.\n */\n\nimport * as React from \"react\";\nimport { useBatchQueue, getChainName } from \"./BatchQueueContext\";\n\n// batch-bounce-in: played on the whole widget when a new call is added to the\n// queue — a subtle scale pop that draws attention without being distracting.\n// batch-item-bounce: reserved for future per-item jiggle feedback (not\n// currently triggered by default, available via inline animation assignment).\nconst ANIMATION_STYLES = `\n@keyframes batch-bounce-in {\n 0% { transform: scale(0.8); opacity: 0; }\n 50% { transform: scale(1.05); }\n 100% { transform: scale(1); opacity: 1; }\n}\n@keyframes batch-item-bounce {\n 0%, 100% { transform: translateX(0); }\n 25% { transform: translateX(-2px); }\n 75% { transform: translateX(2px); }\n}\n`;\n\n/**\n * Inject the widget's CSS keyframe animations into `document.head`.\n *\n * Uses a stable element ID (`\"batch-queue-widget-styles\"`) as a guard so the\n * style tag is only inserted once even if the component mounts multiple times\n * (e.g. during React strict-mode double-invocation or hot reloads). No-ops in\n * non-browser environments (SSR/Node) where `document` is undefined.\n */\nfunction injectStyles() {\n if (typeof document === \"undefined\") return;\n const styleId = \"batch-queue-widget-styles\";\n if (document.getElementById(styleId)) return;\n\n const style = document.createElement(\"style\");\n style.id = styleId;\n style.textContent = ANIMATION_STYLES;\n document.head.appendChild(style);\n}\n\n// Fixed bottom-right positioning keeps the widget out of the page flow so it\n// never displaces content. z-index 50 sits above typical page elements but\n// below full-screen modals (which usually start at 100+).\nconst widgetStyles: React.CSSProperties = {\n position: \"fixed\",\n bottom: \"16px\",\n right: \"16px\",\n zIndex: 50,\n backgroundColor: \"#18181b\",\n color: \"#ffffff\",\n borderRadius: \"12px\",\n boxShadow: \"0 4px 12px rgba(0,0,0,0.3)\",\n minWidth: \"240px\",\n maxWidth: \"360px\",\n fontFamily: \"system-ui, -apple-system, sans-serif\",\n fontSize: \"14px\",\n overflow: \"hidden\",\n};\n\nconst headerStyles: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"12px 16px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n};\n\nconst headerLeftStyles: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n};\n\nconst counterBadgeStyles: React.CSSProperties = {\n backgroundColor: \"#ffffff\",\n color: \"#18181b\",\n borderRadius: \"9999px\",\n padding: \"2px 8px\",\n fontSize: \"12px\",\n fontWeight: 600,\n};\n\nconst chainBadgeStyles: React.CSSProperties = {\n backgroundColor: \"rgba(255,255,255,0.15)\",\n color: \"#a1a1aa\",\n borderRadius: \"4px\",\n padding: \"2px 6px\",\n fontSize: \"11px\",\n};\n\nconst signAllButtonStyles: React.CSSProperties = {\n backgroundColor: \"#ffffff\",\n color: \"#18181b\",\n border: \"none\",\n borderRadius: \"6px\",\n padding: \"6px 12px\",\n fontSize: \"13px\",\n fontWeight: 500,\n cursor: \"pointer\",\n transition: \"background-color 0.15s\",\n};\n\nconst signAllButtonHoverStyles: React.CSSProperties = {\n backgroundColor: \"#e4e4e7\",\n};\n\nconst signAllButtonDisabledStyles: React.CSSProperties = {\n opacity: 0.5,\n cursor: \"not-allowed\",\n};\n\nconst listContainerStyles: React.CSSProperties = {\n maxHeight: \"300px\",\n overflowY: \"auto\",\n borderTop: \"1px solid #27272a\",\n};\n\nconst callItemStyles: React.CSSProperties = {\n display: \"flex\",\n alignItems: \"flex-start\",\n padding: \"10px 16px\",\n borderBottom: \"1px solid #27272a\",\n position: \"relative\",\n};\n\nconst callItemLastStyles: React.CSSProperties = {\n borderBottom: \"none\",\n};\n\nconst callContentStyles: React.CSSProperties = {\n flex: 1,\n minWidth: 0,\n};\n\nconst callLabelStyles: React.CSSProperties = {\n fontWeight: 500,\n marginBottom: \"2px\",\n};\n\nconst callSublabelStyles: React.CSSProperties = {\n color: \"#a1a1aa\",\n fontSize: \"12px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n};\n\nconst removeButtonStyles: React.CSSProperties = {\n position: \"absolute\",\n left: \"8px\",\n top: \"50%\",\n transform: \"translateY(-50%)\",\n backgroundColor: \"#dc2626\",\n color: \"#ffffff\",\n border: \"none\",\n borderRadius: \"4px\",\n width: \"20px\",\n height: \"20px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n fontSize: \"14px\",\n opacity: 0,\n transition: \"opacity 0.15s\",\n};\n\nconst removeButtonVisibleStyles: React.CSSProperties = {\n opacity: 1,\n};\n\nconst clearButtonStyles: React.CSSProperties = {\n display: \"block\",\n width: \"100%\",\n padding: \"10px 16px\",\n backgroundColor: \"transparent\",\n color: \"#a1a1aa\",\n border: \"none\",\n borderTop: \"1px solid #27272a\",\n fontSize: \"12px\",\n cursor: \"pointer\",\n textAlign: \"center\",\n transition: \"color 0.15s\",\n};\n\nconst clearButtonHoverStyles: React.CSSProperties = {\n color: \"#ffffff\",\n};\n\n/**\n * Animated chevron arrow used as the expand/collapse indicator in the widget\n * header. Points downward when the list is expanded and rotates 90° counter-\n * clockwise (points right) when collapsed, providing a clear affordance for\n * the toggle action.\n *\n * @param down - `true` when the queue list is expanded (chevron points down).\n */\nfunction ChevronIcon({ down }: { down: boolean }) {\n return (\n <svg\n width=\"16\"\n height=\"16\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n style={{\n transition: \"transform 0.2s\",\n transform: down ? \"rotate(0deg)\" : \"rotate(-90deg)\",\n }}\n >\n <path d=\"m6 9 6 6 6-6\" />\n </svg>\n );\n}\n\nexport interface BatchQueueWidgetProps {\n /** Callback when \"Sign All\" is clicked. */\n onSignAll: () => void;\n}\n\n/**\n * Floating widget that displays the current batch transaction queue.\n *\n * Renders nothing while the queue is empty. When calls are present it shows a\n * fixed card in the bottom-right corner of the viewport with:\n * - A count badge and optional chain name in the header.\n * - A \"Sign All\" button that invokes `onSignAll` to begin the signing ceremony.\n * - An expandable list of queued calls with per-item remove buttons revealed\n * on hover and a \"Clear batch\" footer to discard all pending calls at once.\n *\n * A brief scale animation (`batch-bounce-in`) plays each time a new call is\n * added to the queue to draw the user's attention without interrupting flow.\n *\n * Must be rendered inside a `BatchQueueProvider`.\n *\n * @param props.onSignAll - Called when the user clicks \"Sign All\". The\n * implementor is responsible for resolving the account identity and passing\n * it to `useBatchQueue().signAll({ accountAddress })`.\n */\nexport function BatchQueueWidget({ onSignAll }: BatchQueueWidgetProps) {\n const {\n queue,\n batchChainId,\n removeFromBatch,\n clearBatch,\n isExpanded,\n setExpanded,\n isSigning,\n animationTrigger,\n } = useBatchQueue();\n\n const [hoveredItemId, setHoveredItemId] = React.useState<string | null>(null);\n const [isSignAllHovered, setIsSignAllHovered] = React.useState(false);\n const [isClearHovered, setIsClearHovered] = React.useState(false);\n const [shouldAnimate, setShouldAnimate] = React.useState(false);\n\n // Inject CSS animations on mount\n React.useEffect(() => {\n injectStyles();\n }, []);\n\n // Trigger bounce animation when item is added\n React.useEffect(() => {\n if (animationTrigger > 0) {\n setShouldAnimate(true);\n const timer = setTimeout(() => setShouldAnimate(false), 300);\n return () => clearTimeout(timer);\n }\n }, [animationTrigger]);\n\n // Don't render if queue is empty\n if (queue.length === 0) {\n return null;\n }\n\n const handleHeaderClick = () => {\n setExpanded(!isExpanded);\n };\n\n const handleSignAllClick = (e: React.MouseEvent) => {\n e.stopPropagation(); // Don't toggle expand\n if (!isSigning) {\n onSignAll();\n }\n };\n\n const animatedWidgetStyles: React.CSSProperties = {\n ...widgetStyles,\n animation: shouldAnimate ? \"batch-bounce-in 0.3s ease-out\" : undefined,\n };\n\n const currentSignAllStyles: React.CSSProperties = {\n ...signAllButtonStyles,\n ...(isSignAllHovered && !isSigning ? signAllButtonHoverStyles : {}),\n ...(isSigning ? signAllButtonDisabledStyles : {}),\n };\n\n return (\n <div style={animatedWidgetStyles}>\n {/* Header - always visible */}\n <div style={headerStyles} onClick={handleHeaderClick}>\n <div style={headerLeftStyles}>\n <ChevronIcon down={isExpanded} />\n <span style={counterBadgeStyles}>{queue.length}</span>\n <span>call{queue.length !== 1 ? \"s\" : \"\"} queued</span>\n {batchChainId && (\n <span style={chainBadgeStyles}>{getChainName(batchChainId)}</span>\n )}\n </div>\n <button\n style={currentSignAllStyles}\n onClick={handleSignAllClick}\n onMouseEnter={() => setIsSignAllHovered(true)}\n onMouseLeave={() => setIsSignAllHovered(false)}\n disabled={isSigning}\n >\n {isSigning ? \"Signing...\" : \"Sign All\"}\n </button>\n </div>\n\n {/* Expanded list of calls */}\n {isExpanded && (\n <>\n <div style={listContainerStyles}>\n {queue.map((item, index) => {\n const isHovered = hoveredItemId === item.id;\n const isLast = index === queue.length - 1;\n\n return (\n <div\n key={item.id}\n style={{\n ...callItemStyles,\n ...(isLast ? callItemLastStyles : {}),\n paddingLeft: isHovered ? \"36px\" : \"16px\",\n transition: \"padding-left 0.15s\",\n }}\n onMouseEnter={() => setHoveredItemId(item.id)}\n onMouseLeave={() => setHoveredItemId(null)}\n >\n <button\n style={{\n ...removeButtonStyles,\n ...(isHovered ? removeButtonVisibleStyles : {}),\n }}\n onClick={() => removeFromBatch(item.id)}\n title=\"Remove from batch\"\n >\n ×\n </button>\n <div style={callContentStyles}>\n <div style={callLabelStyles}>\n {item.call.label || \"Contract Call\"}\n </div>\n {item.call.sublabel && (\n <div style={callSublabelStyles}>{item.call.sublabel}</div>\n )}\n {!item.call.sublabel && item.call.to && (\n <div style={callSublabelStyles}>\n To: {item.call.to.slice(0, 6)}...{item.call.to.slice(-4)}\n </div>\n )}\n </div>\n </div>\n );\n })}\n </div>\n\n {/* Clear batch button */}\n <button\n style={{\n ...clearButtonStyles,\n ...(isClearHovered ? clearButtonHoverStyles : {}),\n }}\n onClick={clearBatch}\n onMouseEnter={() => setIsClearHovered(true)}\n onMouseLeave={() => setIsClearHovered(false)}\n >\n Clear batch\n </button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":"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","names":["balances","result","next","prepareResult","signingResult","dialogOrigin","closeOn","successStatuses","dialog","iframe","hashTypedData","toAccount","hashTypedData","toAccount","getChainName","React","jsx","getChainName"]}
|