@rhinestone/1auth 0.6.5 → 0.6.7

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/account.ts","../src/walletClient/index.ts","../src/batch/BatchQueueContext.tsx","../src/batch/BatchQueueWidget.tsx","../src/verify.ts"],"sourcesContent":["import { parseUnits, hashTypedData, type TypedDataDefinition, type Address } from \"viem\";\nimport type {\n PasskeyProviderConfig,\n SigningRequestOptions,\n SigningResult,\n CreateSigningRequestResponse,\n SigningRequestStatus,\n SigningErrorCode,\n EmbedOptions,\n UserPasskeysResponse,\n PasskeyCredential,\n AuthResult,\n ConnectResult,\n AuthenticateOptions,\n AuthenticateResult,\n SendIntentOptions,\n SendIntentResult,\n PrepareIntentResponse,\n ExecuteIntentResponse,\n WebAuthnSignature,\n SendSwapOptions,\n SendSwapResult,\n ThemeConfig,\n SignMessageOptions,\n SignMessageResult,\n SignTypedDataOptions,\n SignTypedDataResult,\n IntentHistoryOptions,\n IntentHistoryResult,\n IntentTokenRequest,\n SendBatchIntentOptions,\n SendBatchIntentResult,\n PrepareBatchIntentResponse,\n BatchIntentItemResult,\n CheckConsentOptions,\n CheckConsentResult,\n RequestConsentOptions,\n RequestConsentResult,\n} from \"./types\";\nimport {\n getChainById,\n getSupportedTokens,\n getTokenDecimals,\n getTokenSymbol,\n isTokenAddressSupported,\n resolveTokenAddress,\n} from \"./registry\";\n\nconst POPUP_WIDTH = 450;\nconst POPUP_HEIGHT = 600;\nconst DEFAULT_EMBED_WIDTH = \"400px\";\nconst DEFAULT_EMBED_HEIGHT = \"500px\";\nconst DEFAULT_PROVIDER_URL = \"https://passkey.1auth.box\";\n\ntype NormalizedPasskeyProviderConfig = PasskeyProviderConfig & {\n providerUrl: string;\n dialogUrl: string;\n};\n\nexport class OneAuthClient {\n private config: NormalizedPasskeyProviderConfig;\n private theme: ThemeConfig;\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\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 }\n }\n\n /**\n * Update the theme configuration at runtime\n */\n setTheme(theme: ThemeConfig): void {\n this.theme = theme;\n }\n\n /**\n * Build theme URL parameters\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 if (theme.accent) {\n params.set('accent', theme.accent);\n }\n\n return params.toString();\n }\n\n /**\n * Get the dialog URL (Vite app URL)\n * Defaults to providerUrl if dialogUrl is not set\n */\n private getDialogUrl(): string {\n return this.config.dialogUrl || this.config.providerUrl;\n }\n\n /**\n * Get the origin for message validation\n * Uses dialogUrl origin if set, otherwise providerUrl origin\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 private async waitForTransactionHash(\n intentId: string,\n options: { timeoutMs?: number; intervalMs?: number } = {}\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: this.config.clientId\n ? { \"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 * @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?: {\n username?: string;\n theme?: ThemeConfig;\n oauthEnabled?: boolean;\n }): Promise<AuthResult> {\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 if (options?.username) {\n params.set('username', options.username);\n }\n if (options?.oauthEnabled === false) {\n params.set('oauth', '0');\n }\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/auth?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n return this.waitForModalAuthResponse(dialog, iframe, cleanup);\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 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\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\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n });\n if (!ready) {\n return {\n success: false,\n action: \"cancel\",\n error: { code: \"USER_CANCELLED\", message: \"Connection was cancelled\" },\n };\n }\n\n return this.waitForConnectResponse(dialog, iframe, cleanup);\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 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;\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 * Check if a user has already granted consent for the requested fields.\n * This is a read-only check — no dialog is shown.\n *\n * @example\n * ```typescript\n * const result = await client.checkConsent({\n * username: \"alice\",\n * fields: [\"email\"],\n * });\n * if (result.hasConsent) {\n * console.log(result.data?.email);\n * }\n * ```\n */\n async checkConsent(options: CheckConsentOptions): Promise<CheckConsentResult> {\n const clientId = options.clientId ?? this.config.clientId;\n if (!clientId) {\n return {\n hasConsent: false,\n };\n }\n\n const username = options.username ?? options.accountAddress;\n if (!username) {\n return {\n hasConsent: false,\n };\n }\n\n try {\n const res = await fetch(`${this.config.providerUrl || \"https://passkey.1auth.box\"}/api/consent`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(clientId ? { \"x-client-id\": clientId } : {}),\n },\n body: JSON.stringify({\n username,\n requestedFields: options.fields,\n clientId,\n }),\n });\n\n if (!res.ok) {\n return { hasConsent: false };\n }\n\n const data = await res.json();\n return {\n hasConsent: data.hasConsent ?? false,\n data: data.data,\n grantedAt: data.grantedAt,\n };\n } catch {\n return { hasConsent: false };\n }\n }\n\n /**\n * Request consent from the user to share their data.\n *\n * First checks if consent was already granted (returns cached data immediately).\n * If not, opens the consent dialog where the user can review and approve sharing.\n *\n * @example\n * ```typescript\n * const result = await client.requestConsent({\n * username: \"alice\",\n * fields: [\"email\", \"deviceNames\"],\n * });\n * if (result.success) {\n * console.log(result.data?.email);\n * console.log(result.cached); // true if no dialog was shown\n * }\n * ```\n */\n async requestConsent(options: RequestConsentOptions): Promise<RequestConsentResult> {\n const clientId = options.clientId ?? this.config.clientId;\n if (!clientId) {\n return {\n success: false,\n error: { code: \"INVALID_REQUEST\", message: \"clientId is required (set in config or options)\" },\n };\n }\n\n const username = options.username ?? options.accountAddress;\n if (!username) {\n return {\n success: false,\n error: { code: \"INVALID_REQUEST\", message: \"username or accountAddress is required\" },\n };\n }\n\n if (!options.fields || options.fields.length === 0) {\n return {\n success: false,\n error: { code: \"INVALID_REQUEST\", message: \"At least one field is required\" },\n };\n }\n\n // Check if consent already granted\n const existing = await this.checkConsent({ ...options, clientId });\n if (existing.hasConsent && existing.data) {\n return {\n success: true,\n data: existing.data,\n grantedAt: existing.grantedAt,\n cached: true,\n };\n }\n\n // Open consent dialog\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: \"iframe\",\n username,\n clientId,\n fields: options.fields.join(\",\"),\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/consent?${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) {\n return {\n success: false,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n\n return this.waitForConsentResponse(dialog, iframe, cleanup);\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)\n * 2. The challenge is hashed with a domain separator\n * 3. User signs the hash with their passkey\n * 4. Returns user info + signature for server-side verification\n *\n * The domain separator (\"\\x19Passkey Signed Message:\\n\") ensures the signature\n * cannot be reused for transaction signing, preventing phishing attacks.\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 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\n if (options?.challenge) {\n params.set('challenge', options.challenge);\n }\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/authenticate?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n return this.waitForAuthenticateResponse(dialog, iframe, cleanup);\n }\n\n /**\n * Show signing in a modal overlay (iframe dialog)\n */\n async signWithModal(options: SigningRequestOptions & { theme?: ThemeConfig }): Promise<SigningResult> {\n const dialogUrl = this.getDialogUrl();\n const themeParams = this.getThemeParams(options?.theme);\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n challenge: options.challenge,\n username: options.username,\n description: options.description,\n transaction: options.transaction,\n metadata: options.metadata,\n });\n if (!ready) {\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n\n return this.waitForSigningResponse(dialog, iframe, cleanup);\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 // Determine username, targetChain, and calls from either signedIntent or direct options\n const signedIntent = options.signedIntent\n ? {\n ...options.signedIntent,\n merchantId:\n options.signedIntent.merchantId || options.signedIntent.developerId,\n }\n : undefined;\n const username = signedIntent?.username || options.username;\n const targetChain = signedIntent?.targetChain || options.targetChain;\n const calls = signedIntent?.calls || options.calls;\n\n if (signedIntent && !signedIntent.merchantId) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"Signed intent requires developerId (clientId)\",\n },\n };\n }\n\n // Validate we have required fields\n const accountAddress = signedIntent?.accountAddress || options.accountAddress;\n if (!username && !accountAddress) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"Either username, accountAddress, or signedIntent with user identifier is required\",\n },\n };\n }\n\n if (!targetChain || !calls?.length) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"targetChain and calls are required (either directly or via signedIntent)\",\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 // Define requestBody outside try block so it's accessible for quote refresh\n const requestBody = signedIntent || {\n username: options.username,\n accountAddress: options.accountAddress,\n targetChain: options.targetChain,\n calls: options.calls,\n tokenRequests: serializedTokenRequests,\n sourceAssets: options.sourceAssets,\n sourceChainId: options.sourceChainId,\n ...(this.config.clientId && { clientId: this.config.clientId }),\n };\n\n // 1. Show dialog immediately + prepare in parallel\n // The dialog starts in \"loading\" state and waits for PASSKEY_INIT data.\n // Two-phase approach: send raw calls early so the dialog can decode and\n // display actions immediately, then send quote data when prepare completes.\n const dialogUrl = this.getDialogUrl();\n const themeParams = this.getThemeParams();\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const dialogOrigin = this.getDialogOrigin();\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 } };\n let earlyPrepareResult: PrepareResult | null = null;\n const preparePromise = this.prepareIntent(requestBody).then((r) => {\n earlyPrepareResult = r;\n return r;\n });\n\n // Wait for iframe to be ready\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\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 // Mutable init payload — starts as early preview, upgraded to full after quote\n let currentInitPayload: Record<string, unknown>;\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 const prepareResult = earlyPrepareResult as PrepareResult;\n if (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n await this.waitForDialogClose(dialog, cleanup);\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResponse = prepareResult.data;\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 tier: prepareResult.tier,\n };\n dialogResult.sendInit(currentInitPayload);\n } else {\n // Progressive path: send early preview with raw calls so the dialog\n // can decode and display transaction actions immediately\n currentInitPayload = {\n mode: \"iframe\",\n calls,\n chainId: targetChain,\n username,\n accountAddress: options.accountAddress,\n tokenRequests: serializedTokenRequests,\n };\n dialogResult.sendInit(currentInitPayload);\n\n // Wait for prepare to complete, then send quote data\n const prepareResult = await preparePromise;\n if (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n await this.waitForDialogClose(dialog, cleanup);\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResponse = prepareResult.data;\n\n // Upgrade the init payload with full quote data\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 tier: prepareResult.tier,\n };\n\n // Re-send as PASSKEY_INIT so all dialog versions handle it\n // (PASSKEY_QUOTE_READY only exists in newer dialogs)\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentInitPayload, fullViewport: true },\n dialogOrigin,\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 },\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 this.waitForSigningWithRefresh(\n dialog,\n iframe,\n cleanup,\n dialogOrigin,\n // Refresh callback - called when dialog requests a quote refresh\n async () => {\n console.log(\"[SDK] Dialog requested quote refresh, re-preparing intent\");\n try {\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(requestBody),\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 // Update prepareResponse with refreshed data for execute step\n prepareResponse = refreshedData;\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 };\n } catch (error) {\n console.error(\"[SDK] Quote refresh error:\", error);\n return null;\n }\n }\n );\n\n window.removeEventListener(\"message\", handleReReady);\n\n if (!signingResult.success) {\n // cleanup already called if user rejected via X button\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 } else {\n // Legacy flow - execute with signature from dialog\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\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 // Signature from dialog\n signature: signingResult.signature,\n passkey: signingResult.passkey, // Include passkey info for signature encoding\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 // Wait for dialog to close\n await this.waitForDialogClose(dialog, cleanup);\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 } catch (error) {\n // Send failure status to dialog\n this.sendTransactionStatus(iframe, \"failed\");\n // Wait for dialog to close\n await this.waitForDialogClose(dialog, cleanup);\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\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 if (event.data?.type === \"PASSKEY_CLOSE\") {\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: this.config.clientId\n ? { \"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 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.waitForDialogClose(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 });\n if (hash) {\n finalTxHash = hash;\n finalStatus = \"completed\";\n } else {\n finalStatus = \"failed\";\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 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 if (!options.username && !options.accountAddress) {\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n if (!options.intents?.length) {\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n // Serialize token request amounts to strings for API\n const serializedIntents = options.intents.map((intent) => ({\n targetChain: intent.targetChain,\n calls: 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 ...(this.config.clientId && { clientId: this.config.clientId }),\n };\n\n // 1. Show dialog immediately + prepare batch in parallel\n // Two-phase approach: send raw intent calls early for immediate decode,\n // then send quote data when batch-prepare completes.\n const dialogUrl = this.getDialogUrl();\n const themeParams = this.getThemeParams();\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\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 const preparePromise = this.prepareBatchIntent(requestBody).then((r) => {\n earlyBatchResult = r;\n return r;\n });\n\n // Wait for iframe to be ready\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\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.waitForDialogClose(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 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 currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: prepareResponse.intents,\n batchFailedIntents: prepareResponse.failedIntents,\n challenge: prepareResponse.challenge,\n username: options.username,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\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 };\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\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 username: options.username,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\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 },\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 },\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 console.log(\"[SDK] Batch dialog requested quote refresh, re-preparing all intents\");\n try {\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(requestBody),\n });\n\n if (refreshResponse.ok) {\n const refreshed: PrepareBatchIntentResponse = await refreshResponse.json();\n prepareResponse = refreshed;\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_COMPLETE\",\n batchIntents: refreshed.intents,\n challenge: refreshed.challenge,\n expiresAt: refreshed.expiresAt,\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 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 // Wait for user to close dialog\n await this.waitForDialogClose(dialog, cleanup);\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 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 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 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 * Wait for the signing result without closing the modal\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 (message?.type === \"PASSKEY_CLOSE\") {\n // User clicked X button to close/reject\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 * Wait for signing result (simplified - no requestId matching)\n */\n private waitForSigningResponse(\n dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<SigningResult & { signedHash?: string }> {\n const dialogOrigin = this.getDialogOrigin();\n console.log(\"[SDK] waitForSigningResponse, expecting origin:\", dialogOrigin);\n\n return new Promise((resolve) => {\n const handleMessage = (event: MessageEvent) => {\n console.log(\"[SDK] Received message:\", event.origin, event.data?.type);\n if (event.origin !== dialogOrigin) {\n console.log(\"[SDK] Origin mismatch, ignoring. Expected:\", dialogOrigin, \"Got:\", event.origin);\n return;\n }\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 resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (message?.type === \"PASSKEY_CLOSE\") {\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 signing result with auto-refresh support\n * This method handles both signing results and quote refresh requests from the dialog\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 } | null>\n ): Promise<SigningResult & { signedHash?: string }> {\n console.log(\"[SDK] waitForSigningWithRefresh, expecting origin:\", dialogOrigin);\n\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 console.log(\"[SDK] Received quote refresh request from dialog\");\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 resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (message?.type === \"PASSKEY_CLOSE\") {\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 closed\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 * Inject a preconnect link tag to pre-warm DNS + TLS for a given URL.\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 * Wait for the dialog iframe to signal ready without sending init data.\n * Returns a sendInit function the caller uses once prepare data is available.\n */\n private waitForDialogReadyDeferred(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n ): Promise<\n | { ready: true; 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 teardown();\n resolve({\n ready: true,\n sendInit: (initMessage: Record<string, unknown>) => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initMessage, fullViewport: true },\n dialogOrigin,\n );\n },\n });\n } else if (event.data?.type === \"PASSKEY_CLOSE\") {\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 * Prepare an intent by calling the orchestrator for a quote.\n * Returns the prepare response and the origin tier from the response header.\n */\n private async prepareIntent(\n requestBody: Record<string, unknown>,\n ): Promise<\n | { success: true; data: PrepareIntentResponse; tier: string | null }\n | { success: false; error: { code: string; message: string } }\n > {\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\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 },\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 * Prepare a batch intent by calling the orchestrator for quotes on all intents.\n */\n private async prepareBatchIntent(\n requestBody: Record<string, unknown>,\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\" },\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 * Send a prepare error message to the dialog iframe.\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 try {\n const response = await fetch(\n `${this.config.providerUrl}/api/intent/status/${intentId}`,\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 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 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 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 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: this.config.clientId\n ? { \"x-client-id\": this.config.clientId }\n : {},\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || \"Failed to get intent history\");\n }\n\n return response.json();\n }\n\n /**\n * Send a swap intent through the Rhinestone orchestrator\n *\n * This is a high-level abstraction for token swaps (including cross-chain):\n * 1. Resolves token symbols to addresses\n * 2. Builds the swap intent with tokenRequests (output-first model)\n * 3. The orchestrator's solver network finds the best route\n * 4. Executes via the standard intent flow\n *\n * NOTE: The `amount` parameter specifies the OUTPUT amount (what the user wants to receive),\n * not the input amount. The orchestrator will calculate the required input from sourceAssets.\n *\n * @example\n * ```typescript\n * // Buy 100 USDC using ETH on Base\n * const result = await client.sendSwap({\n * username: 'alice',\n * targetChain: 8453,\n * fromToken: 'ETH',\n * toToken: 'USDC',\n * amount: '100', // Receive 100 USDC\n * });\n *\n * // Cross-chain: Buy 50 USDC on Base, paying with ETH from any chain\n * const result = await client.sendSwap({\n * username: 'alice',\n * targetChain: 8453, // Base\n * fromToken: 'ETH',\n * toToken: 'USDC',\n * amount: '50', // Receive 50 USDC\n * });\n * ```\n */\n async sendSwap(options: SendSwapOptions): Promise<SendSwapResult> {\n try {\n getChainById(options.targetChain);\n } catch {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_CHAIN\",\n message: `Unsupported chain: ${options.targetChain}`,\n },\n };\n }\n\n const resolveToken = (token: string, label: \"fromToken\" | \"toToken\") => {\n try {\n const address = resolveTokenAddress(token, options.targetChain);\n if (!isTokenAddressSupported(address, options.targetChain)) {\n return {\n error: `Unsupported ${label}: ${token} on chain ${options.targetChain}`,\n };\n }\n return { address };\n } catch (error) {\n return {\n error: error instanceof Error\n ? error.message\n : `Unsupported ${label}: ${token} on chain ${options.targetChain}`,\n };\n }\n };\n\n // Resolve fromToken (optional - omit to let orchestrator pick)\n let fromTokenAddress: Address | undefined;\n if (options.fromToken) {\n const fromTokenResult = resolveToken(options.fromToken, \"fromToken\");\n if (!fromTokenResult.address) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_TOKEN\",\n message: fromTokenResult.error || `Unknown fromToken: ${options.fromToken}`,\n },\n };\n }\n fromTokenAddress = fromTokenResult.address;\n }\n\n const toTokenResult = resolveToken(options.toToken, \"toToken\");\n if (!toTokenResult.address) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_TOKEN\",\n message: toTokenResult.error || `Unknown toToken: ${options.toToken}`,\n },\n };\n }\n\n const toTokenAddress = toTokenResult.address;\n\n // Debug: log token resolution\n console.log(\"[SDK sendSwap] Token resolution:\", {\n fromToken: options.fromToken ?? \"Any\",\n fromTokenAddress: fromTokenAddress ?? \"orchestrator picks\",\n toToken: options.toToken,\n toTokenAddress,\n targetChain: options.targetChain,\n });\n\n const formatTokenLabel = (token: string, fallback: string): string => {\n if (!token.startsWith(\"0x\")) {\n return token;\n }\n try {\n return getTokenSymbol(token as Address, options.targetChain);\n } catch {\n return fallback;\n }\n };\n\n const toSymbol = formatTokenLabel(\n options.toToken,\n `${options.toToken.slice(0, 6)}...${options.toToken.slice(-4)}`\n );\n\n // Check if swapping from/to native ETH\n const isFromNativeEth = fromTokenAddress\n ? fromTokenAddress === \"0x0000000000000000000000000000000000000000\"\n : false;\n const isToNativeEth =\n toTokenAddress === \"0x0000000000000000000000000000000000000000\";\n\n // Get decimals for the tokens to convert human-readable amounts to base units\n // Use known decimals for common tokens as fallback\n const KNOWN_DECIMALS: Record<string, number> = {\n ETH: 18,\n WETH: 18,\n USDC: 6,\n USDT: 6,\n USDT0: 6,\n };\n const getDecimals = (symbol: string, chainId: number): number => {\n try {\n // Case-insensitive lookup from registry (symbols like \"MockUSD\" are case-sensitive in upstream SDK)\n const match = getSupportedTokens(chainId).find(\n (t) => t.symbol.toUpperCase() === symbol.toUpperCase()\n );\n if (match) {\n console.log(`[SDK] getTokenDecimals(${match.symbol}, ${chainId}) = ${match.decimals}`);\n return match.decimals;\n }\n const decimals = getTokenDecimals(symbol as never, chainId);\n console.log(`[SDK] getTokenDecimals(${symbol}, ${chainId}) = ${decimals}`);\n return decimals;\n } catch (e) {\n const upperSymbol = symbol.toUpperCase();\n console.warn(`[SDK] getTokenDecimals failed for ${symbol}, using fallback`, e);\n return KNOWN_DECIMALS[upperSymbol] ?? 18;\n }\n };\n const toDecimals = getDecimals(options.toToken, options.targetChain);\n\n // Check if this is a bridge (same token) or swap (different tokens)\n const isBridge = options.fromToken\n ? options.fromToken.toUpperCase() === options.toToken.toUpperCase()\n : false;\n\n // Build tokenRequests - tells orchestrator what output token/amount we want\n // The amount parameter now represents OUTPUT (what user wants to receive)\n // Always specify tokenRequests so the orchestrator knows the desired output and we can show \"Buying\" in UI\n const tokenRequests: IntentTokenRequest[] = [{\n token: toTokenAddress,\n amount: parseUnits(options.amount, toDecimals),\n }];\n\n console.log(\"[SDK sendSwap] Building intent:\", {\n isBridge,\n isFromNativeEth,\n isToNativeEth,\n toDecimals,\n tokenRequests,\n });\n\n // Build the intent\n // The orchestrator will handle finding the best swap/bridge route\n // For swaps/bridges, we use tokenRequests to specify output\n // We need at least one call (SDK requirement), so we use a minimal placeholder\n // The label/sublabel tell the dialog what to display (instead of \"Send\" with unknown address)\n const result = await this.sendIntent({\n username: options.username,\n targetChain: options.targetChain,\n calls: [\n {\n // Minimal call - just signals to orchestrator we want the tokenRequests delivered\n to: toTokenAddress,\n value: \"0\",\n // SDK provides labels so dialog shows \"Buy ETH\" not \"Send ETH / To: 0x000...\"\n label: `Buy ${toSymbol}`,\n sublabel: `${options.amount} ${toSymbol}`,\n },\n ],\n // Request specific output tokens - this is what actually matters for swaps\n tokenRequests,\n // Constrain orchestrator to use only the fromToken as input\n // This ensures the swap uses the correct source token\n // Use canonical symbol casing from registry (e.g. \"MockUSD\" not \"MOCKUSD\")\n sourceAssets: options.sourceAssets || (options.fromToken ? [options.fromToken] : undefined),\n // Pass source chain ID so orchestrator knows which chain to look for tokens on\n sourceChainId: options.sourceChainId,\n closeOn: options.closeOn || \"preconfirmed\",\n waitForHash: options.waitForHash,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n\n // Return with swap-specific data\n return {\n ...result,\n quote: result.success\n ? {\n fromToken: fromTokenAddress ?? options.fromToken,\n toToken: toTokenAddress,\n amountIn: options.amount,\n amountOut: \"\", // Filled by orchestrator quote\n rate: \"\",\n }\n : undefined,\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 dialogUrl = this.getDialogUrl();\n const themeParams = this.getThemeParams(options?.theme);\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n if (!dialogResult.ready) {\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 };\n dialogResult.sendInit(initPayload);\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 },\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 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 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 // 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 themeParams = this.getThemeParams(options?.theme);\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n if (!dialogResult.ready) {\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 };\n dialogResult.sendInit(initPayload);\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 },\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 return {\n success: true,\n signature: signingResult.signature,\n signedHash,\n passkey: signingResult.passkey,\n };\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 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 return iframe;\n }\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 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 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 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 send init data.\n * Also handles early close (X button, escape, backdrop) during the ready phase.\n * Returns true if dialog is ready, false if it was closed before becoming ready.\n */\n private waitForDialogReady(\n dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void,\n initMessage: Record<string, unknown>,\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 teardown();\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n ...initMessage,\n fullViewport: true,\n }, dialogOrigin);\n resolve(true);\n } else if (event.data?.type === \"PASSKEY_CLOSE\") {\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 a modal dialog with a full-viewport iframe inside.\n * All visual chrome (backdrop, positioning, animations) is rendered\n * by the passkey app inside the iframe — the SDK just provides\n * a transparent full-screen container.\n */\n private createModalDialog(url: string): {\n dialog: HTMLDialogElement;\n iframe: HTMLIFrameElement;\n cleanup: () => void;\n } {\n const dialogUrl = this.getDialogUrl();\n const hostUrl = new URL(dialogUrl);\n\n // Extract theme from URL params for loading overlay styling\n const urlParams = new URL(url, window.location.href).searchParams;\n const themeMode = urlParams.get('theme') || 'light';\n const accentColor = urlParams.get('accent') || '#0090ff';\n const isDark = themeMode === 'dark' ||\n (themeMode !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);\n\n const bgPrimary = isDark ? '#191919' : '#fcfcfc';\n const bgSecondary = isDark ? '#222222' : '#f9f9f9';\n const borderColor = isDark ? '#2a2a2a' : '#e0e0e0';\n const textPrimary = isDark ? '#eeeeee' : '#202020';\n const textSecondary = isDark ? '#7b7b7b' : '#838383';\n const bgSurface = isDark ? '#222222' : '#f0f0f0';\n const ah = accentColor.replace('#', '');\n const accentRgb = `${parseInt(ah.slice(0,2),16)},${parseInt(ah.slice(2,4),16)},${parseInt(ah.slice(4,6),16)}`;\n const accentTint = isDark ? `rgba(${accentRgb},0.15)` : `rgba(${accentRgb},0.1)`;\n const hostname = window.location.hostname;\n\n const dialog = document.createElement(\"dialog\");\n dialog.dataset.passkey = \"\";\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] 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(8px);\n -webkit-backdrop-filter: blur(8px);\n }\n dialog[data-passkey] [data-passkey-overlay] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding-top: 50px;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n z-index: 1;\n animation: _1auth-backdrop-in 0.2s ease-out;\n }\n @media (max-width: 768px) {\n dialog[data-passkey] [data-passkey-overlay] {\n align-items: flex-end;\n padding-top: 0;\n }\n }\n dialog[data-passkey] [data-passkey-card] {\n width: 340px;\n overflow: hidden;\n border-radius: 14px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08);\n animation: _1auth-card-in 0.2s cubic-bezier(0.32, 0.72, 0, 1);\n max-height: calc(100dvh - 100px);\n }\n @media (max-width: 768px) {\n dialog[data-passkey] [data-passkey-card] {\n width: 100%;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n animation: _1auth-card-slide 0.3s cubic-bezier(0.32, 0.72, 0, 1);\n }\n }\n @keyframes _1auth-backdrop-in {\n from { opacity: 0; } to { opacity: 1; }\n }\n @keyframes _1auth-card-in {\n from { opacity: 0; transform: scale(0.96) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n }\n @keyframes _1auth-card-slide {\n from { transform: translate3d(0, 100%, 0); }\n to { transform: translate3d(0, 0, 0); }\n }\n @keyframes _1auth-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `;\n dialog.appendChild(style);\n\n // Create loading overlay — replicates the passkey dialog's exact visual\n // structure (TitleBar + IndeterminateLoader) for a seamless transition\n const overlay = document.createElement(\"div\");\n overlay.dataset.passkeyOverlay = \"\";\n const _sp = '<path d=\"M10 0.5C8.02219 0.5 6.08879 1.08649 4.4443 2.1853C2.79981 3.28412 1.51809 4.8459 0.761209 6.67316C0.00433288 8.50043 -0.1937 10.5111 0.192152 12.4509C0.578004 14.3907 1.53041 16.1725 2.92894 17.5711C4.32746 18.9696 6.10929 19.922 8.0491 20.3078C9.98891 20.6937 11.9996 20.4957 13.8268 19.7388C15.6541 18.9819 17.2159 17.7002 18.3147 16.0557C19.4135 14.4112 20 12.4778 20 10.5C20 7.84783 18.9464 5.3043 17.0711 3.42893C15.1957 1.55357 12.6522 0.5 10 0.5ZM10 17.7727C8.56159 17.7727 7.15549 17.3462 5.95949 16.547C4.7635 15.7479 3.83134 14.6121 3.28088 13.2831C2.73042 11.9542 2.5864 10.4919 2.86702 9.08116C3.14764 7.67039 3.8403 6.37451 4.85741 5.3574C5.87452 4.3403 7.17039 3.64764 8.58116 3.36702C9.99193 3.0864 11.4542 3.23042 12.7832 3.78088C14.1121 4.33133 15.2479 5.26349 16.0471 6.45949C16.8462 7.65548 17.2727 9.06159 17.2727 10.5C17.2727 12.4288 16.5065 14.2787 15.1426 15.6426C13.7787 17.0065 11.9288 17.7727 10 17.7727Z\" fill=\"currentColor\" opacity=\"0.3\"/><path d=\"M10 3.22767C11.7423 3.22846 13.4276 3.8412 14.7556 4.95667C16.0837 6.07214 16.9681 7.61784 17.2512 9.31825C17.3012 9.64364 17.4662 9.94096 17.7169 10.1573C17.9677 10.3737 18.2878 10.4951 18.6205 10.5C18.8211 10.5001 19.0193 10.457 19.2012 10.3735C19.3832 10.2901 19.5445 10.1684 19.674 10.017C19.8036 9.86549 19.8981 9.68789 19.9511 9.49656C20.004 9.30523 20.0141 9.10478 19.9807 8.90918C19.5986 6.56305 18.3843 4.42821 16.5554 2.88726C14.7265 1.34631 12.4025 0.5 10 0.5C7.59751 0.5 5.27354 1.34631 3.44461 2.88726C1.61569 4.42821 0.401366 6.56305 0.0192815 8.90918C-0.0141442 9.10478 -0.00402016 9.30523 0.0489472 9.49656C0.101914 9.68789 0.196449 9.86549 0.325956 10.017C0.455463 10.1684 0.616823 10.2901 0.798778 10.3735C0.980732 10.457 1.1789 10.5001 1.37945 10.5C1.71216 10.4951 2.03235 10.3737 2.28307 10.1573C2.5338 9.94096 2.69883 9.64364 2.74882 9.31825C3.03193 7.61784 3.91633 6.07214 5.24436 4.95667C6.57239 3.8412 8.25775 3.22846 10 3.22767Z\" fill=\"currentColor\"/>';\n overlay.innerHTML =\n `<div data-passkey-card style=\"background:${bgPrimary};border:1px solid ${borderColor};font-family:ui-sans-serif,system-ui,sans-serif,'Apple Color Emoji','Segoe UI Emoji'\">` +\n // TitleBar — matches apps/passkey TitleBar.tsx layout\n `<div style=\"height:36px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;background:${bgSecondary};border-bottom:1px solid ${borderColor}\">` +\n `<div style=\"display:flex;align-items:center;gap:8px\">` +\n `<div style=\"display:flex;width:20px;height:20px;align-items:center;justify-content:center;border-radius:4px;background:${bgSurface}\">` +\n `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${textPrimary}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 12V7H5a2 2 0 0 1 0-4h14v4\"/><path d=\"M3 5v14a2 2 0 0 0 2 2h16v-5\"/><path d=\"M18 12a2 2 0 0 0 0 4h4v-4Z\"/></svg>` +\n `</div>` +\n `<span style=\"font-size:13px;font-weight:500;color:${textPrimary};max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\">${hostname}</span>` +\n `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${textSecondary}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\"/><path d=\"m9 12 2 2 4-4\"/></svg>` +\n `</div>` +\n `<div style=\"display:flex;align-items:center;gap:4px\">` +\n `<div style=\"display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary}\">` +\n `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></svg>` +\n `</div>` +\n `<button data-passkey-close style=\"display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary};border:none;background:none;cursor:pointer;padding:0\">` +\n `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>` +\n `</button>` +\n `</div>` +\n `</div>` +\n // Content — matches IndeterminateLoader (horizontal) with p-3\n `<div style=\"padding:12px\">` +\n `<div style=\"display:flex;align-items:center;gap:8px\">` +\n `<div style=\"display:flex;width:32px;height:32px;min-width:32px;align-items:center;justify-content:center;border-radius:50%;background:${accentTint};padding:6px\">` +\n `<svg style=\"width:100%;height:100%;animation:_1auth-spin 0.8s linear infinite;color:${accentColor}\" fill=\"none\" viewBox=\"0 0 20 21\" xmlns=\"http://www.w3.org/2000/svg\">${_sp}</svg>` +\n `</div>` +\n `<div style=\"font-weight:500;font-size:18px;color:${textPrimary}\">Loading...</div>` +\n `</div>` +\n `<div style=\"margin-top:8px\">` +\n `<div style=\"font-size:15px;line-height:20px;color:${textPrimary}\">This will only take a few moments.</div>` +\n `<div style=\"font-size:15px;line-height:20px;color:${textSecondary}\">Please do not close the window.</div>` +\n `</div>` +\n `</div>` +\n `</div>`;\n overlay.addEventListener(\"click\", (e) => {\n if (e.target === overlay) cleanup();\n });\n const overlayCloseBtn = overlay.querySelector(\"[data-passkey-close]\");\n if (overlayCloseBtn) overlayCloseBtn.addEventListener(\"click\", () => cleanup());\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 iframe.setAttribute(\n \"sandbox\",\n \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\",\n );\n iframe.setAttribute(\"src\", url);\n iframe.setAttribute(\"title\", \"Passkey\");\n iframe.style.opacity = \"0\";\n\n dialog.appendChild(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 // Hide loading overlay and reveal iframe content.\n // Sequence across two frames: first make the iframe visible (it renders\n // behind the overlay due to z-index), then remove the overlay on the next\n // frame once the iframe's backdrop-filter is composited.\n let overlayHidden = false;\n const hideOverlay = () => {\n if (overlayHidden) return;\n overlayHidden = true;\n iframe.style.opacity = \"1\";\n requestAnimationFrame(() => {\n overlay.style.display = \"none\";\n });\n };\n\n // Handle messages from iframe\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== hostUrl.origin) return;\n if (event.data?.type === \"PASSKEY_RENDERED\") {\n hideOverlay();\n }\n if (event.data?.type === \"PASSKEY_DISCONNECT\") {\n localStorage.removeItem(\"1auth-user\");\n }\n };\n window.addEventListener(\"message\", handleMessage);\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 // Show modal\n dialog.showModal();\n\n let cleanedUp = false;\n const cleanup = () => {\n if (cleanedUp) return;\n cleanedUp = true;\n inertObserver.disconnect();\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 return { dialog, iframe, cleanup };\n }\n\n private waitForModalAuthResponse(\n _dialog: HTMLDialogElement,\n iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<AuthResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n // Track whether the dialog has signaled ready\n // This prevents stale PASSKEY_CLOSE messages from previous dialogs\n let dialogReady = false;\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n\n // Wait for dialog to signal ready before processing other messages\n if (data?.type === \"PASSKEY_READY\") {\n dialogReady = true;\n // Send init message to the auth dialog\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n mode: \"iframe\",\n fullViewport: true,\n }, dialogOrigin);\n return;\n }\n\n // Ignore messages until dialog is ready (prevents stale CLOSE from previous dialogs)\n if (!dialogReady && data?.type === \"PASSKEY_CLOSE\") {\n return;\n }\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 });\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 } else if (data?.type === \"PASSKEY_CLOSE\") {\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 }\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 });\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 private waitForAuthenticateResponse(\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<AuthenticateResult> {\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_AUTHENTICATE_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?.accountAddress as `0x${string}`,\n },\n challenge: data.data?.signature ? {\n signature: data.data.signature,\n signedHash: data.data.signedHash,\n } : undefined,\n });\n } else {\n resolve({\n success: false,\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 error: {\n code: \"USER_CANCELLED\",\n message: \"Authentication was cancelled\",\n },\n });\n }\n };\n\n window.addEventListener(\"message\", handleMessage);\n });\n }\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 private waitForConsentResponse(\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<RequestConsentResult> {\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_CONSENT_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (data.success) {\n resolve({\n success: true,\n data: data.data,\n grantedAt: data.data?.grantedAt,\n });\n } else {\n resolve({\n success: false,\n error: data.error ?? {\n code: \"USER_REJECTED\" as const,\n message: \"User denied the consent request\",\n },\n });\n }\n } else if (data?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\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 window.addEventListener(\"message\", handleMessage);\n });\n }\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 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 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 {\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 username: string;\n};\n\nexport function createPasskeyAccount(\n client: OneAuthClient,\n params: { address: Address; username: string }\n): PasskeyAccount {\n const { address, username } = params;\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,\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 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 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,\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,\n };\n}\n","import {\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 } 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.box',\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 provider = new OneAuthClient({\n providerUrl: config.providerUrl,\n clientId: config.clientId,\n dialogUrl: config.dialogUrl,\n });\n\n // Helper function to sign a message\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 username: config.username,\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 // Helper function to sign a transaction\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 username: config.username,\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 // Helper function to sign typed data\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 username: config.username,\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 const buildIntentPayload = async (\n calls: TransactionCall[],\n targetChainOverride?: number\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 }));\n\n if (config.signIntent) {\n const signedIntent = await config.signIntent({\n username: config.username,\n accountAddress: config.accountAddress,\n targetChain,\n calls: intentCalls,\n });\n return { signedIntent };\n }\n\n return {\n username: config.username,\n targetChain,\n calls: intentCalls,\n };\n };\n\n // Create account with type assertion to avoid complex generic issues\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 const closeOn = (config.waitForHash ?? true)\n ? \"completed\"\n : \"preconfirmed\";\n\n const intentPayload = await buildIntentPayload(calls, targetChain);\n const result = await provider.sendIntent({\n ...intentPayload,\n closeOn,\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 } = params;\n const closeOn = (config.waitForHash ?? true)\n ? \"completed\"\n : \"preconfirmed\";\n const intentPayload = await buildIntentPayload(calls, targetChain);\n const result = await provider.sendIntent({\n ...intentPayload,\n tokenRequests,\n closeOn,\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/**\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: (username: string) => 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 */\nfunction getStorageKey(username?: string): string {\n return username ? `1auth_batch_queue_${username}` : \"1auth_batch_queue_anonymous\";\n}\n\nexport interface BatchQueueProviderProps {\n /** The OneAuthClient instance */\n client: OneAuthClient;\n /** Optional username for localStorage persistence key */\n username?: 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 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 // 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(username);\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 }, [username]);\n\n // Save queue to localStorage when it changes\n React.useEffect(() => {\n const storageKey = getStorageKey(username);\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, username]);\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 (username: string): 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 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,\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]);\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","import * as React from \"react\";\nimport { useBatchQueue, getChainName } from \"./BatchQueueContext\";\n\n// Inject animation styles into document head\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\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// Inline styles\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// Chevron icon\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 - should provide username */\n onSignAll: () => void;\n}\n\n/**\n * Floating widget showing the batch queue\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 &times;\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","import { keccak256, toBytes } from \"viem\";\n\n/**\n * The EIP-191 prefix used for personal message signing.\n * This is the standard Ethereum message prefix for `personal_sign`.\n */\nexport const ETHEREUM_MESSAGE_PREFIX = \"\\x19Ethereum Signed Message:\\n\";\n\n/**\n * Hash a message with the EIP-191 Ethereum prefix.\n *\n * This is the same hashing function used by the passkey sign dialog.\n * Use this to verify that the `signedHash` returned from `signMessage()`\n * matches your original message.\n *\n * Format: keccak256(\"\\x19Ethereum Signed Message:\\n\" + len + message)\n *\n * @example\n * ```typescript\n * const message = \"Sign in to MyApp\\nTimestamp: 1234567890\";\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * // Verify the hash matches\n * const expectedHash = hashMessage(message);\n * if (result.signedHash === expectedHash) {\n * console.log('Hash matches - signature is for this message');\n * }\n * ```\n */\nexport function hashMessage(message: string): `0x${string}` {\n const messageBytes = toBytes(message);\n const prefixed = ETHEREUM_MESSAGE_PREFIX + messageBytes.length.toString() + message;\n return keccak256(toBytes(prefixed));\n}\n\n/**\n * Verify that a signedHash matches the expected message.\n *\n * This is a convenience wrapper around `hashMessage()` that returns\n * a boolean. For full cryptographic verification of the P256 signature,\n * use on-chain verification via the WebAuthn.sol contract.\n *\n * @example\n * ```typescript\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * if (result.success && verifyMessageHash(message, result.signedHash)) {\n * // The signature is for this exact message\n * // For full verification, verify the P256 signature on-chain or server-side\n * }\n * ```\n */\nexport function verifyMessageHash(\n message: string,\n signedHash: string | undefined\n): boolean {\n if (!signedHash) return false;\n const expectedHash = hashMessage(message);\n return expectedHash.toLowerCase() === signedHash.toLowerCase();\n}\n"],"mappings":"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","names":["dialogOrigin","closeOn","successStatuses","hashTypedData","toAccount","hashTypedData","toAccount","getChainName","username","React","jsx","getChainName","hashMessage"]}
1
+ {"version":3,"sources":["../src/client.ts","../src/account.ts","../src/walletClient/index.ts","../src/batch/BatchQueueContext.tsx","../src/batch/BatchQueueWidget.tsx","../src/verify.ts"],"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 * - Token swaps (convenience wrapper over sendIntent)\n * - Data consent management\n */\nimport { parseUnits, hashTypedData, type TypedDataDefinition, type Address } from \"viem\";\nimport type {\n PasskeyProviderConfig,\n SigningRequestOptions,\n SigningResult,\n CreateSigningRequestResponse,\n SigningRequestStatus,\n SigningErrorCode,\n EmbedOptions,\n UserPasskeysResponse,\n PasskeyCredential,\n AuthResult,\n ConnectResult,\n AuthenticateOptions,\n AuthenticateResult,\n SendIntentOptions,\n SendIntentResult,\n PrepareIntentResponse,\n ExecuteIntentResponse,\n WebAuthnSignature,\n SendSwapOptions,\n SendSwapResult,\n ThemeConfig,\n SignMessageOptions,\n SignMessageResult,\n SignTypedDataOptions,\n SignTypedDataResult,\n IntentHistoryOptions,\n IntentHistoryResult,\n IntentTokenRequest,\n SendBatchIntentOptions,\n SendBatchIntentResult,\n PrepareBatchIntentResponse,\n BatchIntentItemResult,\n CheckConsentOptions,\n CheckConsentResult,\n RequestConsentOptions,\n RequestConsentResult,\n} from \"./types\";\nimport {\n getChainById,\n getSupportedTokens,\n getTokenDecimals,\n getTokenSymbol,\n isTokenAddressSupported,\n resolveTokenAddress,\n} from \"./registry\";\n\nconst POPUP_WIDTH = 450;\nconst POPUP_HEIGHT = 600;\nconst DEFAULT_EMBED_WIDTH = \"400px\";\nconst DEFAULT_EMBED_HEIGHT = \"500px\";\nconst DEFAULT_PROVIDER_URL = \"https://passkey.1auth.box\";\n\ntype NormalizedPasskeyProviderConfig = PasskeyProviderConfig & {\n providerUrl: string;\n dialogUrl: string;\n};\n\nexport class OneAuthClient {\n private config: NormalizedPasskeyProviderConfig;\n private theme: ThemeConfig;\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\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 }\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 if (theme.accent) {\n params.set('accent', theme.accent);\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.box\"`).\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 * 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 ): 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: this.config.clientId\n ? { \"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 * @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?: {\n username?: string;\n theme?: ThemeConfig;\n oauthEnabled?: boolean;\n }): Promise<AuthResult> {\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 if (options?.username) {\n params.set('username', options.username);\n }\n if (options?.oauthEnabled === false) {\n params.set('oauth', '0');\n }\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/auth?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n return this.waitForModalAuthResponse(dialog, iframe, cleanup);\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 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\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\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n });\n if (!ready) {\n return {\n success: false,\n action: \"cancel\",\n error: { code: \"USER_CANCELLED\", message: \"Connection was cancelled\" },\n };\n }\n\n return this.waitForConnectResponse(dialog, iframe, cleanup);\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 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;\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 * Check if a user has already granted consent for the requested fields.\n * This is a read-only check — no dialog is shown.\n *\n * @example\n * ```typescript\n * const result = await client.checkConsent({\n * username: \"alice\",\n * fields: [\"email\"],\n * });\n * if (result.hasConsent) {\n * console.log(result.data?.email);\n * }\n * ```\n */\n async checkConsent(options: CheckConsentOptions): Promise<CheckConsentResult> {\n const clientId = options.clientId ?? this.config.clientId;\n if (!clientId) {\n return {\n hasConsent: false,\n };\n }\n\n const username = options.username ?? options.accountAddress;\n if (!username) {\n return {\n hasConsent: false,\n };\n }\n\n try {\n const res = await fetch(`${this.config.providerUrl || \"https://passkey.1auth.box\"}/api/consent`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n ...(clientId ? { \"x-client-id\": clientId } : {}),\n },\n body: JSON.stringify({\n username,\n requestedFields: options.fields,\n clientId,\n }),\n });\n\n if (!res.ok) {\n return { hasConsent: false };\n }\n\n const data = await res.json();\n return {\n hasConsent: data.hasConsent ?? false,\n data: data.data,\n grantedAt: data.grantedAt,\n };\n } catch {\n return { hasConsent: false };\n }\n }\n\n /**\n * Request consent from the user to share their data.\n *\n * First checks if consent was already granted (returns cached data immediately).\n * If not, opens the consent dialog where the user can review and approve sharing.\n *\n * @example\n * ```typescript\n * const result = await client.requestConsent({\n * username: \"alice\",\n * fields: [\"email\", \"deviceNames\"],\n * });\n * if (result.success) {\n * console.log(result.data?.email);\n * console.log(result.cached); // true if no dialog was shown\n * }\n * ```\n */\n async requestConsent(options: RequestConsentOptions): Promise<RequestConsentResult> {\n const clientId = options.clientId ?? this.config.clientId;\n if (!clientId) {\n return {\n success: false,\n error: { code: \"INVALID_REQUEST\", message: \"clientId is required (set in config or options)\" },\n };\n }\n\n const username = options.username ?? options.accountAddress;\n if (!username) {\n return {\n success: false,\n error: { code: \"INVALID_REQUEST\", message: \"username or accountAddress is required\" },\n };\n }\n\n if (!options.fields || options.fields.length === 0) {\n return {\n success: false,\n error: { code: \"INVALID_REQUEST\", message: \"At least one field is required\" },\n };\n }\n\n // Check if consent already granted\n const existing = await this.checkConsent({ ...options, clientId });\n if (existing.hasConsent && existing.data) {\n return {\n success: true,\n data: existing.data,\n grantedAt: existing.grantedAt,\n cached: true,\n };\n }\n\n // Open consent dialog\n const dialogUrl = this.getDialogUrl();\n const params = new URLSearchParams({\n mode: \"iframe\",\n username,\n clientId,\n fields: options.fields.join(\",\"),\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/consent?${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) {\n return {\n success: false,\n error: { code: \"USER_CANCELLED\", message: \"User closed the dialog\" },\n };\n }\n\n return this.waitForConsentResponse(dialog, iframe, cleanup);\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)\n * 2. The challenge is hashed with a domain separator\n * 3. User signs the hash with their passkey\n * 4. Returns user info + signature for server-side verification\n *\n * The domain separator (\"\\x19Passkey Signed Message:\\n\") ensures the signature\n * cannot be reused for transaction signing, preventing phishing attacks.\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 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\n if (options?.challenge) {\n params.set('challenge', options.challenge);\n }\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/authenticate?${params.toString()}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(url);\n\n return this.waitForAuthenticateResponse(dialog, iframe, cleanup);\n }\n\n /**\n * Show signing in a modal overlay (iframe dialog)\n */\n async signWithModal(options: SigningRequestOptions & { theme?: ThemeConfig }): Promise<SigningResult> {\n const dialogUrl = this.getDialogUrl();\n const themeParams = this.getThemeParams(options?.theme);\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const ready = await this.waitForDialogReady(dialog, iframe, cleanup, {\n mode: \"iframe\",\n challenge: options.challenge,\n username: options.username,\n description: options.description,\n transaction: options.transaction,\n metadata: options.metadata,\n });\n if (!ready) {\n return {\n success: false,\n error: {\n code: \"USER_REJECTED\" as SigningErrorCode,\n message: \"User closed the dialog\",\n },\n };\n }\n\n return this.waitForSigningResponse(dialog, iframe, cleanup);\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, calls } = options;\n\n if (!username && !accountAddress) {\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 if (!targetChain || !calls?.length) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_OPTIONS\",\n message: \"targetChain and calls are required\",\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 // 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 ...(this.config.clientId && { clientId: this.config.clientId }),\n };\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 // - 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 raw `calls` to the dialog (no fees yet) so it can\n // decode and display the transaction actions immediately.\n // - Phase 2: once the quote arrives, upgrade the dialog with full fee\n // data by re-sending PASSKEY_INIT with the complete payload.\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 themeParams = this.getThemeParams();\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const dialogOrigin = this.getDialogOrigin();\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 } };\n let earlyPrepareResult: PrepareResult | null = null;\n const preparePromise = this.prepareIntent(requestBody).then((r) => {\n earlyPrepareResult = r;\n return r;\n });\n\n // Wait for iframe to be ready\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\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 // Mutable init payload — starts as early preview, upgraded to full after quote\n let currentInitPayload: Record<string, unknown>;\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 const prepareResult = earlyPrepareResult as PrepareResult;\n if (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n await this.waitForDialogClose(dialog, cleanup);\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResponse = prepareResult.data;\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 tier: prepareResult.tier,\n };\n dialogResult.sendInit(currentInitPayload);\n } else {\n // Progressive path: send early preview with raw calls so the dialog\n // can decode and display transaction actions immediately\n currentInitPayload = {\n mode: \"iframe\",\n calls,\n chainId: targetChain,\n username,\n accountAddress: options.accountAddress,\n tokenRequests: serializedTokenRequests,\n };\n dialogResult.sendInit(currentInitPayload);\n\n // Wait for prepare to complete, then send quote data\n const prepareResult = await preparePromise;\n if (!prepareResult.success) {\n this.sendPrepareError(iframe, prepareResult.error.message);\n await this.waitForDialogClose(dialog, cleanup);\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: prepareResult.error,\n };\n }\n prepareResponse = prepareResult.data;\n\n // Upgrade the init payload with full quote data\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 tier: prepareResult.tier,\n };\n\n // Re-send as PASSKEY_INIT so all dialog versions handle it\n // (PASSKEY_QUOTE_READY only exists in newer dialogs)\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...currentInitPayload, fullViewport: true },\n dialogOrigin,\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 },\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 this.waitForSigningWithRefresh(\n dialog,\n iframe,\n cleanup,\n dialogOrigin,\n // Refresh callback - called when dialog requests a quote refresh\n async () => {\n try {\n const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(requestBody),\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 // Update prepareResponse with refreshed data for execute step\n prepareResponse = refreshedData;\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 };\n } catch (error) {\n console.error(\"[SDK] Quote refresh error:\", error);\n return null;\n }\n }\n );\n\n window.removeEventListener(\"message\", handleReReady);\n\n if (!signingResult.success) {\n // cleanup already called if user rejected via X button\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 } else {\n // Legacy flow - execute with signature from dialog\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/execute`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\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 // Signature from dialog\n signature: signingResult.signature,\n passkey: signingResult.passkey, // Include passkey info for signature encoding\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 // Wait for dialog to close\n await this.waitForDialogClose(dialog, cleanup);\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 } catch (error) {\n // Send failure status to dialog\n this.sendTransactionStatus(iframe, \"failed\");\n // Wait for dialog to close\n await this.waitForDialogClose(dialog, cleanup);\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\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 if (event.data?.type === \"PASSKEY_CLOSE\") {\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: this.config.clientId\n ? { \"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 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.waitForDialogClose(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 });\n if (hash) {\n finalTxHash = hash;\n finalStatus = \"completed\";\n } else {\n finalStatus = \"failed\";\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 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 if (!options.username && !options.accountAddress) {\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n if (!options.intents?.length) {\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\n\n // Serialize token request amounts to strings for API\n const serializedIntents = options.intents.map((intent) => ({\n targetChain: intent.targetChain,\n calls: 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 ...(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 themeParams = this.getThemeParams();\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\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 const preparePromise = this.prepareBatchIntent(requestBody).then((r) => {\n earlyBatchResult = r;\n return r;\n });\n\n // Wait for iframe to be ready\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n\n // Handle dialog closed before ready\n if (!dialogResult.ready) {\n return {\n success: false,\n results: [],\n successCount: 0,\n failureCount: 0,\n };\n }\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.waitForDialogClose(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 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 currentBatchPayload = {\n mode: \"iframe\",\n batchMode: true,\n batchIntents: prepareResponse.intents,\n batchFailedIntents: prepareResponse.failedIntents,\n challenge: prepareResponse.challenge,\n username: options.username,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\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 };\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\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 username: options.username,\n accountAddress: prepareResponse.accountAddress,\n userId: prepareResponse.userId,\n expiresAt: prepareResponse.expiresAt,\n tier: prepareResult.tier,\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 },\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 },\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 const refreshResponse = await fetch(`${this.config.providerUrl}/api/intent/batch-prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(requestBody),\n });\n\n if (refreshResponse.ok) {\n const refreshed: PrepareBatchIntentResponse = await refreshResponse.json();\n prepareResponse = refreshed;\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_REFRESH_COMPLETE\",\n batchIntents: refreshed.intents,\n challenge: refreshed.challenge,\n expiresAt: refreshed.expiresAt,\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 // Wait for user to close dialog\n await this.waitForDialogClose(dialog, cleanup);\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 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 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 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 (message?.type === \"PASSKEY_CLOSE\") {\n // User clicked X button to close/reject\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 - Unused; kept for signature consistency with other wait helpers.\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 resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (message?.type === \"PASSKEY_CLOSE\") {\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 } | 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 resolve({\n success: false,\n error: message.error || {\n code: \"SIGNING_FAILED\" as SigningErrorCode,\n message: \"Signing failed\",\n },\n });\n }\n } else if (message?.type === \"PASSKEY_CLOSE\") {\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 * 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 * 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 ): Promise<\n | { ready: true; 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 teardown();\n resolve({\n ready: true,\n sendInit: (initMessage: Record<string, unknown>) => {\n iframe.contentWindow?.postMessage(\n { type: \"PASSKEY_INIT\", ...initMessage, fullViewport: true },\n dialogOrigin,\n );\n },\n });\n } else if (event.data?.type === \"PASSKEY_CLOSE\") {\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 } }`.\n */\n private async prepareIntent(\n requestBody: Record<string, unknown>,\n ): Promise<\n | { success: true; data: PrepareIntentResponse; tier: string | null }\n | { success: false; error: { code: string; message: string } }\n > {\n try {\n const response = await fetch(`${this.config.providerUrl}/api/intent/prepare`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\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 },\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 ): 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\" },\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 try {\n const response = await fetch(\n `${this.config.providerUrl}/api/intent/status/${intentId}`,\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 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 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 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 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: this.config.clientId\n ? { \"x-client-id\": this.config.clientId }\n : {},\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const errorData = await response.json().catch(() => ({}));\n throw new Error(errorData.error || \"Failed to get intent history\");\n }\n\n return response.json();\n }\n\n /**\n * Send a swap intent through the Rhinestone orchestrator\n *\n * This is a high-level abstraction for token swaps (including cross-chain):\n * 1. Resolves token symbols to addresses\n * 2. Builds the swap intent with tokenRequests (output-first model)\n * 3. The orchestrator's solver network finds the best route\n * 4. Executes via the standard intent flow\n *\n * NOTE: The `amount` parameter specifies the OUTPUT amount (what the user wants to receive),\n * not the input amount. The orchestrator will calculate the required input from sourceAssets.\n *\n * @example\n * ```typescript\n * // Buy 100 USDC using ETH on Base\n * const result = await client.sendSwap({\n * username: 'alice',\n * targetChain: 8453,\n * fromToken: 'ETH',\n * toToken: 'USDC',\n * amount: '100', // Receive 100 USDC\n * });\n *\n * // Cross-chain: Buy 50 USDC on Base, paying with ETH from any chain\n * const result = await client.sendSwap({\n * username: 'alice',\n * targetChain: 8453, // Base\n * fromToken: 'ETH',\n * toToken: 'USDC',\n * amount: '50', // Receive 50 USDC\n * });\n * ```\n */\n async sendSwap(options: SendSwapOptions): Promise<SendSwapResult> {\n try {\n getChainById(options.targetChain);\n } catch {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_CHAIN\",\n message: `Unsupported chain: ${options.targetChain}`,\n },\n };\n }\n\n const resolveToken = (token: string, label: \"fromToken\" | \"toToken\") => {\n try {\n const address = resolveTokenAddress(token, options.targetChain);\n if (!isTokenAddressSupported(address, options.targetChain)) {\n return {\n error: `Unsupported ${label}: ${token} on chain ${options.targetChain}`,\n };\n }\n return { address };\n } catch (error) {\n return {\n error: error instanceof Error\n ? error.message\n : `Unsupported ${label}: ${token} on chain ${options.targetChain}`,\n };\n }\n };\n\n // Resolve fromToken (optional - omit to let orchestrator pick)\n let fromTokenAddress: Address | undefined;\n if (options.fromToken) {\n const fromTokenResult = resolveToken(options.fromToken, \"fromToken\");\n if (!fromTokenResult.address) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_TOKEN\",\n message: fromTokenResult.error || `Unknown fromToken: ${options.fromToken}`,\n },\n };\n }\n fromTokenAddress = fromTokenResult.address;\n }\n\n const toTokenResult = resolveToken(options.toToken, \"toToken\");\n if (!toTokenResult.address) {\n return {\n success: false,\n intentId: \"\",\n status: \"failed\",\n error: {\n code: \"INVALID_TOKEN\",\n message: toTokenResult.error || `Unknown toToken: ${options.toToken}`,\n },\n };\n }\n\n const toTokenAddress = toTokenResult.address;\n\n const formatTokenLabel = (token: string, fallback: string): string => {\n if (!token.startsWith(\"0x\")) {\n return token;\n }\n try {\n return getTokenSymbol(token as Address, options.targetChain);\n } catch {\n return fallback;\n }\n };\n\n const toSymbol = formatTokenLabel(\n options.toToken,\n `${options.toToken.slice(0, 6)}...${options.toToken.slice(-4)}`\n );\n\n // Check if swapping from/to native ETH\n const isFromNativeEth = fromTokenAddress\n ? fromTokenAddress === \"0x0000000000000000000000000000000000000000\"\n : false;\n const isToNativeEth =\n toTokenAddress === \"0x0000000000000000000000000000000000000000\";\n\n // Get decimals for the tokens to convert human-readable amounts to base units\n // Use known decimals for common tokens as fallback\n const KNOWN_DECIMALS: Record<string, number> = {\n ETH: 18,\n WETH: 18,\n USDC: 6,\n USDT: 6,\n USDT0: 6,\n };\n const getDecimals = (symbol: string, chainId: number): number => {\n try {\n // Case-insensitive lookup from registry (symbols like \"MockUSD\" are case-sensitive in upstream SDK)\n const match = getSupportedTokens(chainId).find(\n (t) => t.symbol.toUpperCase() === symbol.toUpperCase()\n );\n if (match) return match.decimals;\n return getTokenDecimals(symbol as never, chainId);\n } catch {\n const upperSymbol = symbol.toUpperCase();\n return KNOWN_DECIMALS[upperSymbol] ?? 18;\n }\n };\n const toDecimals = getDecimals(options.toToken, options.targetChain);\n\n // Check if this is a bridge (same token) or swap (different tokens)\n const isBridge = options.fromToken\n ? options.fromToken.toUpperCase() === options.toToken.toUpperCase()\n : false;\n\n // Build tokenRequests - tells orchestrator what output token/amount we want\n // The amount parameter now represents OUTPUT (what user wants to receive)\n // Always specify tokenRequests so the orchestrator knows the desired output and we can show \"Buying\" in UI\n const tokenRequests: IntentTokenRequest[] = [{\n token: toTokenAddress,\n amount: parseUnits(options.amount, toDecimals),\n }];\n\n // Build the intent\n // The orchestrator will handle finding the best swap/bridge route\n // For swaps/bridges, we use tokenRequests to specify output\n // We need at least one call (SDK requirement), so we use a minimal placeholder\n // The label/sublabel tell the dialog what to display (instead of \"Send\" with unknown address)\n const result = await this.sendIntent({\n username: options.username,\n targetChain: options.targetChain,\n calls: [\n {\n // Minimal call - just signals to orchestrator we want the tokenRequests delivered\n to: toTokenAddress,\n value: \"0\",\n // SDK provides labels so dialog shows \"Buy ETH\" not \"Send ETH / To: 0x000...\"\n label: `Buy ${toSymbol}`,\n sublabel: `${options.amount} ${toSymbol}`,\n },\n ],\n // Request specific output tokens - this is what actually matters for swaps\n tokenRequests,\n // Constrain orchestrator to use only the fromToken as input\n // This ensures the swap uses the correct source token\n // Use canonical symbol casing from registry (e.g. \"MockUSD\" not \"MOCKUSD\")\n sourceAssets: options.sourceAssets || (options.fromToken ? [options.fromToken] : undefined),\n // Pass source chain ID so orchestrator knows which chain to look for tokens on\n sourceChainId: options.sourceChainId,\n closeOn: options.closeOn || \"preconfirmed\",\n waitForHash: options.waitForHash,\n hashTimeoutMs: options.hashTimeoutMs,\n hashIntervalMs: options.hashIntervalMs,\n });\n\n // Return with swap-specific data\n return {\n ...result,\n quote: result.success\n ? {\n fromToken: fromTokenAddress ?? options.fromToken,\n toToken: toTokenAddress,\n amountIn: options.amount,\n amountOut: \"\", // Filled by orchestrator quote\n rate: \"\",\n }\n : undefined,\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 dialogUrl = this.getDialogUrl();\n const themeParams = this.getThemeParams(options?.theme);\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n if (!dialogResult.ready) {\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 };\n dialogResult.sendInit(initPayload);\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 },\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 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 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 // 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 themeParams = this.getThemeParams(options?.theme);\n const signingUrl = `${dialogUrl}/dialog/sign?mode=iframe${themeParams ? `&${themeParams}` : ''}`;\n\n const { dialog, iframe, cleanup } = this.createModalDialog(signingUrl);\n\n const dialogResult = await this.waitForDialogReadyDeferred(dialog, iframe, cleanup);\n if (!dialogResult.ready) {\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 };\n dialogResult.sendInit(initPayload);\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 },\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 return {\n success: true,\n signature: signingResult.signature,\n signedHash,\n passkey: signingResult.passkey,\n };\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 return iframe;\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 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 ): 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 teardown();\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n ...initMessage,\n fullViewport: true,\n }, dialogOrigin);\n resolve(true);\n } else if (event.data?.type === \"PASSKEY_CLOSE\") {\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 only the transparent outer shell; all visible UI (backdrop,\n * card, animations, close button) is rendered by the passkey app inside the\n * iframe. This approach means design changes can be shipped server-side\n * without updating SDK consumers.\n *\n * Lifecycle:\n * 1. A themed \"Loading…\" overlay is injected and shown immediately while the\n * iframe loads, matching the exact visual structure of the passkey app's\n * TitleBar + IndeterminateLoader so the transition is seamless.\n * 2. When the iframe sends `PASSKEY_RENDERED`, the overlay fades out and\n * the iframe becomes fully visible.\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 *\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): {\n dialog: HTMLDialogElement;\n iframe: HTMLIFrameElement;\n cleanup: () => void;\n } {\n const dialogUrl = this.getDialogUrl();\n const hostUrl = new URL(dialogUrl);\n\n // Extract theme from URL params for loading overlay styling\n const urlParams = new URL(url, window.location.href).searchParams;\n const themeMode = urlParams.get('theme') || 'light';\n const accentColor = urlParams.get('accent') || '#0090ff';\n const isDark = themeMode === 'dark' ||\n (themeMode !== 'light' && window.matchMedia('(prefers-color-scheme: dark)').matches);\n\n const bgPrimary = isDark ? '#191919' : '#fcfcfc';\n const bgSecondary = isDark ? '#222222' : '#f9f9f9';\n const borderColor = isDark ? '#2a2a2a' : '#e0e0e0';\n const textPrimary = isDark ? '#eeeeee' : '#202020';\n const textSecondary = isDark ? '#7b7b7b' : '#838383';\n const bgSurface = isDark ? '#222222' : '#f0f0f0';\n const ah = accentColor.replace('#', '');\n const accentRgb = `${parseInt(ah.slice(0,2),16)},${parseInt(ah.slice(2,4),16)},${parseInt(ah.slice(4,6),16)}`;\n const accentTint = isDark ? `rgba(${accentRgb},0.15)` : `rgba(${accentRgb},0.1)`;\n const hostname = window.location.hostname;\n\n const dialog = document.createElement(\"dialog\");\n dialog.dataset.passkey = \"\";\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] 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(8px);\n -webkit-backdrop-filter: blur(8px);\n }\n dialog[data-passkey] [data-passkey-overlay] {\n position: fixed;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: flex-start;\n justify-content: center;\n padding-top: 50px;\n background: rgba(0, 0, 0, 0.4);\n backdrop-filter: blur(8px);\n -webkit-backdrop-filter: blur(8px);\n z-index: 1;\n animation: _1auth-backdrop-in 0.2s ease-out;\n }\n @media (max-width: 768px) {\n dialog[data-passkey] [data-passkey-overlay] {\n align-items: flex-end;\n padding-top: 0;\n }\n }\n dialog[data-passkey] [data-passkey-card] {\n width: 340px;\n overflow: hidden;\n border-radius: 14px;\n box-shadow: 0 8px 32px rgba(0,0,0,0.12), 0 2px 8px rgba(0,0,0,0.08);\n animation: _1auth-card-in 0.2s cubic-bezier(0.32, 0.72, 0, 1);\n max-height: calc(100dvh - 100px);\n }\n @media (max-width: 768px) {\n dialog[data-passkey] [data-passkey-card] {\n width: 100%;\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n animation: _1auth-card-slide 0.3s cubic-bezier(0.32, 0.72, 0, 1);\n }\n }\n @keyframes _1auth-backdrop-in {\n from { opacity: 0; } to { opacity: 1; }\n }\n @keyframes _1auth-card-in {\n from { opacity: 0; transform: scale(0.96) translateY(8px); }\n to { opacity: 1; transform: scale(1) translateY(0); }\n }\n @keyframes _1auth-card-slide {\n from { transform: translate3d(0, 100%, 0); }\n to { transform: translate3d(0, 0, 0); }\n }\n @keyframes _1auth-spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `;\n dialog.appendChild(style);\n\n // Create loading overlay — replicates the passkey dialog's exact visual\n // structure (TitleBar + IndeterminateLoader) for a seamless transition\n const overlay = document.createElement(\"div\");\n overlay.dataset.passkeyOverlay = \"\";\n const _sp = '<path d=\"M10 0.5C8.02219 0.5 6.08879 1.08649 4.4443 2.1853C2.79981 3.28412 1.51809 4.8459 0.761209 6.67316C0.00433288 8.50043 -0.1937 10.5111 0.192152 12.4509C0.578004 14.3907 1.53041 16.1725 2.92894 17.5711C4.32746 18.9696 6.10929 19.922 8.0491 20.3078C9.98891 20.6937 11.9996 20.4957 13.8268 19.7388C15.6541 18.9819 17.2159 17.7002 18.3147 16.0557C19.4135 14.4112 20 12.4778 20 10.5C20 7.84783 18.9464 5.3043 17.0711 3.42893C15.1957 1.55357 12.6522 0.5 10 0.5ZM10 17.7727C8.56159 17.7727 7.15549 17.3462 5.95949 16.547C4.7635 15.7479 3.83134 14.6121 3.28088 13.2831C2.73042 11.9542 2.5864 10.4919 2.86702 9.08116C3.14764 7.67039 3.8403 6.37451 4.85741 5.3574C5.87452 4.3403 7.17039 3.64764 8.58116 3.36702C9.99193 3.0864 11.4542 3.23042 12.7832 3.78088C14.1121 4.33133 15.2479 5.26349 16.0471 6.45949C16.8462 7.65548 17.2727 9.06159 17.2727 10.5C17.2727 12.4288 16.5065 14.2787 15.1426 15.6426C13.7787 17.0065 11.9288 17.7727 10 17.7727Z\" fill=\"currentColor\" opacity=\"0.3\"/><path d=\"M10 3.22767C11.7423 3.22846 13.4276 3.8412 14.7556 4.95667C16.0837 6.07214 16.9681 7.61784 17.2512 9.31825C17.3012 9.64364 17.4662 9.94096 17.7169 10.1573C17.9677 10.3737 18.2878 10.4951 18.6205 10.5C18.8211 10.5001 19.0193 10.457 19.2012 10.3735C19.3832 10.2901 19.5445 10.1684 19.674 10.017C19.8036 9.86549 19.8981 9.68789 19.9511 9.49656C20.004 9.30523 20.0141 9.10478 19.9807 8.90918C19.5986 6.56305 18.3843 4.42821 16.5554 2.88726C14.7265 1.34631 12.4025 0.5 10 0.5C7.59751 0.5 5.27354 1.34631 3.44461 2.88726C1.61569 4.42821 0.401366 6.56305 0.0192815 8.90918C-0.0141442 9.10478 -0.00402016 9.30523 0.0489472 9.49656C0.101914 9.68789 0.196449 9.86549 0.325956 10.017C0.455463 10.1684 0.616823 10.2901 0.798778 10.3735C0.980732 10.457 1.1789 10.5001 1.37945 10.5C1.71216 10.4951 2.03235 10.3737 2.28307 10.1573C2.5338 9.94096 2.69883 9.64364 2.74882 9.31825C3.03193 7.61784 3.91633 6.07214 5.24436 4.95667C6.57239 3.8412 8.25775 3.22846 10 3.22767Z\" fill=\"currentColor\"/>';\n overlay.innerHTML =\n `<div data-passkey-card style=\"background:${bgPrimary};border:1px solid ${borderColor};font-family:ui-sans-serif,system-ui,sans-serif,'Apple Color Emoji','Segoe UI Emoji'\">` +\n // TitleBar — matches apps/passkey TitleBar.tsx layout\n `<div style=\"height:36px;display:flex;align-items:center;justify-content:space-between;padding:0 12px;background:${bgSecondary};border-bottom:1px solid ${borderColor}\">` +\n `<div style=\"display:flex;align-items:center;gap:8px\">` +\n `<div style=\"display:flex;width:20px;height:20px;align-items:center;justify-content:center;border-radius:4px;background:${bgSurface}\">` +\n `<svg width=\"12\" height=\"12\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${textPrimary}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M21 12V7H5a2 2 0 0 1 0-4h14v4\"/><path d=\"M3 5v14a2 2 0 0 0 2 2h16v-5\"/><path d=\"M18 12a2 2 0 0 0 0 4h4v-4Z\"/></svg>` +\n `</div>` +\n `<span style=\"font-size:13px;font-weight:500;color:${textPrimary};max-width:200px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap\">${hostname}</span>` +\n `<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"${textSecondary}\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z\"/><path d=\"m9 12 2 2 4-4\"/></svg>` +\n `</div>` +\n `<div style=\"display:flex;align-items:center;gap:4px\">` +\n `<div style=\"display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary}\">` +\n `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z\"/><circle cx=\"12\" cy=\"12\" r=\"3\"/></svg>` +\n `</div>` +\n `<button data-passkey-close style=\"display:flex;width:24px;height:24px;align-items:center;justify-content:center;border-radius:6px;color:${textSecondary};border:none;background:none;cursor:pointer;padding:0\">` +\n `<svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/></svg>` +\n `</button>` +\n `</div>` +\n `</div>` +\n // Content — matches IndeterminateLoader (horizontal) with p-3\n `<div style=\"padding:12px\">` +\n `<div style=\"display:flex;align-items:center;gap:8px\">` +\n `<div style=\"display:flex;width:32px;height:32px;min-width:32px;align-items:center;justify-content:center;border-radius:50%;background:${accentTint};padding:6px\">` +\n `<svg style=\"width:100%;height:100%;animation:_1auth-spin 0.8s linear infinite;color:${accentColor}\" fill=\"none\" viewBox=\"0 0 20 21\" xmlns=\"http://www.w3.org/2000/svg\">${_sp}</svg>` +\n `</div>` +\n `<div style=\"font-weight:500;font-size:18px;color:${textPrimary}\">Loading...</div>` +\n `</div>` +\n `<div style=\"margin-top:8px\">` +\n `<div style=\"font-size:15px;line-height:20px;color:${textPrimary}\">This will only take a few moments.</div>` +\n `<div style=\"font-size:15px;line-height:20px;color:${textSecondary}\">Please do not close the window.</div>` +\n `</div>` +\n `</div>` +\n `</div>`;\n overlay.addEventListener(\"click\", (e) => {\n if (e.target === overlay) cleanup();\n });\n const overlayCloseBtn = overlay.querySelector(\"[data-passkey-close]\");\n if (overlayCloseBtn) overlayCloseBtn.addEventListener(\"click\", () => cleanup());\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 iframe.setAttribute(\n \"sandbox\",\n \"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\",\n );\n iframe.setAttribute(\"src\", url);\n iframe.setAttribute(\"title\", \"Passkey\");\n iframe.style.opacity = \"0\";\n\n dialog.appendChild(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 // Hide loading overlay and reveal iframe content.\n // Sequence across two frames: first make the iframe visible (it renders\n // behind the overlay due to z-index), then remove the overlay on the next\n // frame once the iframe's backdrop-filter is composited.\n let overlayHidden = false;\n const hideOverlay = () => {\n if (overlayHidden) return;\n overlayHidden = true;\n iframe.style.opacity = \"1\";\n requestAnimationFrame(() => {\n overlay.style.display = \"none\";\n });\n };\n\n // Handle messages from iframe\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== hostUrl.origin) return;\n if (event.data?.type === \"PASSKEY_RENDERED\") {\n hideOverlay();\n }\n if (event.data?.type === \"PASSKEY_DISCONNECT\") {\n localStorage.removeItem(\"1auth-user\");\n }\n };\n window.addEventListener(\"message\", handleMessage);\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 // Show modal\n dialog.showModal();\n\n let cleanedUp = false;\n const cleanup = () => {\n if (cleanedUp) return;\n cleanedUp = true;\n inertObserver.disconnect();\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 return { dialog, iframe, cleanup };\n }\n\n /**\n * Listen for the auth result from the modal dialog.\n *\n * Waits for `PASSKEY_READY` before processing any other messages to avoid\n * acting on stale `PASSKEY_CLOSE` events that may still be in the event queue\n * from a previously closed dialog.\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 ): Promise<AuthResult> {\n const dialogOrigin = this.getDialogOrigin();\n return new Promise((resolve) => {\n // Track whether the dialog has signaled ready\n // This prevents stale PASSKEY_CLOSE messages from previous dialogs\n let dialogReady = false;\n\n const handleMessage = (event: MessageEvent) => {\n if (event.origin !== dialogOrigin) return;\n\n const data = event.data;\n\n // Wait for dialog to signal ready before processing other messages\n if (data?.type === \"PASSKEY_READY\") {\n dialogReady = true;\n // Send init message to the auth dialog\n iframe.contentWindow?.postMessage({\n type: \"PASSKEY_INIT\",\n mode: \"iframe\",\n fullViewport: true,\n }, dialogOrigin);\n return;\n }\n\n // Ignore messages until dialog is ready (prevents stale CLOSE from previous dialogs)\n if (!dialogReady && data?.type === \"PASSKEY_CLOSE\") {\n return;\n }\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 });\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 } else if (data?.type === \"PASSKEY_CLOSE\") {\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 }\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 });\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 authenticate result from the modal dialog.\n *\n * The authenticate flow combines sign-in/sign-up with optional off-chain\n * challenge signing. The dialog sends `PASSKEY_AUTHENTICATE_RESULT` on\n * completion with both user details and, if a challenge was requested, the\n * WebAuthn signature and the hashed challenge value for server-side\n * verification.\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 An `AuthenticateResult` discriminated union.\n */\n private waitForAuthenticateResponse(\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<AuthenticateResult> {\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_AUTHENTICATE_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?.accountAddress as `0x${string}`,\n },\n challenge: data.data?.signature ? {\n signature: data.data.signature,\n signedHash: data.data.signedHash,\n } : undefined,\n });\n } else {\n resolve({\n success: false,\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 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 the consent result from the consent dialog.\n *\n * The consent dialog shows the user which data fields an app is requesting\n * access to and lets them approve or deny. On approval, `data` contains the\n * consented field values (e.g. email address, device names) and `grantedAt`\n * records when consent was given.\n *\n * A `PASSKEY_CLOSE` without a prior `PASSKEY_CONSENT_RESULT` is treated as an\n * explicit user cancellation (distinct from denial, though both yield\n * `success: false`).\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 `RequestConsentResult` discriminated union.\n */\n private waitForConsentResponse(\n _dialog: HTMLDialogElement,\n _iframe: HTMLIFrameElement,\n cleanup: () => void\n ): Promise<RequestConsentResult> {\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_CONSENT_RESULT\") {\n window.removeEventListener(\"message\", handleMessage);\n cleanup();\n\n if (data.success) {\n resolve({\n success: true,\n data: data.data,\n grantedAt: data.data?.grantedAt,\n });\n } else {\n resolve({\n success: false,\n error: data.error ?? {\n code: \"USER_REJECTED\" as const,\n message: \"User denied the consent request\",\n },\n });\n }\n } else if (data?.type === \"PASSKEY_CLOSE\") {\n window.removeEventListener(\"message\", handleMessage);\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 window.addEventListener(\"message\", handleMessage);\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","/**\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 username: string;\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 - The 1auth username associated with the account; included\n * in signing requests so the passkey service can look up the correct credential\n * @returns A `PasskeyAccount` extending `LocalAccount<\"1auth\">` with a `username` field\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 * username: \"alice\",\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,\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,\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,\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.box',\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 resolvedUsername = config.username ?? config.accountAddress;\n\n const provider = new OneAuthClient({\n providerUrl: config.providerUrl,\n clientId: config.clientId,\n dialogUrl: config.dialogUrl,\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 username: resolvedUsername,\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 username: resolvedUsername,\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 username: resolvedUsername,\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 }));\n\n return {\n username: resolvedUsername,\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 const closeOn = (config.waitForHash ?? true)\n ? \"completed\"\n : \"preconfirmed\";\n\n const intentPayload = await buildIntentPayload(calls, targetChain);\n const result = await provider.sendIntent({\n ...intentPayload,\n closeOn,\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 closeOn = (config.waitForHash ?? true)\n ? \"completed\"\n : \"preconfirmed\";\n const intentPayload = await buildIntentPayload(calls, targetChain, { tokenRequests, sourceAssets });\n const result = await provider.sendIntent({\n ...intentPayload,\n tokenRequests,\n sourceAssets,\n sourceChainId,\n closeOn,\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/**\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: (username: string) => 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 */\nfunction getStorageKey(username?: string): string {\n return username ? `1auth_batch_queue_${username}` : \"1auth_batch_queue_anonymous\";\n}\n\nexport interface BatchQueueProviderProps {\n /** The OneAuthClient instance */\n client: OneAuthClient;\n /** Optional username for localStorage persistence key */\n username?: 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 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 // 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(username);\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 }, [username]);\n\n // Save queue to localStorage when it changes\n React.useEffect(() => {\n const storageKey = getStorageKey(username);\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, username]);\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 (username: string): 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 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,\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]);\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 - should provide username */\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 username and passing it to\n * `useBatchQueue().signAll(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 &times;\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","import { keccak256, toBytes } from \"viem\";\n\n/**\n * The EIP-191 prefix used for personal message signing.\n * This is the standard Ethereum message prefix for `personal_sign`.\n */\nexport const ETHEREUM_MESSAGE_PREFIX = \"\\x19Ethereum Signed Message:\\n\";\n\n/**\n * Hash a message with the EIP-191 Ethereum prefix.\n *\n * This is the same hashing function used by the passkey sign dialog.\n * Use this to verify that the `signedHash` returned from `signMessage()`\n * matches your original message.\n *\n * Format: keccak256(\"\\x19Ethereum Signed Message:\\n\" + len + message)\n *\n * @example\n * ```typescript\n * const message = \"Sign in to MyApp\\nTimestamp: 1234567890\";\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * // Verify the hash matches\n * const expectedHash = hashMessage(message);\n * if (result.signedHash === expectedHash) {\n * console.log('Hash matches - signature is for this message');\n * }\n * ```\n */\nexport function hashMessage(message: string): `0x${string}` {\n const messageBytes = toBytes(message);\n const prefixed = ETHEREUM_MESSAGE_PREFIX + messageBytes.length.toString() + message;\n return keccak256(toBytes(prefixed));\n}\n\n/**\n * Verify that a signedHash matches the expected message.\n *\n * This is a convenience wrapper around `hashMessage()` that returns\n * a boolean. For full cryptographic verification of the P256 signature,\n * use on-chain verification via the WebAuthn.sol contract.\n *\n * @example\n * ```typescript\n * const result = await client.signMessage({ username: 'alice', message });\n *\n * if (result.success && verifyMessageHash(message, result.signedHash)) {\n * // The signature is for this exact message\n * // For full verification, verify the P256 signature on-chain or server-side\n * }\n * ```\n */\nexport function verifyMessageHash(\n message: string,\n signedHash: string | undefined\n): boolean {\n if (!signedHash) return false;\n const expectedHash = hashMessage(message);\n return expectedHash.toLowerCase() === signedHash.toLowerCase();\n}\n"],"mappings":"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","names":["dialogOrigin","closeOn","successStatuses","hashTypedData","toAccount","hashTypedData","toAccount","getChainName","username","React","jsx","getChainName","hashMessage"]}