kentucky-signer-viem 0.1.0

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/react/index.ts","../../src/react/context.tsx","../../src/client.ts","../../src/utils.ts","../../src/auth.ts","../../src/account.ts","../../src/react/hooks.ts"],"sourcesContent":["/**\n * Kentucky Signer React Integration\n *\n * React hooks and context for integrating Kentucky Signer authentication\n * and signing into React applications.\n *\n * @packageDocumentation\n */\n\n// Context\nexport {\n KentuckySignerProvider,\n useKentuckySignerContext,\n type KentuckySignerProviderProps,\n type KentuckySignerState,\n type KentuckySignerActions,\n type KentuckySignerContextValue,\n} from './context'\n\n// Hooks\nexport {\n useKentuckySigner,\n useKentuckySignerAccount,\n useWalletClient,\n usePasskeyAuth,\n useSignMessage,\n useSignTypedData,\n useIsReady,\n useAddress,\n type UseWalletClientOptions,\n} from './hooks'\n","import React, {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n useMemo,\n type ReactNode,\n} from 'react'\nimport type { AuthSession } from '../types'\nimport { KentuckySignerClient } from '../client'\nimport {\n authenticateWithPasskey,\n isSessionValid,\n refreshSessionIfNeeded,\n LocalStorageTokenStorage,\n} from '../auth'\nimport {\n createKentuckySignerAccount,\n type KentuckySignerAccount,\n} from '../account'\n\n/**\n * Kentucky Signer context state\n */\nexport interface KentuckySignerState {\n /** Whether authentication is in progress */\n isAuthenticating: boolean\n /** Whether the user is authenticated */\n isAuthenticated: boolean\n /** Current session (if authenticated) */\n session: AuthSession | null\n /** Current account (if authenticated) */\n account: KentuckySignerAccount | null\n /** Last error (if any) */\n error: Error | null\n}\n\n/**\n * Kentucky Signer context actions\n */\nexport interface KentuckySignerActions {\n /** Authenticate with passkey */\n authenticate: (accountId: string, options?: { rpId?: string }) => Promise<void>\n /** Logout and clear session */\n logout: () => Promise<void>\n /** Refresh session if needed */\n refreshSession: () => Promise<void>\n /** Clear any errors */\n clearError: () => void\n}\n\n/**\n * Full Kentucky Signer context value\n */\nexport type KentuckySignerContextValue = KentuckySignerState & KentuckySignerActions\n\nconst KentuckySignerContext = createContext<KentuckySignerContextValue | null>(null)\n\n/**\n * Kentucky Signer provider props\n */\nexport interface KentuckySignerProviderProps {\n /** Base URL of the Kentucky Signer API */\n baseUrl: string\n /** Default chain ID for signing */\n defaultChainId?: number\n /** Storage key prefix for persisting tokens */\n storageKeyPrefix?: string\n /** Whether to persist session in localStorage */\n persistSession?: boolean\n /** Children */\n children: ReactNode\n}\n\n/**\n * Kentucky Signer Provider\n *\n * Wraps your app to provide Kentucky Signer authentication and signing context.\n *\n * @example\n * ```tsx\n * <KentuckySignerProvider baseUrl=\"https://signer.example.com\">\n * <App />\n * </KentuckySignerProvider>\n * ```\n */\nexport function KentuckySignerProvider({\n baseUrl,\n defaultChainId = 1,\n storageKeyPrefix = 'kentucky_signer',\n persistSession = true,\n children,\n}: KentuckySignerProviderProps) {\n const [state, setState] = useState<KentuckySignerState>({\n isAuthenticating: false,\n isAuthenticated: false,\n session: null,\n account: null,\n error: null,\n })\n\n const client = useMemo(\n () => new KentuckySignerClient({ baseUrl }),\n [baseUrl]\n )\n\n const storage = useMemo(\n () => (persistSession ? new LocalStorageTokenStorage(storageKeyPrefix) : null),\n [persistSession, storageKeyPrefix]\n )\n\n // Create account from session\n const createAccount = useCallback(\n (session: AuthSession): KentuckySignerAccount => {\n return createKentuckySignerAccount({\n config: { baseUrl, accountId: session.accountId },\n session,\n defaultChainId,\n onSessionExpired: async () => {\n // Try to refresh the session\n const newSession = await refreshSessionIfNeeded(session, baseUrl, 0)\n setState((s) => ({\n ...s,\n session: newSession,\n account: s.account\n ? { ...s.account, session: newSession }\n : null,\n }))\n return newSession\n },\n })\n },\n [baseUrl, defaultChainId]\n )\n\n // Restore session from storage on mount\n useEffect(() => {\n async function restoreSession() {\n if (!storage) return\n\n try {\n const savedSession = localStorage.getItem(`${storageKeyPrefix}_session`)\n if (!savedSession) return\n\n const session: AuthSession = JSON.parse(savedSession)\n if (!isSessionValid(session)) {\n // Try to refresh\n try {\n const refreshed = await refreshSessionIfNeeded(session, baseUrl, 0)\n const account = createAccount(refreshed)\n localStorage.setItem(\n `${storageKeyPrefix}_session`,\n JSON.stringify(refreshed)\n )\n setState({\n isAuthenticating: false,\n isAuthenticated: true,\n session: refreshed,\n account,\n error: null,\n })\n } catch {\n // Clear invalid session\n localStorage.removeItem(`${storageKeyPrefix}_session`)\n }\n return\n }\n\n const account = createAccount(session)\n setState({\n isAuthenticating: false,\n isAuthenticated: true,\n session,\n account,\n error: null,\n })\n } catch {\n localStorage.removeItem(`${storageKeyPrefix}_session`)\n }\n }\n\n restoreSession()\n }, [storage, storageKeyPrefix, baseUrl, createAccount])\n\n // Authenticate with passkey\n const authenticate = useCallback(\n async (accountId: string, options?: { rpId?: string }) => {\n setState((s) => ({ ...s, isAuthenticating: true, error: null }))\n\n try {\n const session = await authenticateWithPasskey({\n baseUrl,\n accountId,\n rpId: options?.rpId,\n })\n\n const account = createAccount(session)\n\n // Persist session\n if (storage) {\n localStorage.setItem(\n `${storageKeyPrefix}_session`,\n JSON.stringify(session)\n )\n }\n\n setState({\n isAuthenticating: false,\n isAuthenticated: true,\n session,\n account,\n error: null,\n })\n } catch (error) {\n setState((s) => ({\n ...s,\n isAuthenticating: false,\n error: error as Error,\n }))\n throw error\n }\n },\n [baseUrl, createAccount, storage, storageKeyPrefix]\n )\n\n // Logout\n const logout = useCallback(async () => {\n try {\n if (state.session) {\n await client.logout(state.session.token)\n }\n } catch {\n // Ignore logout errors\n }\n\n // Clear storage\n if (storage) {\n localStorage.removeItem(`${storageKeyPrefix}_session`)\n }\n\n setState({\n isAuthenticating: false,\n isAuthenticated: false,\n session: null,\n account: null,\n error: null,\n })\n }, [client, state.session, storage, storageKeyPrefix])\n\n // Refresh session\n const refreshSession = useCallback(async () => {\n if (!state.session) return\n\n try {\n const refreshed = await refreshSessionIfNeeded(state.session, baseUrl)\n\n if (refreshed !== state.session) {\n const account = createAccount(refreshed)\n\n if (storage) {\n localStorage.setItem(\n `${storageKeyPrefix}_session`,\n JSON.stringify(refreshed)\n )\n }\n\n setState((s) => ({\n ...s,\n session: refreshed,\n account,\n }))\n }\n } catch (error) {\n setState((s) => ({ ...s, error: error as Error }))\n }\n }, [state.session, baseUrl, createAccount, storage, storageKeyPrefix])\n\n // Clear error\n const clearError = useCallback(() => {\n setState((s) => ({ ...s, error: null }))\n }, [])\n\n const value: KentuckySignerContextValue = useMemo(\n () => ({\n ...state,\n authenticate,\n logout,\n refreshSession,\n clearError,\n }),\n [state, authenticate, logout, refreshSession, clearError]\n )\n\n return (\n <KentuckySignerContext.Provider value={value}>\n {children}\n </KentuckySignerContext.Provider>\n )\n}\n\n/**\n * Use the Kentucky Signer context\n *\n * Must be used within a KentuckySignerProvider.\n *\n * @returns Kentucky Signer context value\n */\nexport function useKentuckySignerContext(): KentuckySignerContextValue {\n const context = useContext(KentuckySignerContext)\n if (!context) {\n throw new Error(\n 'useKentuckySignerContext must be used within a KentuckySignerProvider'\n )\n }\n return context\n}\n","import type {\n ClientOptions,\n ChallengeResponse,\n AuthResponse,\n AccountInfoResponse,\n EvmSignatureResponse,\n ApiErrorResponse,\n PasskeyCredential,\n AccountCreationResponse,\n SignEvmRequest,\n CreatePasswordAccountRequest,\n PasswordAuthRequest,\n} from './types'\nimport type { Hex } from 'viem'\n\n/**\n * Kentucky Signer API error\n */\nexport class KentuckySignerError extends Error {\n constructor(\n message: string,\n public code: string,\n public details?: string\n ) {\n super(message)\n this.name = 'KentuckySignerError'\n }\n}\n\n/**\n * Kentucky Signer API client\n *\n * Handles communication with the Kentucky Signer API for authentication,\n * account management, and transaction signing.\n */\nexport class KentuckySignerClient {\n private baseUrl: string\n private fetchImpl: typeof fetch\n private timeout: number\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, '') // Remove trailing slash\n this.fetchImpl = options.fetch ?? globalThis.fetch\n this.timeout = options.timeout ?? 30000\n }\n\n /**\n * Make an authenticated request to the API\n */\n private async request<T>(\n path: string,\n options: RequestInit & { token?: string } = {}\n ): Promise<T> {\n const { token, ...fetchOptions } = options\n\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n ...options.headers,\n }\n\n if (token) {\n ;(headers as Record<string, string>)['Authorization'] = `Bearer ${token}`\n }\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), this.timeout)\n\n try {\n const response = await this.fetchImpl(`${this.baseUrl}${path}`, {\n ...fetchOptions,\n headers,\n signal: controller.signal,\n })\n\n const data = await response.json()\n\n if (!response.ok || data.success === false) {\n const error = data as ApiErrorResponse\n throw new KentuckySignerError(\n error.error?.message ?? 'Unknown error',\n error.error?.code ?? 'UNKNOWN_ERROR',\n error.error?.details\n )\n }\n\n return data as T\n } finally {\n clearTimeout(timeoutId)\n }\n }\n\n /**\n * Get a challenge for passkey authentication\n *\n * @param accountId - Account ID to authenticate\n * @returns Challenge response with 32-byte challenge\n */\n async getChallenge(accountId: string): Promise<ChallengeResponse> {\n return this.request<ChallengeResponse>('/api/auth/challenge', {\n method: 'POST',\n body: JSON.stringify({ account_id: accountId }),\n })\n }\n\n /**\n * Authenticate with a passkey credential\n *\n * @param accountId - Account ID to authenticate\n * @param credential - WebAuthn credential from navigator.credentials.get()\n * @returns Authentication response with JWT token\n */\n async authenticatePasskey(\n accountId: string,\n credential: PasskeyCredential\n ): Promise<AuthResponse> {\n return this.request<AuthResponse>('/api/auth/passkey', {\n method: 'POST',\n body: JSON.stringify({\n account_id: accountId,\n credential_id: credential.credentialId,\n client_data_json: credential.clientDataJSON,\n authenticator_data: credential.authenticatorData,\n signature: credential.signature,\n user_handle: credential.userHandle,\n }),\n })\n }\n\n /**\n * Refresh an authentication token\n *\n * @param token - Current JWT token\n * @returns New authentication response with fresh token\n */\n async refreshToken(token: string): Promise<AuthResponse> {\n return this.request<AuthResponse>('/api/auth/refresh', {\n method: 'POST',\n token,\n })\n }\n\n /**\n * Logout and invalidate token\n *\n * @param token - JWT token to invalidate\n */\n async logout(token: string): Promise<void> {\n await this.request('/api/auth/logout', {\n method: 'POST',\n token,\n })\n }\n\n /**\n * Get account information\n *\n * @param accountId - Account ID\n * @param token - JWT token\n * @returns Account info with addresses and passkeys\n */\n async getAccountInfo(accountId: string, token: string): Promise<AccountInfoResponse> {\n return this.request<AccountInfoResponse>(`/api/accounts/${accountId}`, {\n method: 'GET',\n token,\n })\n }\n\n /**\n * Check if an account exists\n *\n * @param accountId - Account ID\n * @param token - JWT token\n * @returns True if account exists\n */\n async accountExists(accountId: string, token: string): Promise<boolean> {\n try {\n await this.request(`/api/accounts/${accountId}`, {\n method: 'HEAD',\n token,\n })\n return true\n } catch {\n return false\n }\n }\n\n /**\n * Sign an EVM transaction hash\n *\n * @param request - Sign request with tx_hash and chain_id\n * @param token - JWT token\n * @returns Signature response with r, s, v components\n */\n async signEvmTransaction(\n request: SignEvmRequest,\n token: string\n ): Promise<EvmSignatureResponse> {\n return this.request<EvmSignatureResponse>('/api/sign/evm', {\n method: 'POST',\n token,\n body: JSON.stringify(request),\n })\n }\n\n /**\n * Sign a raw hash for EVM\n *\n * Convenience method that wraps signEvmTransaction.\n *\n * @param hash - 32-byte hash to sign (hex encoded with 0x prefix)\n * @param chainId - Chain ID\n * @param token - JWT token\n * @returns Full signature (hex encoded with 0x prefix)\n */\n async signHash(hash: Hex, chainId: number, token: string): Promise<Hex> {\n const response = await this.signEvmTransaction(\n { tx_hash: hash, chain_id: chainId },\n token\n )\n return response.signature.full\n }\n\n /**\n * Create a new account with passkey authentication\n *\n * @param credential - WebAuthn credential from navigator.credentials.create()\n * @returns Account creation response with account ID and addresses\n */\n async createAccountWithPasskey(\n credential: PasskeyCredential & { publicKey: string }\n ): Promise<AccountCreationResponse> {\n return this.request<AccountCreationResponse>('/api/accounts/create/passkey', {\n method: 'POST',\n body: JSON.stringify({\n credential_id: credential.credentialId,\n public_key: credential.publicKey,\n client_data_json: credential.clientDataJSON,\n authenticator_data: credential.authenticatorData,\n }),\n })\n }\n\n /**\n * Create a new account with password authentication\n *\n * @param request - Password and confirmation\n * @returns Account creation response with account ID and addresses\n */\n async createAccountWithPassword(\n request: CreatePasswordAccountRequest\n ): Promise<AccountCreationResponse> {\n return this.request<AccountCreationResponse>('/api/accounts/create/password', {\n method: 'POST',\n body: JSON.stringify(request),\n })\n }\n\n /**\n * Authenticate with password\n *\n * @param request - Account ID and password\n * @returns Authentication response with JWT token\n */\n async authenticatePassword(request: PasswordAuthRequest): Promise<AuthResponse> {\n return this.request<AuthResponse>('/api/auth/password', {\n method: 'POST',\n body: JSON.stringify(request),\n })\n }\n\n /**\n * Health check\n *\n * @returns True if the API is healthy\n */\n async healthCheck(): Promise<boolean> {\n try {\n const response = await this.request<{ status: string }>('/api/health', {\n method: 'GET',\n })\n return response.status === 'ok'\n } catch {\n return false\n }\n }\n\n /**\n * Get API version\n *\n * @returns Version string\n */\n async getVersion(): Promise<string> {\n const response = await this.request<{ version: string }>('/api/version', {\n method: 'GET',\n })\n return response.version\n }\n}\n\n/**\n * Create a new Kentucky Signer client\n *\n * @param options - Client options\n * @returns Kentucky Signer client instance\n */\nexport function createClient(options: ClientOptions): KentuckySignerClient {\n return new KentuckySignerClient(options)\n}\n","/**\n * Utility functions for Kentucky Signer Viem integration\n */\n\n/**\n * Base64URL encode a Uint8Array\n *\n * @param data - Data to encode\n * @returns Base64URL encoded string (no padding)\n */\nexport function base64UrlEncode(data: Uint8Array): string {\n // Convert to regular base64\n let base64: string\n if (typeof Buffer !== 'undefined') {\n // Node.js\n base64 = Buffer.from(data).toString('base64')\n } else {\n // Browser\n const binary = Array.from(data)\n .map((byte) => String.fromCharCode(byte))\n .join('')\n base64 = btoa(binary)\n }\n\n // Convert to base64url (replace + with -, / with _, remove padding)\n return base64.replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=+$/, '')\n}\n\n/**\n * Base64URL decode a string to Uint8Array\n *\n * @param str - Base64URL encoded string\n * @returns Decoded bytes\n */\nexport function base64UrlDecode(str: string): Uint8Array {\n // Convert base64url to regular base64\n let base64 = str.replace(/-/g, '+').replace(/_/g, '/')\n\n // Add padding if needed\n const padding = (4 - (base64.length % 4)) % 4\n base64 += '='.repeat(padding)\n\n if (typeof Buffer !== 'undefined') {\n // Node.js\n return new Uint8Array(Buffer.from(base64, 'base64'))\n } else {\n // Browser\n const binary = atob(base64)\n const bytes = new Uint8Array(binary.length)\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i)\n }\n return bytes\n }\n}\n\n/**\n * Convert a hex string to Uint8Array\n *\n * @param hex - Hex string (with or without 0x prefix)\n * @returns Byte array\n */\nexport function hexToBytes(hex: string): Uint8Array {\n const cleanHex = hex.startsWith('0x') ? hex.slice(2) : hex\n const bytes = new Uint8Array(cleanHex.length / 2)\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(cleanHex.slice(i * 2, i * 2 + 2), 16)\n }\n return bytes\n}\n\n/**\n * Convert a Uint8Array to hex string\n *\n * @param bytes - Byte array\n * @param withPrefix - Include 0x prefix (default: true)\n * @returns Hex string\n */\nexport function bytesToHex(bytes: Uint8Array, withPrefix: boolean = true): string {\n const hex = Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n return withPrefix ? `0x${hex}` : hex\n}\n\n/**\n * Validate an account ID format\n *\n * Account IDs are 64-character hex strings (32 bytes).\n *\n * @param accountId - Account ID to validate\n * @returns True if valid\n */\nexport function isValidAccountId(accountId: string): boolean {\n return /^[0-9a-fA-F]{64}$/.test(accountId)\n}\n\n/**\n * Validate an EVM address format\n *\n * @param address - Address to validate\n * @returns True if valid\n */\nexport function isValidEvmAddress(address: string): boolean {\n return /^0x[0-9a-fA-F]{40}$/.test(address)\n}\n\n/**\n * Sleep for a specified duration\n *\n * @param ms - Milliseconds to sleep\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n\n/**\n * Retry a function with exponential backoff\n *\n * @param fn - Function to retry\n * @param maxRetries - Maximum number of retries (default: 3)\n * @param baseDelay - Base delay in ms (default: 1000)\n * @returns Result of the function\n */\nexport async function withRetry<T>(\n fn: () => Promise<T>,\n maxRetries: number = 3,\n baseDelay: number = 1000\n): Promise<T> {\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await fn()\n } catch (error) {\n lastError = error as Error\n\n if (attempt < maxRetries) {\n const delay = baseDelay * Math.pow(2, attempt)\n await sleep(delay)\n }\n }\n }\n\n throw lastError\n}\n\n/**\n * Parse a JWT token (without validation)\n *\n * @param token - JWT token string\n * @returns Decoded payload\n */\nexport function parseJwt(token: string): Record<string, unknown> {\n const parts = token.split('.')\n if (parts.length !== 3) {\n throw new Error('Invalid JWT format')\n }\n\n const payload = base64UrlDecode(parts[1])\n const text = new TextDecoder().decode(payload)\n return JSON.parse(text)\n}\n\n/**\n * Get JWT expiration time\n *\n * @param token - JWT token string\n * @returns Expiration timestamp in milliseconds, or null if no exp claim\n */\nexport function getJwtExpiration(token: string): number | null {\n try {\n const payload = parseJwt(token)\n if (typeof payload.exp === 'number') {\n return payload.exp * 1000 // Convert seconds to milliseconds\n }\n return null\n } catch {\n return null\n }\n}\n\n/**\n * Format an error for display\n *\n * @param error - Error to format\n * @returns Formatted error message\n */\nexport function formatError(error: unknown): string {\n if (error instanceof Error) {\n return error.message\n }\n if (typeof error === 'string') {\n return error\n }\n return 'An unknown error occurred'\n}\n","import type {\n AuthSession,\n PasskeyAuthOptions,\n PasskeyCredential,\n PasskeyRegistrationOptions,\n TokenStorage,\n PasswordAuthOptions,\n PasswordAccountCreationOptions,\n AccountCreationResponse,\n} from './types'\nimport { KentuckySignerClient, KentuckySignerError } from './client'\nimport { base64UrlEncode, base64UrlDecode } from './utils'\nimport type { Address } from 'viem'\n\n/**\n * Check if WebAuthn is available in the current environment\n */\nexport function isWebAuthnAvailable(): boolean {\n return (\n typeof window !== 'undefined' &&\n typeof window.PublicKeyCredential !== 'undefined' &&\n typeof navigator.credentials !== 'undefined'\n )\n}\n\n/**\n * In-memory token storage (default implementation)\n */\nexport class MemoryTokenStorage implements TokenStorage {\n private token: string | null = null\n private expiresAt: number = 0\n\n async getToken(): Promise<string | null> {\n if (this.token && Date.now() < this.expiresAt) {\n return this.token\n }\n return null\n }\n\n async setToken(token: string, expiresAt: number): Promise<void> {\n this.token = token\n this.expiresAt = expiresAt\n }\n\n async clearToken(): Promise<void> {\n this.token = null\n this.expiresAt = 0\n }\n}\n\n/**\n * Browser localStorage token storage\n */\nexport class LocalStorageTokenStorage implements TokenStorage {\n private keyPrefix: string\n\n constructor(keyPrefix: string = 'kentucky_signer') {\n this.keyPrefix = keyPrefix\n }\n\n async getToken(): Promise<string | null> {\n if (typeof localStorage === 'undefined') return null\n\n const token = localStorage.getItem(`${this.keyPrefix}_token`)\n const expiresAt = localStorage.getItem(`${this.keyPrefix}_expires`)\n\n if (token && expiresAt && Date.now() < parseInt(expiresAt, 10)) {\n return token\n }\n\n // Clear expired token\n await this.clearToken()\n return null\n }\n\n async setToken(token: string, expiresAt: number): Promise<void> {\n if (typeof localStorage === 'undefined') return\n\n localStorage.setItem(`${this.keyPrefix}_token`, token)\n localStorage.setItem(`${this.keyPrefix}_expires`, expiresAt.toString())\n }\n\n async clearToken(): Promise<void> {\n if (typeof localStorage === 'undefined') return\n\n localStorage.removeItem(`${this.keyPrefix}_token`)\n localStorage.removeItem(`${this.keyPrefix}_expires`)\n }\n}\n\n/**\n * Convert a PublicKeyCredential to our PasskeyCredential format\n */\nfunction credentialToPasskey(credential: PublicKeyCredential): PasskeyCredential {\n const response = credential.response as AuthenticatorAssertionResponse\n\n return {\n credentialId: base64UrlEncode(new Uint8Array(credential.rawId)),\n clientDataJSON: base64UrlEncode(new Uint8Array(response.clientDataJSON)),\n authenticatorData: base64UrlEncode(new Uint8Array(response.authenticatorData)),\n signature: base64UrlEncode(new Uint8Array(response.signature)),\n userHandle: response.userHandle\n ? base64UrlEncode(new Uint8Array(response.userHandle))\n : undefined,\n }\n}\n\n/**\n * Authenticate with a passkey (browser only)\n *\n * This function handles the full WebAuthn authentication flow:\n * 1. Request a challenge from the Kentucky Signer\n * 2. Prompt the user to authenticate with their passkey\n * 3. Send the credential to the Kentucky Signer\n * 4. Return an authenticated session\n *\n * @param options - Passkey authentication options\n * @returns Authenticated session\n */\nexport async function authenticateWithPasskey(\n options: PasskeyAuthOptions\n): Promise<AuthSession> {\n if (!isWebAuthnAvailable()) {\n throw new KentuckySignerError(\n 'WebAuthn is not available in this environment',\n 'WEBAUTHN_NOT_AVAILABLE',\n 'Use authenticateWithToken() for server-side authentication'\n )\n }\n\n const client = new KentuckySignerClient({ baseUrl: options.baseUrl })\n\n // Step 1: Get challenge\n const challengeResponse = await client.getChallenge(options.accountId)\n const challengeBytes = base64UrlDecode(challengeResponse.challenge)\n\n // Step 2: Build credential request options\n const credentialRequestOptions: CredentialRequestOptions = {\n publicKey: {\n challenge: challengeBytes.buffer as ArrayBuffer,\n timeout: 60000,\n rpId: options.rpId ?? window.location.hostname,\n userVerification: 'preferred',\n allowCredentials: options.allowCredentials?.map((id) => ({\n type: 'public-key' as const,\n id: base64UrlDecode(id).buffer as ArrayBuffer,\n })),\n },\n }\n\n // Step 3: Request credential from user\n const credential = (await navigator.credentials.get(\n credentialRequestOptions\n )) as PublicKeyCredential | null\n\n if (!credential) {\n throw new KentuckySignerError(\n 'User cancelled passkey authentication',\n 'USER_CANCELLED'\n )\n }\n\n // Step 4: Authenticate with Kentucky Signer\n const passkeyCredential = credentialToPasskey(credential)\n const authResponse = await client.authenticatePasskey(\n options.accountId,\n passkeyCredential\n )\n\n // Step 5: Get account info to retrieve addresses\n const accountInfo = await client.getAccountInfo(\n options.accountId,\n authResponse.token\n )\n\n // Step 6: Build and return session\n const expiresAt = Date.now() + authResponse.expires_in * 1000\n\n return {\n token: authResponse.token,\n accountId: options.accountId,\n evmAddress: accountInfo.addresses.evm as Address,\n btcAddress: accountInfo.addresses.bitcoin,\n solAddress: accountInfo.addresses.solana,\n expiresAt,\n }\n}\n\n/**\n * Create an authenticated session from an existing JWT token (Node.js compatible)\n *\n * Use this for server-side applications where you already have a JWT token.\n *\n * @param baseUrl - Kentucky Signer API URL\n * @param accountId - Account ID\n * @param token - JWT token\n * @param expiresAt - Token expiration timestamp (Unix ms), optional\n * @returns Authenticated session\n */\nexport async function authenticateWithToken(\n baseUrl: string,\n accountId: string,\n token: string,\n expiresAt?: number\n): Promise<AuthSession> {\n const client = new KentuckySignerClient({ baseUrl })\n\n // Get account info to retrieve addresses\n const accountInfo = await client.getAccountInfo(accountId, token)\n\n return {\n token,\n accountId,\n evmAddress: accountInfo.addresses.evm as Address,\n btcAddress: accountInfo.addresses.bitcoin,\n solAddress: accountInfo.addresses.solana,\n expiresAt: expiresAt ?? Date.now() + 3600000, // Default 1 hour if not specified\n }\n}\n\n/**\n * Register a new passkey for account creation (browser only)\n *\n * @param options - Registration options\n * @returns Registration credential with public key\n */\nexport async function registerPasskey(\n options: PasskeyRegistrationOptions\n): Promise<PasskeyCredential & { publicKey: string }> {\n if (!isWebAuthnAvailable()) {\n throw new KentuckySignerError(\n 'WebAuthn is not available in this environment',\n 'WEBAUTHN_NOT_AVAILABLE'\n )\n }\n\n // Generate a random user ID\n const userId = new Uint8Array(32)\n crypto.getRandomValues(userId)\n\n // Generate a random challenge\n const challenge = new Uint8Array(32)\n crypto.getRandomValues(challenge)\n\n const createOptions: CredentialCreationOptions = {\n publicKey: {\n challenge,\n rp: {\n name: options.rpName ?? 'Kentucky Signer',\n id: options.rpId ?? window.location.hostname,\n },\n user: {\n id: userId,\n name: options.username ?? 'user@example.com',\n displayName: options.username ?? 'User',\n },\n pubKeyCredParams: [\n { type: 'public-key', alg: -7 }, // ES256 (P-256)\n { type: 'public-key', alg: -257 }, // RS256\n ],\n authenticatorSelection: {\n authenticatorAttachment: 'platform',\n userVerification: 'preferred',\n residentKey: 'preferred',\n },\n timeout: 60000,\n attestation: 'none',\n },\n }\n\n const credential = (await navigator.credentials.create(\n createOptions\n )) as PublicKeyCredential | null\n\n if (!credential) {\n throw new KentuckySignerError(\n 'User cancelled passkey registration',\n 'USER_CANCELLED'\n )\n }\n\n const response = credential.response as AuthenticatorAttestationResponse\n\n // Extract public key from attestation object\n const publicKeyBytes = response.getPublicKey?.()\n if (!publicKeyBytes) {\n throw new KentuckySignerError(\n 'Failed to get public key from credential',\n 'PUBLIC_KEY_ERROR'\n )\n }\n\n return {\n credentialId: base64UrlEncode(new Uint8Array(credential.rawId)),\n clientDataJSON: base64UrlEncode(new Uint8Array(response.clientDataJSON)),\n authenticatorData: base64UrlEncode(new Uint8Array(response.getAuthenticatorData())),\n signature: '', // Not applicable for registration\n publicKey: base64UrlEncode(new Uint8Array(publicKeyBytes)),\n }\n}\n\n/**\n * Check if a session is still valid\n *\n * @param session - Session to check\n * @param bufferMs - Buffer time before expiration (default 60 seconds)\n * @returns True if session is valid\n */\nexport function isSessionValid(session: AuthSession, bufferMs: number = 60000): boolean {\n return Date.now() + bufferMs < session.expiresAt\n}\n\n/**\n * Refresh a session if needed\n *\n * @param session - Current session\n * @param baseUrl - Kentucky Signer API URL\n * @param bufferMs - Buffer time before expiration (default 60 seconds)\n * @returns Updated session (or original if still valid)\n */\nexport async function refreshSessionIfNeeded(\n session: AuthSession,\n baseUrl: string,\n bufferMs: number = 60000\n): Promise<AuthSession> {\n if (isSessionValid(session, bufferMs)) {\n return session\n }\n\n const client = new KentuckySignerClient({ baseUrl })\n const authResponse = await client.refreshToken(session.token)\n\n return {\n ...session,\n token: authResponse.token,\n expiresAt: Date.now() + authResponse.expires_in * 1000,\n }\n}\n\n/**\n * Authenticate with password (works in browser and Node.js)\n *\n * @param options - Password authentication options\n * @returns Authenticated session\n *\n * @example\n * ```typescript\n * const session = await authenticateWithPassword({\n * baseUrl: 'https://signer.example.com',\n * accountId: '0123456789abcdef...',\n * password: 'your-secure-password',\n * })\n * ```\n */\nexport async function authenticateWithPassword(\n options: PasswordAuthOptions\n): Promise<AuthSession> {\n const client = new KentuckySignerClient({ baseUrl: options.baseUrl })\n\n // Authenticate with password\n const authResponse = await client.authenticatePassword({\n account_id: options.accountId,\n password: options.password,\n })\n\n // Get account info to retrieve addresses\n const accountInfo = await client.getAccountInfo(\n options.accountId,\n authResponse.token\n )\n\n // Build and return session\n const expiresAt = Date.now() + authResponse.expires_in * 1000\n\n return {\n token: authResponse.token,\n accountId: options.accountId,\n evmAddress: accountInfo.addresses.evm as Address,\n btcAddress: accountInfo.addresses.bitcoin,\n solAddress: accountInfo.addresses.solana,\n expiresAt,\n }\n}\n\n/**\n * Create a new account with password authentication (works in browser and Node.js)\n *\n * @param options - Account creation options with password\n * @returns Account creation response with account ID and addresses\n *\n * @example\n * ```typescript\n * const account = await createAccountWithPassword({\n * baseUrl: 'https://signer.example.com',\n * password: 'your-secure-password',\n * confirmation: 'your-secure-password',\n * })\n * console.log('Account ID:', account.account_id)\n * console.log('EVM Address:', account.addresses.evm)\n * ```\n */\nexport async function createAccountWithPassword(\n options: PasswordAccountCreationOptions\n): Promise<AccountCreationResponse> {\n // Validate password matches confirmation\n if (options.password !== options.confirmation) {\n throw new KentuckySignerError(\n 'Password and confirmation do not match',\n 'PASSWORD_MISMATCH'\n )\n }\n\n // Validate password length\n if (options.password.length < 8 || options.password.length > 128) {\n throw new KentuckySignerError(\n 'Password must be 8-128 characters',\n 'INVALID_PASSWORD'\n )\n }\n\n const client = new KentuckySignerClient({ baseUrl: options.baseUrl })\n\n return client.createAccountWithPassword({\n password: options.password,\n confirmation: options.confirmation,\n })\n}\n","import {\n type Account,\n type Address,\n type Chain,\n type Hex,\n type LocalAccount,\n type SignableMessage,\n type TransactionSerializable,\n type TypedData,\n type TypedDataDefinition,\n hashMessage,\n hashTypedData,\n keccak256,\n serializeTransaction,\n toHex,\n concat,\n numberToHex,\n} from 'viem'\nimport { toAccount } from 'viem/accounts'\nimport type { AuthSession, KentuckySignerConfig } from './types'\nimport { KentuckySignerClient, KentuckySignerError } from './client'\n\n/**\n * Options for creating a Kentucky Signer account\n */\nexport interface KentuckySignerAccountOptions {\n /** Kentucky Signer configuration */\n config: KentuckySignerConfig\n /** Authenticated session */\n session: AuthSession\n /** Default chain ID for signing (can be overridden per-transaction) */\n defaultChainId?: number\n /** Callback when session needs refresh */\n onSessionExpired?: () => Promise<AuthSession>\n}\n\n/**\n * Extended account type with Kentucky Signer specific properties\n */\nexport interface KentuckySignerAccount extends LocalAccount<'kentuckySigner'> {\n /** Account ID */\n accountId: string\n /** Current session */\n session: AuthSession\n /** Update the session (e.g., after refresh) */\n updateSession: (session: AuthSession) => void\n}\n\n/**\n * Create a custom Viem account backed by Kentucky Signer\n *\n * This account implementation uses the Kentucky Signer API to sign\n * transactions, messages, and typed data using passkey authentication.\n *\n * @param options - Account options\n * @returns Viem-compatible account\n *\n * @example\n * ```typescript\n * const account = createKentuckySignerAccount({\n * config: {\n * baseUrl: 'https://signer.example.com',\n * accountId: '0x...',\n * },\n * session: authenticatedSession,\n * defaultChainId: 1,\n * })\n *\n * const walletClient = createWalletClient({\n * account,\n * chain: mainnet,\n * transport: http(),\n * })\n *\n * const hash = await walletClient.sendTransaction({\n * to: '0x...',\n * value: parseEther('0.1'),\n * })\n * ```\n */\nexport function createKentuckySignerAccount(\n options: KentuckySignerAccountOptions\n): KentuckySignerAccount {\n const { config, defaultChainId = 1, onSessionExpired } = options\n let session = options.session\n\n const client = new KentuckySignerClient({ baseUrl: config.baseUrl })\n\n /**\n * Get current token, refreshing if needed\n */\n async function getToken(): Promise<string> {\n // Check if session is about to expire (within 60 seconds)\n if (Date.now() + 60000 >= session.expiresAt) {\n if (onSessionExpired) {\n session = await onSessionExpired()\n } else {\n throw new KentuckySignerError(\n 'Session expired',\n 'SESSION_EXPIRED',\n 'Please re-authenticate with your passkey'\n )\n }\n }\n return session.token\n }\n\n /**\n * Sign a hash using Kentucky Signer\n */\n async function signHash(hash: Hex, chainId: number): Promise<Hex> {\n const token = await getToken()\n const response = await client.signEvmTransaction(\n { tx_hash: hash, chain_id: chainId },\n token\n )\n return response.signature.full\n }\n\n /**\n * Parse signature components from full signature\n */\n function parseSignature(signature: Hex): { r: Hex; s: Hex; v: bigint } {\n // Signature is 65 bytes: r (32) + s (32) + v (1)\n const r = `0x${signature.slice(2, 66)}` as Hex\n const s = `0x${signature.slice(66, 130)}` as Hex\n const v = BigInt(`0x${signature.slice(130, 132)}`)\n return { r, s, v }\n }\n\n const account = toAccount({\n address: session.evmAddress,\n\n /**\n * Sign a message\n *\n * Supports string messages, hex messages, and raw bytes.\n */\n async signMessage({ message }: { message: SignableMessage }): Promise<Hex> {\n const messageHash = hashMessage(message)\n return signHash(messageHash, defaultChainId)\n },\n\n /**\n * Sign a transaction\n *\n * Serializes the transaction, hashes it, signs via Kentucky Signer,\n * and returns the signed serialized transaction.\n */\n async signTransaction(\n transaction: TransactionSerializable\n ): Promise<Hex> {\n // Get chain ID from transaction or use default\n const chainId = transaction.chainId ?? defaultChainId\n\n // Serialize unsigned transaction\n const serializedUnsigned = serializeTransaction(transaction)\n\n // Hash the serialized transaction\n const txHash = keccak256(serializedUnsigned)\n\n // Sign the hash\n const signature = await signHash(txHash, chainId)\n\n // Parse signature components\n const { r, s, v } = parseSignature(signature)\n\n // For EIP-1559 and EIP-2930 transactions, v is 0 or 1\n // For legacy transactions, v is chainId * 2 + 35 + recovery\n let yParity: number\n if (\n transaction.type === 'eip1559' ||\n transaction.type === 'eip2930' ||\n transaction.type === 'eip4844' ||\n transaction.type === 'eip7702'\n ) {\n yParity = Number(v) - 27 // Convert from 27/28 to 0/1\n } else {\n // Legacy transaction - v already includes chain ID\n yParity = Number(v)\n }\n\n // Serialize with signature\n const serializedSigned = serializeTransaction(transaction, {\n r,\n s,\n v: BigInt(yParity),\n yParity,\n } as any)\n\n return serializedSigned\n },\n\n /**\n * Sign typed data (EIP-712)\n */\n async signTypedData<\n const TTypedData extends TypedData | Record<string, unknown>,\n TPrimaryType extends keyof TTypedData | 'EIP712Domain' = keyof TTypedData\n >(\n typedData: TypedDataDefinition<TTypedData, TPrimaryType>\n ): Promise<Hex> {\n const hash = hashTypedData(typedData)\n return signHash(hash, defaultChainId)\n },\n }) as KentuckySignerAccount\n\n // Add Kentucky Signer specific properties\n account.source = 'kentuckySigner'\n account.accountId = config.accountId\n account.session = session\n account.updateSession = (newSession: AuthSession) => {\n session = newSession\n // Update address if changed (shouldn't happen but handle it)\n if (newSession.evmAddress !== account.address) {\n ;(account as any).address = newSession.evmAddress\n }\n }\n\n return account\n}\n\n/**\n * Create a Kentucky Signer account for server-side use\n *\n * Convenience function for Node.js environments where you have\n * a pre-existing JWT token.\n *\n * @param baseUrl - Kentucky Signer API URL\n * @param accountId - Account ID\n * @param token - JWT token\n * @param evmAddress - EVM address for the account\n * @param chainId - Default chain ID\n * @returns Kentucky Signer account\n */\nexport function createServerAccount(\n baseUrl: string,\n accountId: string,\n token: string,\n evmAddress: Address,\n chainId: number = 1\n): KentuckySignerAccount {\n const session: AuthSession = {\n token,\n accountId,\n evmAddress,\n expiresAt: Date.now() + 3600000, // 1 hour default\n }\n\n return createKentuckySignerAccount({\n config: { baseUrl, accountId },\n session,\n defaultChainId: chainId,\n })\n}\n","import { useMemo, useCallback, useState } from 'react'\nimport { createWalletClient, http, type Chain, type WalletClient, type Transport } from 'viem'\nimport { useKentuckySignerContext } from './context'\nimport type { KentuckySignerAccount } from '../account'\n\n/**\n * Hook to access Kentucky Signer authentication state\n *\n * @returns Authentication state and actions\n *\n * @example\n * ```tsx\n * function LoginButton() {\n * const { isAuthenticated, isAuthenticating, authenticate, logout } = useKentuckySigner()\n *\n * if (isAuthenticated) {\n * return <button onClick={logout}>Logout</button>\n * }\n *\n * return (\n * <button onClick={() => authenticate('account_id')} disabled={isAuthenticating}>\n * {isAuthenticating ? 'Authenticating...' : 'Login with Passkey'}\n * </button>\n * )\n * }\n * ```\n */\nexport function useKentuckySigner() {\n const context = useKentuckySignerContext()\n\n return {\n isAuthenticated: context.isAuthenticated,\n isAuthenticating: context.isAuthenticating,\n session: context.session,\n account: context.account,\n error: context.error,\n authenticate: context.authenticate,\n logout: context.logout,\n refreshSession: context.refreshSession,\n clearError: context.clearError,\n }\n}\n\n/**\n * Hook to access the Kentucky Signer account\n *\n * @returns Account or null if not authenticated\n *\n * @example\n * ```tsx\n * function AccountInfo() {\n * const account = useKentuckySignerAccount()\n *\n * if (!account) return <div>Not connected</div>\n *\n * return <div>Connected: {account.address}</div>\n * }\n * ```\n */\nexport function useKentuckySignerAccount(): KentuckySignerAccount | null {\n const { account } = useKentuckySignerContext()\n return account\n}\n\n/**\n * Options for useWalletClient hook\n */\nexport interface UseWalletClientOptions {\n /** Viem chain configuration */\n chain: Chain\n /** RPC URL (defaults to chain's default RPC) */\n rpcUrl?: string\n}\n\n/**\n * Hook to create a Viem WalletClient with the Kentucky Signer account\n *\n * @param options - Wallet client options\n * @returns Wallet client or null if not authenticated\n *\n * @example\n * ```tsx\n * import { mainnet } from 'viem/chains'\n *\n * function SendTransaction() {\n * const walletClient = useWalletClient({\n * chain: mainnet,\n * rpcUrl: 'https://eth-mainnet.g.alchemy.com/v2/...'\n * })\n *\n * async function send() {\n * if (!walletClient) return\n *\n * const hash = await walletClient.sendTransaction({\n * to: '0x...',\n * value: parseEther('0.1')\n * })\n * console.log('Transaction hash:', hash)\n * }\n *\n * return <button onClick={send} disabled={!walletClient}>Send</button>\n * }\n * ```\n */\nexport function useWalletClient(\n options: UseWalletClientOptions\n): WalletClient<Transport, Chain, KentuckySignerAccount> | null {\n const { account } = useKentuckySignerContext()\n const { chain, rpcUrl } = options\n\n return useMemo(() => {\n if (!account) return null\n\n return createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n }) as WalletClient<Transport, Chain, KentuckySignerAccount>\n }, [account, chain, rpcUrl])\n}\n\n/**\n * Hook for passkey authentication flow\n *\n * Provides state management for the authentication process.\n *\n * @returns Authentication state and trigger function\n *\n * @example\n * ```tsx\n * function PasskeyLogin() {\n * const { login, isLoading, error } = usePasskeyAuth()\n *\n * return (\n * <div>\n * <input\n * placeholder=\"Account ID\"\n * onChange={(e) => setAccountId(e.target.value)}\n * />\n * <button onClick={() => login(accountId)} disabled={isLoading}>\n * {isLoading ? 'Authenticating...' : 'Login'}\n * </button>\n * {error && <div className=\"error\">{error.message}</div>}\n * </div>\n * )\n * }\n * ```\n */\nexport function usePasskeyAuth() {\n const { authenticate, isAuthenticating, error, clearError } =\n useKentuckySignerContext()\n\n const login = useCallback(\n async (accountId: string, options?: { rpId?: string }) => {\n clearError()\n await authenticate(accountId, options)\n },\n [authenticate, clearError]\n )\n\n return {\n login,\n isLoading: isAuthenticating,\n error,\n clearError,\n }\n}\n\n/**\n * Hook for signing messages\n *\n * @returns Sign function and loading state\n *\n * @example\n * ```tsx\n * function SignMessage() {\n * const { signMessage, isLoading } = useSignMessage()\n * const [signature, setSignature] = useState('')\n *\n * async function sign() {\n * const sig = await signMessage('Hello, World!')\n * setSignature(sig)\n * }\n *\n * return (\n * <div>\n * <button onClick={sign} disabled={isLoading}>Sign Message</button>\n * {signature && <div>Signature: {signature}</div>}\n * </div>\n * )\n * }\n * ```\n */\nexport function useSignMessage() {\n const { account } = useKentuckySignerContext()\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n const signMessage = useCallback(\n async (message: string): Promise<string> => {\n if (!account) {\n throw new Error('Not authenticated')\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const signature = await account.signMessage({ message })\n return signature\n } catch (err) {\n setError(err as Error)\n throw err\n } finally {\n setIsLoading(false)\n }\n },\n [account]\n )\n\n return {\n signMessage,\n isLoading,\n error,\n isAvailable: !!account,\n }\n}\n\n/**\n * Hook for signing typed data (EIP-712)\n *\n * @returns Sign function and loading state\n */\nexport function useSignTypedData() {\n const { account } = useKentuckySignerContext()\n const [isLoading, setIsLoading] = useState(false)\n const [error, setError] = useState<Error | null>(null)\n\n const signTypedData = useCallback(\n async (typedData: Parameters<NonNullable<typeof account>['signTypedData']>[0]): Promise<string> => {\n if (!account) {\n throw new Error('Not authenticated')\n }\n\n setIsLoading(true)\n setError(null)\n\n try {\n const signature = await account.signTypedData(typedData)\n return signature\n } catch (err) {\n setError(err as Error)\n throw err\n } finally {\n setIsLoading(false)\n }\n },\n [account]\n )\n\n return {\n signTypedData,\n isLoading,\n error,\n isAvailable: !!account,\n }\n}\n\n/**\n * Hook to check if Kentucky Signer is ready\n *\n * @returns Whether the signer is authenticated and ready\n */\nexport function useIsReady(): boolean {\n const { isAuthenticated, account } = useKentuckySignerContext()\n return isAuthenticated && account !== null\n}\n\n/**\n * Hook to get the connected address\n *\n * @returns EVM address or undefined if not connected\n */\nexport function useAddress(): `0x${string}` | undefined {\n const { account } = useKentuckySignerContext()\n return account?.address\n}\n"],"mappings":"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","names":["account","import_react","import_viem"]}