@cedros/login-react 0.0.37 → 0.0.39

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.
Files changed (108) hide show
  1. package/dist/{AuthenticationSettings-CsPbxwP7.js → AuthenticationSettings-BF_7Ea6Z.js} +1 -1
  2. package/dist/{AuthenticationSettings-CsPbxwP7.js.map → AuthenticationSettings-BF_7Ea6Z.js.map} +1 -1
  3. package/dist/{AuthenticationSettings-C-aYDXNH.cjs → AuthenticationSettings-BMDrCVSf.cjs} +1 -1
  4. package/dist/{AuthenticationSettings-C-aYDXNH.cjs.map → AuthenticationSettings-BMDrCVSf.cjs.map} +1 -1
  5. package/dist/{AuthenticationSettings-DIVk0OP8.js → AuthenticationSettings-DUXpyiJ5.js} +39 -39
  6. package/dist/{AuthenticationSettings-DIVk0OP8.js.map → AuthenticationSettings-DUXpyiJ5.js.map} +1 -1
  7. package/dist/{AuthenticationSettings-CoTic-d_.cjs → AuthenticationSettings-Dk1LX0CK.cjs} +1 -1
  8. package/dist/{AuthenticationSettings-CoTic-d_.cjs.map → AuthenticationSettings-Dk1LX0CK.cjs.map} +1 -1
  9. package/dist/{AutosaveStatus-DGNI4lXn.cjs → AutosaveStatus-BKsCIvPj.cjs} +1 -1
  10. package/dist/AutosaveStatus-BKsCIvPj.cjs.map +1 -0
  11. package/dist/{AutosaveStatus-f-jw25Ay.js → AutosaveStatus-CSZsp6w7.js} +221 -186
  12. package/dist/AutosaveStatus-CSZsp6w7.js.map +1 -0
  13. package/dist/{CreditSystemSettings-C6ed3yp7.js → CreditSystemSettings-Buu7Y-7I.js} +1 -1
  14. package/dist/{CreditSystemSettings-C6ed3yp7.js.map → CreditSystemSettings-Buu7Y-7I.js.map} +1 -1
  15. package/dist/{CreditSystemSettings-DM9ep1TF.cjs → CreditSystemSettings-C2HkyMXy.cjs} +1 -1
  16. package/dist/{CreditSystemSettings-DM9ep1TF.cjs.map → CreditSystemSettings-C2HkyMXy.cjs.map} +1 -1
  17. package/dist/{CreditSystemSettings-BNkvsgsk.cjs → CreditSystemSettings-CLImarX-.cjs} +1 -1
  18. package/dist/{CreditSystemSettings-BNkvsgsk.cjs.map → CreditSystemSettings-CLImarX-.cjs.map} +1 -1
  19. package/dist/{CreditSystemSettings-uinhzoha.js → CreditSystemSettings-Cj21_Ug8.js} +1 -1
  20. package/dist/{CreditSystemSettings-uinhzoha.js.map → CreditSystemSettings-Cj21_Ug8.js.map} +1 -1
  21. package/dist/EmailRegisterForm-CNjYrqU6.cjs +1 -0
  22. package/dist/EmailRegisterForm-CNjYrqU6.cjs.map +1 -0
  23. package/dist/EmailRegisterForm-D2VaJouj.js +750 -0
  24. package/dist/EmailRegisterForm-D2VaJouj.js.map +1 -0
  25. package/dist/{EmailSettings-BC0f1PCI.cjs → EmailSettings-9sdEAONl.cjs} +1 -1
  26. package/dist/{EmailSettings-BC0f1PCI.cjs.map → EmailSettings-9sdEAONl.cjs.map} +1 -1
  27. package/dist/{EmailSettings-BKuXy8sc.js → EmailSettings-CmxxnrA9.js} +1 -1
  28. package/dist/{EmailSettings-BKuXy8sc.js.map → EmailSettings-CmxxnrA9.js.map} +1 -1
  29. package/dist/{EmailSettings-BAuQtEfM.js → EmailSettings-DRfOF0Sf.js} +1 -1
  30. package/dist/{EmailSettings-BAuQtEfM.js.map → EmailSettings-DRfOF0Sf.js.map} +1 -1
  31. package/dist/{EmailSettings-BF5EiPl9.cjs → EmailSettings-eLlzzI5D.cjs} +1 -1
  32. package/dist/{EmailSettings-BF5EiPl9.cjs.map → EmailSettings-eLlzzI5D.cjs.map} +1 -1
  33. package/dist/{EmbeddedWalletSettings-CJY39UZN.cjs → EmbeddedWalletSettings-BuLN_Uqc.cjs} +1 -1
  34. package/dist/{EmbeddedWalletSettings-CJY39UZN.cjs.map → EmbeddedWalletSettings-BuLN_Uqc.cjs.map} +1 -1
  35. package/dist/{EmbeddedWalletSettings-C27X9He2.js → EmbeddedWalletSettings-CHkkCjyR.js} +1 -1
  36. package/dist/{EmbeddedWalletSettings-C27X9He2.js.map → EmbeddedWalletSettings-CHkkCjyR.js.map} +1 -1
  37. package/dist/EmbeddedWalletSettings-DGq-kXbw.cjs +1 -0
  38. package/dist/EmbeddedWalletSettings-DGq-kXbw.cjs.map +1 -0
  39. package/dist/{EmbeddedWalletSettings-Dmi-EQ7W.js → EmbeddedWalletSettings-M-D5N0eY.js} +5 -5
  40. package/dist/EmbeddedWalletSettings-M-D5N0eY.js.map +1 -0
  41. package/dist/{GoogleLoginButton-BDCbxoCB.cjs → GoogleLoginButton-JtRViYWS.cjs} +1 -1
  42. package/dist/GoogleLoginButton-JtRViYWS.cjs.map +1 -0
  43. package/dist/{GoogleLoginButton-6ip-vudk.js → GoogleLoginButton-qf4A_A3G.js} +6 -6
  44. package/dist/GoogleLoginButton-qf4A_A3G.js.map +1 -0
  45. package/dist/{ServerSettings-CKfiLfXi.cjs → ServerSettings-CMmH5pZv.cjs} +1 -1
  46. package/dist/{ServerSettings-CKfiLfXi.cjs.map → ServerSettings-CMmH5pZv.cjs.map} +1 -1
  47. package/dist/{ServerSettings-CZfBdMxG.js → ServerSettings-DQemMrNv.js} +1 -1
  48. package/dist/{ServerSettings-CZfBdMxG.js.map → ServerSettings-DQemMrNv.js.map} +1 -1
  49. package/dist/{ServerSettings-rHrVN8O8.cjs → ServerSettings-DfimU7ay.cjs} +1 -1
  50. package/dist/{ServerSettings-rHrVN8O8.cjs.map → ServerSettings-DfimU7ay.cjs.map} +1 -1
  51. package/dist/{ServerSettings-BT9weFPz.js → ServerSettings-qxi8aZO7.js} +1 -1
  52. package/dist/{ServerSettings-BT9weFPz.js.map → ServerSettings-qxi8aZO7.js.map} +1 -1
  53. package/dist/{WebhookSettings-DXjnq-c7.cjs → WebhookSettings-0sgWRI3U.cjs} +1 -1
  54. package/dist/{WebhookSettings-DXjnq-c7.cjs.map → WebhookSettings-0sgWRI3U.cjs.map} +1 -1
  55. package/dist/{WebhookSettings-Bgld6D_T.js → WebhookSettings-8QAqvkkO.js} +1 -1
  56. package/dist/{WebhookSettings-Bgld6D_T.js.map → WebhookSettings-8QAqvkkO.js.map} +1 -1
  57. package/dist/{WebhookSettings-DnLk97Mr.cjs → WebhookSettings-B6Y3Tnjv.cjs} +1 -1
  58. package/dist/{WebhookSettings-DnLk97Mr.cjs.map → WebhookSettings-B6Y3Tnjv.cjs.map} +1 -1
  59. package/dist/{WebhookSettings-ufiGTmbG.js → WebhookSettings-B8hAwhZ2.js} +1 -1
  60. package/dist/{WebhookSettings-ufiGTmbG.js.map → WebhookSettings-B8hAwhZ2.js.map} +1 -1
  61. package/dist/admin-only.cjs +1 -1
  62. package/dist/admin-only.js +1 -1
  63. package/dist/email-only.cjs +1 -1
  64. package/dist/email-only.d.ts +3 -2
  65. package/dist/email-only.js +2 -2
  66. package/dist/google-only.cjs +1 -1
  67. package/dist/google-only.d.ts +5 -4
  68. package/dist/google-only.js +2 -2
  69. package/dist/index.cjs +13 -13
  70. package/dist/index.cjs.map +1 -1
  71. package/dist/index.d.ts +98 -7
  72. package/dist/index.js +8052 -5962
  73. package/dist/index.js.map +1 -1
  74. package/dist/login-react.css +1 -1
  75. package/dist/{plugin-Xca67fp7.cjs → plugin-CUxpAjL-.cjs} +1 -1
  76. package/dist/{plugin-Xca67fp7.cjs.map → plugin-CUxpAjL-.cjs.map} +1 -1
  77. package/dist/{plugin-BbExid4E.js → plugin-C_NDZ2-D.js} +5 -5
  78. package/dist/{plugin-BbExid4E.js.map → plugin-C_NDZ2-D.js.map} +1 -1
  79. package/dist/solana-only.cjs +1 -1
  80. package/dist/solana-only.d.ts +3 -2
  81. package/dist/solana-only.js +1 -1
  82. package/dist/{useAuth-CVLv2oKA.js → useAuth-C-Vw-ggy.js} +743 -803
  83. package/dist/useAuth-C-Vw-ggy.js.map +1 -0
  84. package/dist/useAuth-U5CYsHEU.cjs +1 -0
  85. package/dist/useAuth-U5CYsHEU.cjs.map +1 -0
  86. package/package.json +4 -1
  87. package/dist/AutosaveStatus-DGNI4lXn.cjs.map +0 -1
  88. package/dist/AutosaveStatus-f-jw25Ay.js.map +0 -1
  89. package/dist/EmailRegisterForm-B_TiJkD6.cjs +0 -1
  90. package/dist/EmailRegisterForm-B_TiJkD6.cjs.map +0 -1
  91. package/dist/EmailRegisterForm-CCEuQA-w.js +0 -773
  92. package/dist/EmailRegisterForm-CCEuQA-w.js.map +0 -1
  93. package/dist/EmbeddedWalletSettings-BRjt2PAj.cjs +0 -1
  94. package/dist/EmbeddedWalletSettings-BRjt2PAj.cjs.map +0 -1
  95. package/dist/EmbeddedWalletSettings-Dmi-EQ7W.js.map +0 -1
  96. package/dist/GoogleLoginButton-6ip-vudk.js.map +0 -1
  97. package/dist/GoogleLoginButton-BDCbxoCB.cjs.map +0 -1
  98. package/dist/shamir-DBpHm7WN.cjs +0 -1
  99. package/dist/shamir-DBpHm7WN.cjs.map +0 -1
  100. package/dist/shamir-R8ddesFt.js +0 -1940
  101. package/dist/shamir-R8ddesFt.js.map +0 -1
  102. package/dist/silentWalletEnroll-Dp1GTeNr.js +0 -41
  103. package/dist/silentWalletEnroll-Dp1GTeNr.js.map +0 -1
  104. package/dist/silentWalletEnroll-HPvsbd2J.cjs +0 -1
  105. package/dist/silentWalletEnroll-HPvsbd2J.cjs.map +0 -1
  106. package/dist/useAuth-CVLv2oKA.js.map +0 -1
  107. package/dist/useAuth-XZaciuLg.cjs +0 -1
  108. package/dist/useAuth-XZaciuLg.cjs.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmailRegisterForm-CCEuQA-w.js","sources":["../src/hooks/useRateLimiter.ts","../src/hooks/useEmailAuth.ts","../src/components/email/PasswordInput.tsx","../src/hooks/useTotpVerify.ts","../src/components/totp/OtpInput.tsx","../src/components/totp/TotpVerify.tsx","../src/components/email/EmailLoginForm.tsx","../src/components/email/EmailRegisterForm.tsx"],"sourcesContent":["import { useRef, useCallback, useState, useEffect } from 'react';\n\nexport interface UseRateLimiterOptions {\n /** Maximum number of attempts allowed within the window */\n maxAttempts?: number;\n /** Time window in milliseconds */\n windowMs?: number;\n /**\n * UI-25: Set to true to enable the 1s countdown interval for displaying\n * time-until-reset in the UI. When false (default), no interval is started,\n * saving resources for callers that don't display a countdown.\n */\n showCountdown?: boolean;\n}\n\nexport interface UseRateLimiterReturn {\n /**\n * Check if an action is allowed. Throws an error if rate limited.\n * Call this before performing the action.\n */\n checkLimit: () => void;\n /**\n * Check if an action is allowed without throwing.\n * Returns true if allowed, false if rate limited.\n */\n isAllowed: () => boolean;\n /**\n * Get remaining attempts in current window\n */\n getRemainingAttempts: () => number;\n /**\n * Get time until rate limit resets (in ms)\n */\n getTimeUntilReset: () => number;\n /**\n * Reset the rate limiter (e.g., after successful action)\n */\n reset: () => void;\n}\n\n/**\n * Rate limiting hook to prevent excessive API calls from the client.\n *\n * @param options - Rate limiter configuration\n * @returns Rate limiter functions\n *\n * @example\n * ```tsx\n * function LoginForm() {\n * const { checkLimit, getRemainingAttempts } = useRateLimiter({\n * maxAttempts: 5,\n * windowMs: 60000, // 1 minute\n * });\n *\n * const handleLogin = async () => {\n * try {\n * checkLimit(); // Throws if rate limited\n * await login(email, password);\n * } catch (err) {\n * if (err.message.includes('Too many attempts')) {\n * // Show rate limit message\n * }\n * }\n * };\n * }\n * ```\n */\nexport function useRateLimiter(options: UseRateLimiterOptions = {}): UseRateLimiterReturn {\n const { maxAttempts = 5, windowMs = 60000, showCountdown = false } = options;\n\n // Store timestamps of recent attempts\n const attemptsRef = useRef<number[]>([]);\n const [hasAttempts, setHasAttempts] = useState(false);\n const [, setTick] = useState(0);\n\n const bump = useCallback(() => {\n setTick((value) => value + 1);\n }, []);\n\n /**\n * Remove expired attempts from the tracking array (no state update).\n * Safe to call during render for getter functions.\n */\n const cleanupAttemptsArray = useCallback(() => {\n const now = Date.now();\n attemptsRef.current = attemptsRef.current.filter((timestamp) => now - timestamp < windowMs);\n }, [windowMs]);\n\n /**\n * Remove expired attempts AND update hasAttempts state.\n * M-04: Use functional setState to avoid hasAttempts dependency cascade.\n * Only call from event handlers and effects, NOT during render.\n */\n const cleanupExpiredAttempts = useCallback(() => {\n cleanupAttemptsArray();\n // Functional update avoids dependency on hasAttempts\n setHasAttempts((current) => (attemptsRef.current.length === 0 && current ? false : current));\n }, [cleanupAttemptsArray]);\n\n /**\n * Get the number of remaining attempts\n * Uses cleanupAttemptsArray (no state) so safe to call during render.\n */\n const getRemainingAttempts = useCallback((): number => {\n cleanupAttemptsArray();\n return Math.max(0, maxAttempts - attemptsRef.current.length);\n }, [cleanupAttemptsArray, maxAttempts]);\n\n /**\n * Get time until rate limit resets\n * Uses cleanupAttemptsArray (no state) so safe to call during render.\n */\n const getTimeUntilReset = useCallback((): number => {\n cleanupAttemptsArray();\n if (attemptsRef.current.length === 0) {\n return 0;\n }\n const oldestAttempt = attemptsRef.current[0];\n const resetTime = oldestAttempt + windowMs;\n return Math.max(0, resetTime - Date.now());\n }, [cleanupAttemptsArray, windowMs]);\n\n /**\n * Check if an action is allowed without throwing\n * Uses cleanupAttemptsArray (no state) so safe to call during render.\n */\n const isAllowed = useCallback((): boolean => {\n cleanupAttemptsArray();\n return attemptsRef.current.length < maxAttempts;\n }, [cleanupAttemptsArray, maxAttempts]);\n\n /**\n * Check rate limit and throw if exceeded\n */\n const checkLimit = useCallback((): void => {\n cleanupExpiredAttempts();\n\n if (attemptsRef.current.length >= maxAttempts) {\n const waitTime = getTimeUntilReset();\n const waitSeconds = Math.ceil(waitTime / 1000);\n throw new Error(\n `Too many attempts. Please wait ${waitSeconds} second${waitSeconds === 1 ? '' : 's'} before trying again.`\n );\n }\n\n // Record this attempt\n attemptsRef.current.push(Date.now());\n // M-04: Functional update avoids hasAttempts dependency\n setHasAttempts((current) => (current ? current : true));\n bump();\n }, [cleanupExpiredAttempts, maxAttempts, getTimeUntilReset, bump]);\n\n /**\n * Reset the rate limiter\n */\n const reset = useCallback((): void => {\n attemptsRef.current = [];\n // M-04: Functional update avoids hasAttempts dependency\n setHasAttempts((current) => (current ? false : current));\n bump();\n }, [bump]);\n\n // UI-25: Only start the 1s interval when the caller opts into countdown display.\n // This avoids a tick firing every second for all callers that don't show a countdown.\n useEffect(() => {\n if (!hasAttempts || !showCountdown) return;\n const intervalId = window.setInterval(() => {\n cleanupExpiredAttempts();\n bump();\n }, 1000);\n return () => {\n window.clearInterval(intervalId);\n };\n }, [hasAttempts, showCountdown, bump, cleanupExpiredAttempts]);\n\n return {\n checkLimit,\n isAllowed,\n getRemainingAttempts,\n getTimeUntilReset,\n reset,\n };\n}\n","import { useState, useCallback, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport { validateEmail } from '../utils/validation';\nimport { useRateLimiter } from './useRateLimiter';\nimport type { AuthResponse, AuthError } from '../types';\nimport type { MfaRequiredResponse } from '../types';\n\nfunction isMfaRequiredResponse(\n response: AuthResponse | MfaRequiredResponse\n): response is MfaRequiredResponse {\n return 'mfaRequired' in response && response.mfaRequired === true;\n}\n\n/** Result when MFA verification is required */\nexport interface MfaRequiredResult {\n mfaRequired: true;\n mfaToken: string;\n email: string;\n userId: string;\n}\n\n/** Result of successful login (no TOTP required or after TOTP verification) */\nexport interface LoginSuccessResult {\n mfaRequired: false;\n response: AuthResponse;\n}\n\n/** Union type for login result */\nexport type LoginResult = MfaRequiredResult | LoginSuccessResult;\n\nexport interface UseEmailAuthReturn {\n /** Login - may return mfaRequired if 2FA is enabled */\n login: (email: string, password: string) => Promise<LoginResult>;\n register: (email: string, password: string, name?: string) => Promise<AuthResponse>;\n isLoading: boolean;\n error: AuthError | null;\n clearError: () => void;\n /**\n * Number of remaining login attempts before rate limiting.\n *\n * M-10: Snapshot Behavior\n * This value is a point-in-time snapshot computed at render time.\n * It may be briefly stale during rapid requests or concurrent renders.\n * For UI display only - actual rate limiting is enforced inside login/register.\n */\n remainingAttempts: number;\n /**\n * Time in ms until rate limit resets (0 if not rate limited).\n *\n * M-10: Snapshot Behavior\n * This value is a point-in-time snapshot computed at render time.\n * It may be briefly stale - use for UI display, not for logic decisions.\n */\n timeUntilReset: number;\n}\n\n/**\n * Hook for email/password authentication.\n *\n * @example\n * ```tsx\n * function LoginForm() {\n * const { login, isLoading, error } = useEmailAuth();\n *\n * const handleSubmit = async (e) => {\n * e.preventDefault();\n * try {\n * await login(email, password);\n * } catch (err) {\n * // Handle error\n * }\n * };\n * }\n * ```\n */\nexport function useEmailAuth(): UseEmailAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n // Rate limiter for login attempts (5 attempts per minute)\n const {\n checkLimit,\n getRemainingAttempts,\n getTimeUntilReset,\n reset: resetRateLimit,\n } = useRateLimiter({ maxAttempts: 5, windowMs: 60000 });\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n const callbacks = config.callbacks;\n const walletEnrollmentEnabled = config.features?.walletEnrollment !== false;\n const serverUrl = config.serverUrl;\n\n const login = useCallback(\n async (email: string, password: string): Promise<LoginResult> => {\n // Validate email format before API call\n if (!validateEmail(email)) {\n const validationError: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Please enter a valid email address',\n };\n setError(validationError);\n throw validationError;\n }\n\n // UI-7: Rate limit is checked BEFORE API call intentionally.\n // This prevents brute force attacks by limiting attempt frequency,\n // not just successful request frequency.\n try {\n checkLimit();\n } catch (err) {\n const rateLimitError: AuthError = {\n code: 'RATE_LIMITED',\n message: err instanceof Error ? err.message : 'Too many attempts',\n };\n setError(rateLimitError);\n throw rateLimitError;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const data = await apiClient.post<AuthResponse | MfaRequiredResponse>('/login', {\n email,\n password,\n });\n\n // Check if MFA verification is required\n if (isMfaRequiredResponse(data)) {\n return {\n mfaRequired: true,\n mfaToken: data.mfaToken,\n email,\n userId: data.userId,\n };\n }\n\n // Normal login success\n const authResponse: AuthResponse = data;\n callbacks?.onLoginSuccess?.(authResponse.user, 'email');\n _internal?.handleLoginSuccess(authResponse.user, authResponse.tokens);\n resetRateLimit(); // Reset on successful login\n return {\n mfaRequired: false,\n response: authResponse,\n };\n } catch (err) {\n const authError = handleApiError(err, 'Unable to sign in. Please try again.');\n setError(authError);\n throw authError;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient, callbacks, _internal, checkLimit, resetRateLimit]\n );\n\n const register = useCallback(\n async (email: string, password: string, name?: string): Promise<AuthResponse> => {\n // Validate email format before API call\n if (!validateEmail(email)) {\n const validationError: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Please enter a valid email address',\n };\n setError(validationError);\n throw validationError;\n }\n\n // UI-7: Rate limit is checked BEFORE API call intentionally.\n // This prevents brute force attacks by limiting attempt frequency,\n // not just successful request frequency.\n try {\n checkLimit();\n } catch (err) {\n const rateLimitError: AuthError = {\n code: 'RATE_LIMITED',\n message: err instanceof Error ? err.message : 'Too many attempts',\n };\n setError(rateLimitError);\n throw rateLimitError;\n }\n\n setIsLoading(true);\n setError(null);\n\n try {\n const data = await apiClient.post<AuthResponse>('/register', { email, password, name });\n callbacks?.onLoginSuccess?.(data.user, 'email');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n resetRateLimit(); // Reset on successful registration\n\n // Auto-enroll embedded wallet in background (don't block registration)\n // Uses password for Share A encryption. Recovery phrase can be retrieved later.\n // UI-09: In cookie mode the accessToken is absent; add a short delay to allow\n // the session cookie to be written before the enroll request is sent.\n if (walletEnrollmentEnabled) {\n const accessToken = data.tokens?.accessToken ?? '';\n const isCookieMode = !accessToken;\n const enrollDelay = isCookieMode ? 200 : 0;\n void new Promise<void>((resolve) => setTimeout(resolve, enrollDelay))\n .then(() => import('../utils/silentWalletEnroll'))\n .then(({ silentWalletEnroll }) =>\n silentWalletEnroll({\n password,\n serverUrl,\n accessToken,\n })\n )\n .then((result) => {\n if (!result.success) {\n // Log auto-enrollment failures for debugging\n console.warn('[useEmailAuth] Wallet auto-enrollment failed:', result.error);\n }\n })\n .catch((err) => {\n const message = err instanceof Error ? err.message : 'Unknown error';\n // Log enrollment errors for debugging\n console.warn('[useEmailAuth] Wallet auto-enrollment unavailable:', message);\n });\n }\n\n return data;\n } catch (err) {\n const authError = handleApiError(err, 'Unable to create your account. Please try again.');\n setError(authError);\n throw authError;\n } finally {\n setIsLoading(false);\n }\n },\n [\n apiClient,\n callbacks,\n _internal,\n checkLimit,\n resetRateLimit,\n serverUrl,\n walletEnrollmentEnabled,\n ]\n );\n\n const clearError = useCallback(() => setError(null), []);\n\n return {\n login,\n register,\n isLoading,\n error,\n clearError,\n // M-10: Point-in-time snapshots for UI display (see interface JSDoc)\n remainingAttempts: getRemainingAttempts(),\n timeUntilReset: getTimeUntilReset(),\n };\n}\n","import { useState, useId, type InputHTMLAttributes } from 'react';\nimport { validatePassword } from '../../utils/validation';\nimport type { PasswordValidation } from '../../types';\n\nexport interface PasswordInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'type'> {\n label?: string;\n /** Action element shown on the right side of the label (e.g., \"Forgot password?\" link) */\n labelAction?: React.ReactNode;\n showStrengthMeter?: boolean;\n onValidationChange?: (validation: PasswordValidation) => void;\n error?: string;\n}\n\n/**\n * Password input with visibility toggle and optional strength meter\n */\nexport function PasswordInput({\n label = 'Password',\n labelAction,\n showStrengthMeter = false,\n onValidationChange,\n error,\n className = '',\n onChange,\n value,\n ...props\n}: PasswordInputProps) {\n const [showPassword, setShowPassword] = useState(false);\n const [validation, setValidation] = useState<PasswordValidation | null>(null);\n const inputId = useId();\n\n const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n\n if (showStrengthMeter || onValidationChange) {\n const newValidation = validatePassword(newValue);\n setValidation(newValidation);\n onValidationChange?.(newValidation);\n }\n\n onChange?.(e);\n };\n\n const strengthColors = {\n weak: 'var(--cedros-destructive, #ef4444)',\n fair: 'var(--cedros-warning, #f59e0b)',\n good: 'var(--cedros-success, #22c55e)',\n strong: 'var(--cedros-success, #22c55e)',\n };\n\n return (\n <div className={`cedros-password-input ${className}`}>\n <div className=\"cedros-label-row\">\n <label htmlFor={inputId} className=\"cedros-label\">\n {label}\n </label>\n {labelAction}\n </div>\n <div className=\"cedros-password-wrapper\">\n <input\n id={inputId}\n type={showPassword ? 'text' : 'password'}\n className=\"cedros-input\"\n onChange={handleChange}\n value={value}\n aria-invalid={error ? 'true' : undefined}\n aria-describedby={error ? `${inputId}-error` : undefined}\n {...props}\n />\n <button\n type=\"button\"\n className=\"cedros-password-toggle\"\n onClick={() => setShowPassword(!showPassword)}\n aria-label={showPassword ? 'Hide password' : 'Show password'}\n aria-pressed={showPassword}\n >\n {showPassword ? (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2.5 10s3-6 7.5-6 7.5 6 7.5 6-3 6-7.5 6-7.5-6-7.5-6z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <circle cx=\"10\" cy=\"10\" r=\"2.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n <path d=\"M3 17L17 3\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n ) : (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 20 20\" fill=\"none\" aria-hidden=\"true\">\n <path\n d=\"M2.5 10s3-6 7.5-6 7.5 6 7.5 6-3 6-7.5 6-7.5-6-7.5-6z\"\n stroke=\"currentColor\"\n strokeWidth=\"1.5\"\n />\n <circle cx=\"10\" cy=\"10\" r=\"2.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" />\n </svg>\n )}\n </button>\n </div>\n\n {error && (\n <p id={`${inputId}-error`} className=\"cedros-input-error\">\n {error}\n </p>\n )}\n\n {showStrengthMeter && validation && (value as string)?.length > 0 && (\n <div className=\"cedros-password-strength\">\n <div className=\"cedros-strength-bar\">\n <div\n className=\"cedros-strength-fill\"\n style={{\n width: `${\n validation.strength === 'weak'\n ? 25\n : validation.strength === 'fair'\n ? 50\n : validation.strength === 'good'\n ? 75\n : 100\n }%`,\n backgroundColor: strengthColors[validation.strength],\n }}\n />\n </div>\n <span className=\"cedros-strength-label\">{validation.strength}</span>\n </div>\n )}\n </div>\n );\n}\n","import { useState, useCallback, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport { useRateLimiter } from './useRateLimiter';\nimport type { AuthError, AuthResponse, TotpVerifyState } from '../types';\n\nexport interface UseTotpVerifyReturn {\n /** Verification state */\n state: TotpVerifyState;\n /** Whether verification is in progress */\n isLoading: boolean;\n /** Error from the last request */\n error: AuthError | null;\n /** Verify MFA code during login */\n verifyTotp: (mfaToken: string, code: string) => Promise<AuthResponse>;\n /** Clear error state */\n clearError: () => void;\n /** Reset to initial state */\n reset: () => void;\n /** Number of remaining verification attempts before rate limiting */\n remainingAttempts: number;\n /** Time in ms until rate limit resets (0 if not rate limited) */\n timeUntilReset: number;\n}\n\n/**\n * Hook for verifying TOTP codes during the login flow.\n *\n * Used when a user has TOTP enabled and needs to provide\n * their 6-digit code after password authentication.\n *\n * @example\n * ```tsx\n * function TotpVerifyStep({ mfaToken }) {\n * const { verifyTotp, isLoading, error } = useTotpVerify();\n *\n * const handleVerify = async (code: string) => {\n * const response = await verifyTotp(mfaToken, code);\n * // User is now authenticated\n * };\n * }\n * ```\n */\nexport function useTotpVerify(): UseTotpVerifyReturn {\n const { config, _internal } = useCedrosLogin();\n const [state, setState] = useState<TotpVerifyState>('idle');\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n // Rate limiter for TOTP verification (5 attempts per 2 minutes)\n // Stricter than login to prevent brute force on short codes\n const {\n checkLimit,\n getRemainingAttempts,\n getTimeUntilReset,\n reset: resetRateLimit,\n } = useRateLimiter({ maxAttempts: 5, windowMs: 120000 });\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n const verifyTotp = useCallback(\n async (mfaToken: string, code: string): Promise<AuthResponse> => {\n // Validate code format (6 digits or recovery code)\n const isRecoveryCode =\n /^[A-Z0-9]{16}$/i.test(code) || /^[A-Z0-9]{4}(-[A-Z0-9]{4}){3}$/i.test(code);\n const isValidCode = /^\\d{6}$/.test(code) || isRecoveryCode;\n if (!isValidCode) {\n const validationError: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Please enter a valid 6-digit code or recovery code',\n };\n setError(validationError);\n throw validationError;\n }\n\n // Rate limit check before API call to prevent brute force\n try {\n checkLimit();\n } catch (err) {\n const rateLimitError: AuthError = {\n code: 'RATE_LIMITED',\n message: err instanceof Error ? err.message : 'Too many attempts',\n };\n setError(rateLimitError);\n throw rateLimitError;\n }\n\n setIsLoading(true);\n setError(null);\n setState('verifying');\n\n try {\n const response = await apiClient.post<AuthResponse>('/login/mfa', { mfaToken, code });\n\n setState('success');\n resetRateLimit(); // Reset on successful verification\n\n // Complete authentication via internal API\n if (_internal && response.user && response.tokens) {\n _internal.handleLoginSuccess(response.user, response.tokens);\n }\n\n return response;\n } catch (err) {\n const authError = handleApiError(err, 'Incorrect verification code. Please check and try again.');\n setError(authError);\n setState('error');\n throw authError;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient, _internal, checkLimit, resetRateLimit]\n );\n\n const clearError = useCallback(() => setError(null), []);\n\n const reset = useCallback(() => {\n setError(null);\n setState('idle');\n setIsLoading(false);\n }, []);\n\n return {\n state,\n isLoading,\n error,\n verifyTotp,\n clearError,\n reset,\n // Point-in-time snapshots for UI display\n remainingAttempts: getRemainingAttempts(),\n timeUntilReset: getTimeUntilReset(),\n };\n}\n","/**\n * OTP Input component (shadcn-style)\n *\n * A 6-digit input with separate boxes for each digit,\n * designed for TOTP verification codes.\n */\n\nimport { useRef, useCallback, useState, useEffect, useId } from 'react';\n\n/** Number of OTP digits */\nconst OTP_LENGTH = 6;\n\nexport interface OtpInputProps {\n /** Current value (up to 6 digits) */\n value?: string;\n /** Called when the value changes */\n onChange?: (value: string) => void;\n /** Called when all 6 digits are entered */\n onComplete?: (value: string) => void;\n /** Whether the input is disabled */\n disabled?: boolean;\n /** Error message to display */\n error?: string;\n /** Auto-focus the first input on mount */\n autoFocus?: boolean;\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * OTP input with separate boxes for each digit (shadcn pattern)\n *\n * Features:\n * - Auto-advances to next input on digit entry\n * - Backspace moves to previous input\n * - Supports paste of full code\n * - Numeric keyboard on mobile\n */\nexport function OtpInput({\n value = '',\n onChange,\n onComplete,\n disabled = false,\n error,\n autoFocus = false,\n className = '',\n}: OtpInputProps) {\n const inputRefs = useRef<(HTMLInputElement | null)[]>([]);\n const [localValue, setLocalValue] = useState(value.padEnd(OTP_LENGTH, ''));\n const id = useId();\n\n // Sync with controlled value\n useEffect(() => {\n setLocalValue(value.padEnd(OTP_LENGTH, ''));\n }, [value]);\n\n const focusInput = useCallback((index: number) => {\n if (index >= 0 && index < OTP_LENGTH) {\n inputRefs.current[index]?.focus();\n }\n }, []);\n\n const updateValue = useCallback(\n (newValue: string) => {\n const sanitized = newValue.replace(/\\D/g, '').slice(0, OTP_LENGTH);\n setLocalValue(sanitized.padEnd(OTP_LENGTH, ''));\n onChange?.(sanitized);\n\n if (sanitized.length === OTP_LENGTH) {\n onComplete?.(sanitized);\n }\n },\n [onChange, onComplete]\n );\n\n const handleChange = useCallback(\n (index: number, digit: string) => {\n if (!/^\\d?$/.test(digit)) return;\n\n const chars = localValue.split('');\n chars[index] = digit;\n const newValue = chars.join('').replace(/ /g, '');\n updateValue(newValue);\n\n // Move to next input if digit entered\n if (digit && index < OTP_LENGTH - 1) {\n focusInput(index + 1);\n }\n },\n [localValue, updateValue, focusInput]\n );\n\n const handleKeyDown = useCallback(\n (index: number, e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === 'Backspace') {\n e.preventDefault();\n const chars = localValue.split('');\n\n if (chars[index] && chars[index] !== ' ') {\n // Clear current digit\n chars[index] = ' ';\n updateValue(chars.join('').replace(/ /g, ''));\n } else if (index > 0) {\n // Move to previous and clear it\n chars[index - 1] = ' ';\n updateValue(chars.join('').replace(/ /g, ''));\n focusInput(index - 1);\n }\n } else if (e.key === 'ArrowLeft' && index > 0) {\n e.preventDefault();\n focusInput(index - 1);\n } else if (e.key === 'ArrowRight' && index < OTP_LENGTH - 1) {\n e.preventDefault();\n focusInput(index + 1);\n }\n },\n [localValue, updateValue, focusInput]\n );\n\n const handlePaste = useCallback(\n (e: React.ClipboardEvent) => {\n e.preventDefault();\n const pasted = e.clipboardData.getData('text');\n const digits = pasted.replace(/\\D/g, '').slice(0, OTP_LENGTH);\n if (digits) {\n updateValue(digits);\n // Focus the next empty slot or the last one\n focusInput(Math.min(digits.length, OTP_LENGTH - 1));\n }\n },\n [updateValue, focusInput]\n );\n\n const handleFocus = useCallback((e: React.FocusEvent<HTMLInputElement>) => {\n e.target.select();\n }, []);\n\n // Auto-focus first input\n useEffect(() => {\n if (autoFocus && !disabled) {\n inputRefs.current[0]?.focus();\n }\n }, [autoFocus, disabled]);\n\n return (\n <div className={`cedros-otp-input ${className}`}>\n <div className=\"cedros-otp-slots\" role=\"group\" aria-label=\"One-time password\">\n {Array.from({ length: OTP_LENGTH }).map((_, index) => (\n <input\n key={index}\n ref={(el) => {\n inputRefs.current[index] = el;\n }}\n id={`${id}-${index}`}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n maxLength={1}\n className={`cedros-otp-slot ${error ? 'cedros-otp-slot-error' : ''}`}\n value={localValue[index] === ' ' ? '' : localValue[index] || ''}\n onChange={(e) => handleChange(index, e.target.value)}\n onKeyDown={(e) => handleKeyDown(index, e)}\n onPaste={handlePaste}\n onFocus={handleFocus}\n disabled={disabled}\n autoComplete=\"one-time-code\"\n aria-label={`Digit ${index + 1}`}\n aria-invalid={error ? 'true' : undefined}\n />\n ))}\n </div>\n {error && (\n <p className=\"cedros-otp-error\" role=\"alert\">\n {error}\n </p>\n )}\n </div>\n );\n}\n","/**\n * TOTP Verification component for login flow\n *\n * Displayed when a user with 2FA enabled needs to\n * enter their verification code to complete login.\n */\n\nimport { useState } from 'react';\nimport { useTotpVerify } from '../../hooks/useTotpVerify';\nimport { OtpInput } from './OtpInput';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface TotpVerifyProps {\n /** Temporary token from password authentication */\n mfaToken: string;\n /** Email address (for display) */\n email?: string;\n /** Called when verification succeeds */\n onSuccess?: () => void;\n /** Called when user wants to go back */\n onBack?: () => void;\n /** Additional CSS class */\n className?: string;\n}\n\n/**\n * Two-factor authentication verification for login.\n *\n * Accepts 6-digit codes from authenticator apps\n * or recovery codes for account recovery.\n */\nexport function TotpVerify({\n mfaToken,\n email,\n onSuccess,\n onBack,\n className = '',\n}: TotpVerifyProps) {\n const { verifyTotp, isLoading, error, clearError } = useTotpVerify();\n const [code, setCode] = useState('');\n const [useBackupCode, setUseBackupCode] = useState(false);\n const [backupCode, setBackupCode] = useState('');\n\n const handleVerify = async (verifyCode?: string) => {\n const codeToVerify = verifyCode || (useBackupCode ? backupCode : code);\n if (!codeToVerify) return;\n\n try {\n await verifyTotp(mfaToken, codeToVerify);\n onSuccess?.();\n } catch {\n // Error handled by hook, clear the input\n if (useBackupCode) {\n setBackupCode('');\n } else {\n setCode('');\n }\n }\n };\n\n const handleOtpComplete = (value: string) => {\n handleVerify(value);\n };\n\n const toggleBackupCode = () => {\n setUseBackupCode(!useBackupCode);\n clearError();\n setCode('');\n setBackupCode('');\n };\n\n return (\n <div className={`cedros-totp-verify ${className}`}>\n <div className=\"cedros-totp-verify-header\">\n <svg\n className=\"cedros-totp-verify-icon\"\n width=\"48\"\n height=\"48\"\n viewBox=\"0 0 48 48\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <rect x=\"8\" y=\"20\" width=\"32\" height=\"24\" rx=\"4\" stroke=\"currentColor\" strokeWidth=\"2\" />\n <path\n d=\"M16 20V14a8 8 0 1 1 16 0v6\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n <circle cx=\"24\" cy=\"32\" r=\"3\" fill=\"currentColor\" />\n </svg>\n <h3 className=\"cedros-totp-title\">Two-factor authentication</h3>\n <p className=\"cedros-totp-description\">\n {useBackupCode\n ? 'Enter one of your recovery codes to sign in.'\n : 'Enter the 6-digit code from your authenticator app.'}\n </p>\n {email && <p className=\"cedros-totp-email\">{email}</p>}\n </div>\n\n {useBackupCode ? (\n <div className=\"cedros-totp-backup-input\">\n <input\n type=\"text\"\n className={`cedros-input ${error ? 'cedros-input-error' : ''}`}\n placeholder=\"Enter recovery code\"\n value={backupCode}\n onChange={(e) => {\n setBackupCode(e.target.value.toUpperCase());\n clearError();\n }}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && backupCode) {\n handleVerify();\n }\n }}\n disabled={isLoading}\n autoFocus\n autoComplete=\"one-time-code\"\n />\n {error && (\n <p className=\"cedros-input-error\" role=\"alert\">\n {error.message}\n </p>\n )}\n </div>\n ) : (\n <OtpInput\n value={code}\n onChange={(value) => {\n setCode(value);\n clearError();\n }}\n onComplete={handleOtpComplete}\n disabled={isLoading}\n error={error?.message}\n autoFocus\n />\n )}\n\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-primary cedros-button-md cedros-button-full\"\n onClick={() => handleVerify()}\n disabled={isLoading || (useBackupCode ? !backupCode : code.length !== 6)}\n >\n {isLoading ? (\n <>\n <LoadingSpinner size=\"sm\" />\n <span>Verifying...</span>\n </>\n ) : (\n 'Verify'\n )}\n </button>\n\n <div className=\"cedros-totp-verify-footer\">\n <button\n type=\"button\"\n className=\"cedros-link cedros-link-sm\"\n onClick={toggleBackupCode}\n disabled={isLoading}\n >\n {useBackupCode ? 'Use authenticator app' : 'Use a recovery code'}\n </button>\n\n {onBack && (\n <>\n <span className=\"cedros-totp-verify-divider\">•</span>\n <button\n type=\"button\"\n className=\"cedros-link cedros-link-sm\"\n onClick={onBack}\n disabled={isLoading}\n >\n Back to login\n </button>\n </>\n )}\n </div>\n </div>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport { useEmailAuth } from '../../hooks/useEmailAuth';\nimport { PasswordInput } from './PasswordInput';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\nimport { ErrorMessage } from '../shared/ErrorMessage';\nimport { TotpVerify } from '../totp/TotpVerify';\n\nexport interface EmailLoginFormProps {\n onSuccess?: () => void;\n onSwitchToRegister?: () => void;\n /** Called when user clicks \"Forgot password?\" — navigates to forgot-password screen */\n onForgotPassword?: () => void;\n className?: string;\n}\n\n/**\n * Email/password login form\n */\nexport function EmailLoginForm({\n onSuccess,\n onSwitchToRegister,\n onForgotPassword,\n className = '',\n}: EmailLoginFormProps) {\n const { login, isLoading, error, clearError } = useEmailAuth();\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n // MFA state for 2FA flow\n const [mfaToken, setMfaToken] = useState<string | null>(null);\n const [mfaEmail, setMfaEmail] = useState<string>('');\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n try {\n const result = await login(email, password);\n if (result.mfaRequired) {\n // MFA verification needed\n setMfaToken(result.mfaToken);\n setMfaEmail(result.email);\n } else {\n // Login successful\n onSuccess?.();\n }\n } catch {\n // Error is handled by the hook\n }\n };\n\n const handleTotpSuccess = () => {\n setMfaToken(null);\n setMfaEmail('');\n onSuccess?.();\n };\n\n const handleTotpBack = () => {\n setMfaToken(null);\n setMfaEmail('');\n setPassword(''); // Clear password for security\n };\n\n // Show TOTP verification step\n if (mfaToken) {\n return (\n <TotpVerify\n mfaToken={mfaToken}\n email={mfaEmail}\n onSuccess={handleTotpSuccess}\n onBack={handleTotpBack}\n className={className}\n />\n );\n }\n\n return (\n <form onSubmit={handleSubmit} className={`cedros-form ${className}`}>\n <div className=\"cedros-form-field\">\n <label htmlFor=\"email\" className=\"cedros-label\">\n Email\n </label>\n <input\n id=\"email\"\n type=\"email\"\n className=\"cedros-input\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n required\n aria-required=\"true\"\n autoComplete=\"email\"\n disabled={isLoading}\n />\n </div>\n\n <div className=\"cedros-form-field\">\n <PasswordInput\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"Enter your password\"\n required\n autoComplete=\"current-password\"\n disabled={isLoading}\n labelAction={\n onForgotPassword ? (\n <button\n type=\"button\"\n className=\"cedros-link cedros-link-muted cedros-link-sm\"\n onClick={onForgotPassword}\n >\n Forgot your password?\n </button>\n ) : undefined\n }\n />\n </div>\n\n <ErrorMessage error={error} onDismiss={clearError} />\n\n <button\n type=\"submit\"\n className=\"cedros-button cedros-button-primary cedros-button-md cedros-button-full\"\n disabled={isLoading || !email || !password}\n aria-busy={isLoading}\n >\n {isLoading ? (\n <>\n <LoadingSpinner size=\"sm\" announce label=\"Signing in\" />\n <span>Signing in...</span>\n </>\n ) : (\n 'Sign in'\n )}\n </button>\n\n {onSwitchToRegister && (\n <p className=\"cedros-form-footer\">\n Don&apos;t have an account?{' '}\n <button type=\"button\" className=\"cedros-link cedros-link-muted\" onClick={onSwitchToRegister}>\n Sign up\n </button>\n </p>\n )}\n </form>\n );\n}\n","import { useState, type FormEvent } from 'react';\nimport { useCedrosLogin } from '../../context/useCedrosLogin';\nimport { useEmailAuth } from '../../hooks/useEmailAuth';\nimport { PasswordInput } from './PasswordInput';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\nimport { ErrorMessage } from '../shared/ErrorMessage';\nimport { sanitizeExternalUrl } from '../../utils/sanitization';\nimport type { PasswordValidation, AuthError } from '../../types';\n\nexport interface EmailRegisterFormProps {\n onSuccess?: () => void;\n onSwitchToLogin?: () => void;\n className?: string;\n}\n\n/** Values collected from the registration form (for callback) */\nexport interface RegistrationData {\n termsAccepted: boolean;\n emailOptIn: boolean;\n}\n\n/**\n * Email/password registration form\n */\nexport function EmailRegisterForm({\n onSuccess,\n onSwitchToLogin,\n className = '',\n}: EmailRegisterFormProps) {\n const { config } = useCedrosLogin();\n const { register, isLoading, error, clearError } = useEmailAuth();\n const [name, setName] = useState('');\n const [email, setEmail] = useState('');\n const [password, setPassword] = useState('');\n const [confirmPassword, setConfirmPassword] = useState('');\n const [passwordValidation, setPasswordValidation] = useState<PasswordValidation | null>(null);\n const [termsError, setTermsError] = useState<AuthError | null>(null);\n\n // Get form configuration\n const termsConfig = config.forms?.termsOfService;\n const emailOptInConfig = config.forms?.emailOptIn;\n\n const showTerms = termsConfig?.show ?? false;\n const termsRequired = termsConfig?.required ?? true;\n const termsDefaultChecked = termsConfig?.defaultChecked ?? false;\n const termsLabel = termsConfig?.label ?? 'I agree to the Terms of Service';\n const termsUrl = termsConfig?.url;\n const safeTermsUrl = sanitizeExternalUrl(termsUrl);\n\n const showEmailOptIn = emailOptInConfig?.show ?? false;\n const emailOptInDefaultChecked = emailOptInConfig?.defaultChecked ?? false;\n const emailOptInLabel = emailOptInConfig?.label ?? 'Send me updates and news';\n\n // Initialize checkbox states with defaults\n const [termsAccepted, setTermsAccepted] = useState(termsDefaultChecked);\n const [emailOptIn, setEmailOptIn] = useState(emailOptInDefaultChecked);\n\n const passwordsMatch = password === confirmPassword;\n const isPasswordValid = passwordValidation?.isValid ?? false;\n\n // Terms must be accepted if shown and required\n const termsValid = !showTerms || !termsRequired || termsAccepted;\n\n const canSubmit =\n email &&\n password &&\n confirmPassword &&\n passwordsMatch &&\n isPasswordValid &&\n termsValid &&\n !isLoading;\n\n const handleSubmit = async (e: FormEvent) => {\n e.preventDefault();\n\n // Clear any previous terms error\n setTermsError(null);\n\n // Validate terms if required\n if (showTerms && termsRequired && !termsAccepted) {\n setTermsError({\n code: 'VALIDATION_ERROR',\n message: 'You must agree to the Terms of Service to continue',\n });\n return;\n }\n\n if (!canSubmit) return;\n\n try {\n // Note: termsAccepted and emailOptIn values can be passed to the backend\n // via the register function if needed. For now, we call register with the\n // standard params, but the backend could be extended to accept these values.\n await register(email, password, name || undefined);\n onSuccess?.();\n } catch {\n // Error is handled by the hook\n }\n };\n\n const combinedError = error || termsError;\n const combinedClearError = () => {\n clearError();\n setTermsError(null);\n };\n\n return (\n <form onSubmit={handleSubmit} className={`cedros-form ${className}`}>\n <div className=\"cedros-form-field\">\n <label htmlFor=\"name\" className=\"cedros-label\">\n Name <span className=\"cedros-optional\">(optional)</span>\n </label>\n <input\n id=\"name\"\n type=\"text\"\n className=\"cedros-input\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n placeholder=\"Your name\"\n autoComplete=\"name\"\n disabled={isLoading}\n />\n </div>\n\n <div className=\"cedros-form-field\">\n <label htmlFor=\"register-email\" className=\"cedros-label\">\n Email\n </label>\n <input\n id=\"register-email\"\n type=\"email\"\n className=\"cedros-input\"\n value={email}\n onChange={(e) => setEmail(e.target.value)}\n placeholder=\"you@example.com\"\n required\n aria-required=\"true\"\n autoComplete=\"email\"\n disabled={isLoading}\n />\n </div>\n\n <div className=\"cedros-form-field\">\n <PasswordInput\n value={password}\n onChange={(e) => setPassword(e.target.value)}\n placeholder=\"Create a password\"\n required\n autoComplete=\"new-password\"\n disabled={isLoading}\n showStrengthMeter\n onValidationChange={setPasswordValidation}\n />\n </div>\n\n <div className=\"cedros-form-field\">\n <PasswordInput\n label=\"Confirm Password\"\n value={confirmPassword}\n onChange={(e) => setConfirmPassword(e.target.value)}\n placeholder=\"Confirm your password\"\n required\n autoComplete=\"new-password\"\n disabled={isLoading}\n aria-invalid={confirmPassword && !passwordsMatch ? 'true' : undefined}\n error={confirmPassword && !passwordsMatch ? 'Passwords do not match' : undefined}\n />\n </div>\n\n {/* Terms of Service checkbox */}\n {showTerms && (\n <div className=\"cedros-form-field cedros-checkbox-field\">\n <label className=\"cedros-checkbox-label\">\n <input\n type=\"checkbox\"\n className=\"cedros-checkbox\"\n checked={termsAccepted}\n onChange={(e) => setTermsAccepted(e.target.checked)}\n disabled={isLoading}\n aria-required={termsRequired}\n />\n <span className=\"cedros-checkbox-text\">\n {safeTermsUrl ? (\n <>\n {termsLabel.replace('Terms of Service', '').trim() || 'I agree to the'}{' '}\n <a\n href={safeTermsUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"cedros-link\"\n >\n Terms of Service\n </a>\n </>\n ) : (\n termsLabel\n )}\n {termsRequired && <span className=\"cedros-required\">*</span>}\n </span>\n </label>\n </div>\n )}\n\n {/* Email opt-in checkbox */}\n {showEmailOptIn && (\n <div className=\"cedros-form-field cedros-checkbox-field\">\n <label className=\"cedros-checkbox-label\">\n <input\n type=\"checkbox\"\n className=\"cedros-checkbox\"\n checked={emailOptIn}\n onChange={(e) => setEmailOptIn(e.target.checked)}\n disabled={isLoading}\n />\n <span className=\"cedros-checkbox-text\">{emailOptInLabel}</span>\n </label>\n </div>\n )}\n\n <ErrorMessage error={combinedError} onDismiss={combinedClearError} />\n\n <button\n type=\"submit\"\n className=\"cedros-button cedros-button-primary cedros-button-md cedros-button-full\"\n disabled={!canSubmit}\n aria-busy={isLoading}\n >\n {isLoading ? (\n <>\n <LoadingSpinner size=\"sm\" announce label=\"Creating account\" />\n <span>Creating account...</span>\n </>\n ) : (\n 'Create account'\n )}\n </button>\n\n {onSwitchToLogin && (\n <p className=\"cedros-form-footer\">\n Already have an account?{' '}\n <button type=\"button\" className=\"cedros-link cedros-link-muted\" onClick={onSwitchToLogin}>\n Sign in\n </button>\n </p>\n )}\n </form>\n );\n}\n"],"names":["useRateLimiter","options","maxAttempts","windowMs","showCountdown","attemptsRef","useRef","hasAttempts","setHasAttempts","useState","setTick","bump","useCallback","value","cleanupAttemptsArray","now","timestamp","cleanupExpiredAttempts","current","getRemainingAttempts","getTimeUntilReset","resetTime","isAllowed","checkLimit","waitTime","waitSeconds","reset","useEffect","intervalId","isMfaRequiredResponse","response","useEmailAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","error","setError","resetRateLimit","apiClient","useMemo","ApiClient","callbacks","walletEnrollmentEnabled","serverUrl","login","email","password","validateEmail","validationError","err","rateLimitError","data","authResponse","authError","handleApiError","register","name","accessToken","enrollDelay","resolve","silentWalletEnroll","result","message","clearError","PasswordInput","label","labelAction","showStrengthMeter","onValidationChange","className","onChange","props","showPassword","setShowPassword","validation","setValidation","inputId","useId","handleChange","e","newValue","newValidation","validatePassword","strengthColors","jsxs","jsx","useTotpVerify","state","setState","verifyTotp","mfaToken","code","isRecoveryCode","OTP_LENGTH","OtpInput","onComplete","disabled","autoFocus","inputRefs","localValue","setLocalValue","id","focusInput","index","updateValue","sanitized","digit","chars","handleKeyDown","handlePaste","digits","handleFocus","_","el","TotpVerify","onSuccess","onBack","setCode","useBackupCode","setUseBackupCode","backupCode","setBackupCode","handleVerify","verifyCode","codeToVerify","handleOtpComplete","toggleBackupCode","Fragment","LoadingSpinner","EmailLoginForm","onSwitchToRegister","onForgotPassword","setEmail","setPassword","setMfaToken","mfaEmail","setMfaEmail","handleSubmit","handleTotpSuccess","handleTotpBack","ErrorMessage","EmailRegisterForm","onSwitchToLogin","setName","confirmPassword","setConfirmPassword","passwordValidation","setPasswordValidation","termsError","setTermsError","termsConfig","emailOptInConfig","showTerms","termsRequired","termsDefaultChecked","termsLabel","termsUrl","safeTermsUrl","sanitizeExternalUrl","showEmailOptIn","emailOptInDefaultChecked","emailOptInLabel","termsAccepted","setTermsAccepted","emailOptIn","setEmailOptIn","passwordsMatch","isPasswordValid","canSubmit","combinedError","combinedClearError"],"mappings":"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"}
@@ -1 +0,0 @@
1
- "use strict";const e=require("react/jsx-runtime"),b=require("react"),E=require("./LoadingSpinner-d6sSxgQN.cjs"),k=require("./ErrorMessage-CHbYbVi2.cjs"),d=require("./AutosaveStatus-DGNI4lXn.cjs"),l=["wallet_recovery_mode"];function q({className:a}){const{settings:c,edits:v,isLoading:x,autosaveStatus:j,autosaveError:p,error:g,fetchSettings:u,handleChange:n,getEffectiveValue:t}=d.useSettingsAutosave();b.useEffect(()=>{u()},[u]);const h=(c.features??[]).filter(o=>l.includes(o.key)).sort((o,_)=>l.indexOf(o.key)-l.indexOf(_.key)),s=t("feature_wallet_signing")==="true",w=()=>{n("feature_wallet_signing",s?"false":"true")},r=t("feature_user_withdrawals")==="true",f=()=>{n("feature_user_withdrawals",r?"false":"true")},m=t("deposit_privacy_enabled")==="true",N=t("wallet_recovery_mode"),i=m&&N!=="none",y=m&&!s,S=b.useMemo(()=>{if(i)return{wallet_recovery_mode:"Private deposits require No Recovery mode. Deposits will fail with the current setting."}},[i]);return x&&Object.keys(c).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${a??""}`,children:[e.jsx(E.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):g?e.jsx("div",{className:`cedros-system-settings ${a??""}`,children:e.jsx(k.ErrorMessage,{error:g.message})}):e.jsxs("div",{className:`cedros-system-settings ${a??""}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:"Embedded Wallet"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure the embedded wallet for transaction signing."})]}),e.jsxs("div",{className:"cedros-settings-page-header-actions",children:[e.jsxs("button",{type:"button",role:"switch","aria-checked":s,className:`cedros-toggle ${s?"cedros-toggle-on":"cedros-toggle-off"}`,onClick:w,children:[e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})}),e.jsx("span",{className:"cedros-toggle-label",children:s?"Enabled":"Disabled"})]}),e.jsx(d.AutosaveStatus,{status:j,error:p})]})]}),s&&e.jsx("div",{className:"cedros-settings-subsection",children:e.jsxs("div",{className:"cedros-settings-subsection-header",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"cedros-settings-subsection-title",children:"User Withdrawals"}),e.jsx("p",{className:"cedros-settings-subsection-description",children:"Allow users to withdraw SOL/SPL tokens from their embedded wallet to external addresses."})]}),e.jsxs("button",{type:"button",role:"switch","aria-checked":r,className:`cedros-toggle ${r?"cedros-toggle-on":"cedros-toggle-off"}`,onClick:f,children:[e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})}),e.jsx("span",{className:"cedros-toggle-label",children:r?"Enabled":"Disabled"})]})]})}),i&&e.jsx("div",{className:"cedros-settings-warning-banner",children:"Private deposits are enabled but require No Recovery mode. Users will see an error when attempting private deposits until recovery mode is changed below."}),y&&e.jsx("div",{className:"cedros-settings-warning-banner",children:"Private deposits are enabled but require the embedded wallet. Enable it above."}),e.jsx("div",{className:"cedros-admin-tab-content",children:h.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsx("p",{children:"No additional settings available."})}):e.jsx(d.SettingsSection,{settings:h,edits:v,onChange:n,externalWarnings:S})})]})}exports.EmbeddedWalletSettings=q;
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmbeddedWalletSettings-BRjt2PAj.cjs","sources":["../src/components/admin/settings/EmbeddedWalletSettings.tsx"],"sourcesContent":["/**\n * Embedded Wallet settings page - enable/disable and configure recovery\n */\nimport { useEffect, useMemo } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\n/** Keys to show on this page (excluding the master toggle which is in header) */\nconst SETTINGS_KEYS = ['wallet_recovery_mode'];\n\nexport interface EmbeddedWalletSettingsProps {\n className?: string;\n}\n\nexport function EmbeddedWalletSettings({ className }: EmbeddedWalletSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n } = useSettingsAutosave();\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get wallet settings from features category\n const featuresSettings = settings['features'] ?? [];\n const currentSettings = featuresSettings\n .filter((s) => SETTINGS_KEYS.includes(s.key))\n .sort((a, b) => SETTINGS_KEYS.indexOf(a.key) - SETTINGS_KEYS.indexOf(b.key));\n\n // Embedded wallet master toggle\n const walletEnabled = getEffectiveValue('feature_wallet_signing') === 'true';\n const handleWalletToggle = () => {\n handleChange('feature_wallet_signing', walletEnabled ? 'false' : 'true');\n };\n\n // User withdrawals toggle (only visible when wallet is enabled)\n const withdrawalsEnabled = getEffectiveValue('feature_user_withdrawals') === 'true';\n const handleWithdrawalsToggle = () => {\n handleChange('feature_user_withdrawals', withdrawalsEnabled ? 'false' : 'true');\n };\n\n // Cross-category mismatch detection\n const privateDepositsEnabled = getEffectiveValue('deposit_privacy_enabled') === 'true';\n const recoveryMode = getEffectiveValue('wallet_recovery_mode');\n const recoveryMismatch = privateDepositsEnabled && recoveryMode !== 'none';\n const walletMismatch = privateDepositsEnabled && !walletEnabled;\n\n // Inline warning on recovery mode row\n const externalWarnings = useMemo(() => {\n if (!recoveryMismatch) return undefined;\n return {\n wallet_recovery_mode:\n 'Private deposits require No Recovery mode. Deposits will fail with the current setting.',\n };\n }, [recoveryMismatch]);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Embedded Wallet</h2>\n <p className=\"cedros-settings-page-description\">\n Configure the embedded wallet for transaction signing.\n </p>\n </div>\n <div className=\"cedros-settings-page-header-actions\">\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={walletEnabled}\n className={`cedros-toggle ${walletEnabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={handleWalletToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">{walletEnabled ? 'Enabled' : 'Disabled'}</span>\n </button>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n </div>\n\n {/* User Withdrawals toggle (only visible when wallet is enabled) */}\n {walletEnabled && (\n <div className=\"cedros-settings-subsection\">\n <div className=\"cedros-settings-subsection-header\">\n <div>\n <h3 className=\"cedros-settings-subsection-title\">User Withdrawals</h3>\n <p className=\"cedros-settings-subsection-description\">\n Allow users to withdraw SOL/SPL tokens from their embedded wallet to external\n addresses.\n </p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={withdrawalsEnabled}\n className={`cedros-toggle ${withdrawalsEnabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={handleWithdrawalsToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">\n {withdrawalsEnabled ? 'Enabled' : 'Disabled'}\n </span>\n </button>\n </div>\n </div>\n )}\n\n {/* Mismatch warnings */}\n {recoveryMismatch && (\n <div className=\"cedros-settings-warning-banner\">\n Private deposits are enabled but require No Recovery mode. Users will see an error when\n attempting private deposits until recovery mode is changed below.\n </div>\n )}\n {walletMismatch && (\n <div className=\"cedros-settings-warning-banner\">\n Private deposits are enabled but require the embedded wallet. Enable it above.\n </div>\n )}\n\n {/* Settings content */}\n <div className=\"cedros-admin-tab-content\">\n {currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No additional settings available.</p>\n </div>\n ) : (\n <SettingsSection\n settings={currentSettings}\n edits={edits}\n onChange={handleChange}\n externalWarnings={externalWarnings}\n />\n )}\n </div>\n </div>\n );\n}\n"],"names":["SETTINGS_KEYS","EmbeddedWalletSettings","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","getEffectiveValue","useSettingsAutosave","useEffect","currentSettings","s","a","b","walletEnabled","handleWalletToggle","withdrawalsEnabled","handleWithdrawalsToggle","privateDepositsEnabled","recoveryMode","recoveryMismatch","walletMismatch","externalWarnings","useMemo","jsx","LoadingSpinner","ErrorMessage","jsxs","AutosaveStatus","SettingsSection"],"mappings":"oMAWMA,EAAgB,CAAC,sBAAsB,EAMtC,SAASC,EAAuB,CAAE,UAAAC,GAA0C,CACjF,KAAM,CACJ,SAAAC,EACA,MAAAC,EACA,UAAAC,EACA,eAAAC,EACA,cAAAC,EACA,MAAAC,EACA,cAAAC,EACA,aAAAC,EACA,kBAAAC,CAAA,EACEC,sBAAA,EAEJC,EAAAA,UAAU,IAAM,CACdJ,EAAA,CACF,EAAG,CAACA,CAAa,CAAC,EAIlB,MAAMK,GADmBX,EAAS,UAAe,CAAA,GAE9C,OAAQY,GAAMf,EAAc,SAASe,EAAE,GAAG,CAAC,EAC3C,KAAK,CAACC,EAAGC,IAAMjB,EAAc,QAAQgB,EAAE,GAAG,EAAIhB,EAAc,QAAQiB,EAAE,GAAG,CAAC,EAGvEC,EAAgBP,EAAkB,wBAAwB,IAAM,OAChEQ,EAAqB,IAAM,CAC/BT,EAAa,yBAA0BQ,EAAgB,QAAU,MAAM,CACzE,EAGME,EAAqBT,EAAkB,0BAA0B,IAAM,OACvEU,EAA0B,IAAM,CACpCX,EAAa,2BAA4BU,EAAqB,QAAU,MAAM,CAChF,EAGME,EAAyBX,EAAkB,yBAAyB,IAAM,OAC1EY,EAAeZ,EAAkB,sBAAsB,EACvDa,EAAmBF,GAA0BC,IAAiB,OAC9DE,EAAiBH,GAA0B,CAACJ,EAG5CQ,EAAmBC,EAAAA,QAAQ,IAAM,CACrC,GAAKH,EACL,MAAO,CACL,qBACE,yFAAA,CAEN,EAAG,CAACA,CAAgB,CAAC,EAErB,OAAInB,GAAa,OAAO,KAAKF,CAAQ,EAAE,SAAW,SAE7C,MAAA,CAAI,UAAW,yDAAyDD,GAAa,EAAE,GACtF,SAAA,CAAA0B,EAAAA,IAACC,EAAAA,eAAA,EAAe,EAChBD,EAAAA,IAAC,QAAK,SAAA,qBAAA,CAAmB,CAAA,EAC3B,EAIApB,EAEAoB,EAAAA,IAAC,MAAA,CAAI,UAAW,0BAA0B1B,GAAa,EAAE,GACvD,SAAA0B,EAAAA,IAACE,EAAAA,aAAA,CAAa,MAAOtB,EAAM,OAAA,CAAS,EACtC,SAKD,MAAA,CAAI,UAAW,0BAA0BN,GAAa,EAAE,GACvD,SAAA,CAAA6B,EAAAA,KAAC,MAAA,CAAI,UAAU,8BACb,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAH,EAAAA,IAAC,KAAA,CAAG,UAAU,6BAA6B,SAAA,kBAAe,EAC1DA,EAAAA,IAAC,IAAA,CAAE,UAAU,mCAAmC,SAAA,wDAAA,CAEhD,CAAA,EACF,EACAG,EAAAA,KAAC,MAAA,CAAI,UAAU,sCACb,SAAA,CAAAA,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,KAAK,SACL,eAAcb,EACd,UAAW,iBAAiBA,EAAgB,mBAAqB,mBAAmB,GACpF,QAASC,EAET,SAAA,CAAAS,EAAAA,IAAC,QAAK,UAAU,sBACd,eAAC,OAAA,CAAK,UAAU,sBAAsB,CAAA,CACxC,QACC,OAAA,CAAK,UAAU,sBAAuB,SAAAV,EAAgB,UAAY,UAAA,CAAW,CAAA,CAAA,CAAA,EAEhFU,EAAAA,IAACI,EAAAA,eAAA,CAAe,OAAQ1B,EAAgB,MAAOC,CAAA,CAAe,CAAA,CAAA,CAChE,CAAA,EACF,EAGCW,SACE,MAAA,CAAI,UAAU,6BACb,SAAAa,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACb,SAAA,CAAAA,OAAC,MAAA,CACC,SAAA,CAAAH,EAAAA,IAAC,KAAA,CAAG,UAAU,mCAAmC,SAAA,mBAAgB,EACjEA,EAAAA,IAAC,IAAA,CAAE,UAAU,yCAAyC,SAAA,0FAAA,CAGtD,CAAA,EACF,EACAG,EAAAA,KAAC,SAAA,CACC,KAAK,SACL,KAAK,SACL,eAAcX,EACd,UAAW,iBAAiBA,EAAqB,mBAAqB,mBAAmB,GACzF,QAASC,EAET,SAAA,CAAAO,EAAAA,IAAC,QAAK,UAAU,sBACd,eAAC,OAAA,CAAK,UAAU,sBAAsB,CAAA,CACxC,QACC,OAAA,CAAK,UAAU,sBACb,SAAAR,EAAqB,UAAY,UAAA,CACpC,CAAA,CAAA,CAAA,CACF,CAAA,CACF,CAAA,CACF,EAIDI,GACCI,EAAAA,IAAC,MAAA,CAAI,UAAU,iCAAiC,SAAA,4JAGhD,EAEDH,GACCG,EAAAA,IAAC,MAAA,CAAI,UAAU,iCAAiC,SAAA,iFAEhD,EAIFA,MAAC,MAAA,CAAI,UAAU,2BACZ,WAAgB,SAAW,EAC1BA,MAAC,MAAA,CAAI,UAAU,+BACb,SAAAA,MAAC,IAAA,CAAE,SAAA,mCAAA,CAAiC,EACtC,EAEAA,EAAAA,IAACK,EAAAA,gBAAA,CACC,SAAUnB,EACV,MAAAV,EACA,SAAUM,EACV,iBAAAgB,CAAA,CAAA,CACF,CAEJ,CAAA,EACF,CAEJ"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"EmbeddedWalletSettings-Dmi-EQ7W.js","sources":["../src/components/admin/settings/EmbeddedWalletSettings.tsx"],"sourcesContent":["/**\n * Embedded Wallet settings page - enable/disable and configure recovery\n */\nimport { useEffect, useMemo } from 'react';\nimport { LoadingSpinner } from '../../shared/LoadingSpinner';\nimport { ErrorMessage } from '../../shared/ErrorMessage';\nimport { useSettingsAutosave } from '../../../hooks/useSettingsAutosave';\nimport { SettingsSection } from './settingsInputs';\nimport { AutosaveStatus } from './AutosaveStatus';\n\n/** Keys to show on this page (excluding the master toggle which is in header) */\nconst SETTINGS_KEYS = ['wallet_recovery_mode'];\n\nexport interface EmbeddedWalletSettingsProps {\n className?: string;\n}\n\nexport function EmbeddedWalletSettings({ className }: EmbeddedWalletSettingsProps) {\n const {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n } = useSettingsAutosave();\n\n useEffect(() => {\n fetchSettings();\n }, [fetchSettings]);\n\n // Get wallet settings from features category\n const featuresSettings = settings['features'] ?? [];\n const currentSettings = featuresSettings\n .filter((s) => SETTINGS_KEYS.includes(s.key))\n .sort((a, b) => SETTINGS_KEYS.indexOf(a.key) - SETTINGS_KEYS.indexOf(b.key));\n\n // Embedded wallet master toggle\n const walletEnabled = getEffectiveValue('feature_wallet_signing') === 'true';\n const handleWalletToggle = () => {\n handleChange('feature_wallet_signing', walletEnabled ? 'false' : 'true');\n };\n\n // User withdrawals toggle (only visible when wallet is enabled)\n const withdrawalsEnabled = getEffectiveValue('feature_user_withdrawals') === 'true';\n const handleWithdrawalsToggle = () => {\n handleChange('feature_user_withdrawals', withdrawalsEnabled ? 'false' : 'true');\n };\n\n // Cross-category mismatch detection\n const privateDepositsEnabled = getEffectiveValue('deposit_privacy_enabled') === 'true';\n const recoveryMode = getEffectiveValue('wallet_recovery_mode');\n const recoveryMismatch = privateDepositsEnabled && recoveryMode !== 'none';\n const walletMismatch = privateDepositsEnabled && !walletEnabled;\n\n // Inline warning on recovery mode row\n const externalWarnings = useMemo(() => {\n if (!recoveryMismatch) return undefined;\n return {\n wallet_recovery_mode:\n 'Private deposits require No Recovery mode. Deposits will fail with the current setting.',\n };\n }, [recoveryMismatch]);\n\n if (isLoading && Object.keys(settings).length === 0) {\n return (\n <div className={`cedros-system-settings cedros-system-settings-loading ${className ?? ''}`}>\n <LoadingSpinner />\n <span>Loading settings...</span>\n </div>\n );\n }\n\n if (error) {\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <ErrorMessage error={error.message} />\n </div>\n );\n }\n\n return (\n <div className={`cedros-system-settings ${className ?? ''}`}>\n <div className=\"cedros-settings-page-header\">\n <div className=\"cedros-settings-page-header-content\">\n <h2 className=\"cedros-settings-page-title\">Embedded Wallet</h2>\n <p className=\"cedros-settings-page-description\">\n Configure the embedded wallet for transaction signing.\n </p>\n </div>\n <div className=\"cedros-settings-page-header-actions\">\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={walletEnabled}\n className={`cedros-toggle ${walletEnabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={handleWalletToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">{walletEnabled ? 'Enabled' : 'Disabled'}</span>\n </button>\n <AutosaveStatus status={autosaveStatus} error={autosaveError} />\n </div>\n </div>\n\n {/* User Withdrawals toggle (only visible when wallet is enabled) */}\n {walletEnabled && (\n <div className=\"cedros-settings-subsection\">\n <div className=\"cedros-settings-subsection-header\">\n <div>\n <h3 className=\"cedros-settings-subsection-title\">User Withdrawals</h3>\n <p className=\"cedros-settings-subsection-description\">\n Allow users to withdraw SOL/SPL tokens from their embedded wallet to external\n addresses.\n </p>\n </div>\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={withdrawalsEnabled}\n className={`cedros-toggle ${withdrawalsEnabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={handleWithdrawalsToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">\n {withdrawalsEnabled ? 'Enabled' : 'Disabled'}\n </span>\n </button>\n </div>\n </div>\n )}\n\n {/* Mismatch warnings */}\n {recoveryMismatch && (\n <div className=\"cedros-settings-warning-banner\">\n Private deposits are enabled but require No Recovery mode. Users will see an error when\n attempting private deposits until recovery mode is changed below.\n </div>\n )}\n {walletMismatch && (\n <div className=\"cedros-settings-warning-banner\">\n Private deposits are enabled but require the embedded wallet. Enable it above.\n </div>\n )}\n\n {/* Settings content */}\n <div className=\"cedros-admin-tab-content\">\n {currentSettings.length === 0 ? (\n <div className=\"cedros-system-settings-empty\">\n <p>No additional settings available.</p>\n </div>\n ) : (\n <SettingsSection\n settings={currentSettings}\n edits={edits}\n onChange={handleChange}\n externalWarnings={externalWarnings}\n />\n )}\n </div>\n </div>\n );\n}\n"],"names":["SETTINGS_KEYS","EmbeddedWalletSettings","className","settings","edits","isLoading","autosaveStatus","autosaveError","error","fetchSettings","handleChange","getEffectiveValue","useSettingsAutosave","useEffect","currentSettings","s","a","b","walletEnabled","handleWalletToggle","withdrawalsEnabled","handleWithdrawalsToggle","privateDepositsEnabled","recoveryMode","recoveryMismatch","walletMismatch","externalWarnings","useMemo","jsx","LoadingSpinner","ErrorMessage","jsxs","AutosaveStatus","SettingsSection"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GoogleLoginButton-6ip-vudk.js","sources":["../src/hooks/useGoogleAuth.ts","../src/components/google/GoogleLoginButton.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport type { AuthResponse, AuthError } from '../types';\n\n/**\n * Module-level singleton for Google script loading (P-01)\n *\n * Prevents race conditions when multiple components mount simultaneously.\n * Uses a promise queue pattern to ensure the script is only loaded once.\n *\n * ## SSR Limitations (F-08)\n *\n * This singleton persists across the module lifecycle. In SSR environments:\n * - Module state persists between requests (potential cross-request leakage)\n * - Google Sign-In requires browser APIs (document, window)\n * - The hook guards against SSR with `googleClientId` checks\n *\n * For SSR frameworks (Next.js, Remix), ensure this hook is only used\n * in client-side components.\n *\n * ## Test Isolation\n *\n * For test isolation, call `scriptLoader._reset()` in test setup/teardown.\n *\n * @internal\n */\nconst scriptLoader = {\n loading: false,\n loaded: false,\n error: null as Error | null,\n callbacks: [] as Array<{ resolve: () => void; reject: (err: Error) => void }>,\n\n load(): Promise<void> {\n // SSR guard: avoid touching browser globals when running in Node/SSR.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('Google Sign-In script loader cannot run in SSR'));\n }\n\n // Already loaded\n if (this.loaded) {\n return Promise.resolve();\n }\n\n // Loading in progress - queue callback\n if (this.loading) {\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n });\n }\n\n // Start loading\n this.loading = true;\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n\n // Check if script already exists (from previous session or SSR)\n const existingScript = document.getElementById('google-gsi-script');\n if (existingScript) {\n if (window.google?.accounts?.id) {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n } else {\n existingScript.addEventListener('load', () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n });\n }\n return;\n }\n\n const script = document.createElement('script');\n script.src = 'https://accounts.google.com/gsi/client';\n script.async = true;\n script.defer = true;\n script.id = 'google-gsi-script';\n\n script.onload = () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n };\n\n script.onerror = () => {\n this.loading = false;\n // M-02: Remove failed script from DOM to allow retry on next load() call.\n // Without removal, retry finds existingScript and waits for a load event\n // that will never fire on an already-failed script.\n script.remove();\n const error = new Error('Failed to load Google Sign-In script');\n this.callbacks.forEach((cb) => cb.reject(error));\n this.callbacks = [];\n };\n\n document.head.appendChild(script);\n });\n },\n\n /**\n * Reset singleton state for test isolation (F-08)\n * @internal - Only use in test setup/teardown\n */\n _reset(): void {\n this.loading = false;\n this.loaded = false;\n this.error = null;\n this.callbacks = [];\n },\n};\n\n/** @internal */\nexport const _internalGoogleScriptLoader = scriptLoader;\n\nexport interface UseGoogleAuthReturn {\n signIn: () => Promise<AuthResponse>;\n isLoading: boolean;\n isInitialized: boolean;\n error: AuthError | null;\n clearError: () => void;\n /** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */\n pendingLinkIdToken: string | null;\n /** Clear the pending link state */\n clearPendingLink: () => void;\n}\n\ninterface PromiseCallbacks {\n resolve: (value: AuthResponse) => void;\n reject: (error: AuthError) => void;\n}\n\n/**\n * Hook for Google OAuth authentication.\n *\n * @example\n * ```tsx\n * function GoogleButton() {\n * const { signIn, isLoading, isInitialized, error } = useGoogleAuth();\n *\n * return (\n * <button onClick={signIn} disabled={!isInitialized || isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign in with Google'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useGoogleAuth(): UseGoogleAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n const [pendingLinkIdToken, setPendingLinkIdToken] = useState<string | null>(null);\n\n const promiseCallbacksRef = useRef<PromiseCallbacks | null>(null);\n const configRef = useRef(config);\n const tokenClientRef = useRef<GoogleTokenClient | null>(null);\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n // Keep config ref in sync\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Handle access token from OAuth popup (initTokenClient flow)\n const handleTokenResponse = useCallback(\n async (response: GoogleTokenResponse) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n if (response.error) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: response.error === 'access_denied'\n ? 'Google sign-in was cancelled.'\n : 'Unable to sign in with Google. Please try again.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n callbacks.reject(err);\n return;\n }\n\n try {\n const data = await apiClient.post<AuthResponse>('/google', {\n accessToken: response.access_token,\n });\n configRef.current.callbacks?.onLoginSuccess?.(data.user, 'google');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n setIsLoading(false);\n callbacks.resolve(data);\n } catch (err) {\n const authError = handleApiError(err, 'Unable to sign in with Google. Please try again.');\n if (authError.code === 'ACCOUNT_LINK_REQUIRED') {\n setPendingLinkIdToken(response.access_token ?? null);\n }\n setError(authError);\n setIsLoading(false);\n callbacks.reject(authError);\n } finally {\n promiseCallbacksRef.current = null;\n }\n },\n [apiClient, _internal]\n );\n\n // Handle popup closed / blocked without completing auth.\n // Google calls error_callback (not callback) when the user closes the popup.\n const handleTokenError = useCallback(\n (err: GoogleTokenErrorResponse) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n const authError: AuthError = {\n code: 'SERVER_ERROR',\n message: err.type === 'popup_failed_to_open'\n ? 'Google sign-in popup was blocked. Please allow popups for this site.'\n : 'Google sign-in was cancelled.',\n };\n setError(authError);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n callbacks.reject(authError);\n },\n []\n );\n\n // P-01: Initialize Google OAuth token client using singleton loader.\n // Uses initTokenClient (OAuth popup) instead of One Tap prompt() which\n // has exponential cooldown after dismissal and is blocked by Brave.\n useEffect(() => {\n if (!config.googleClientId) {\n return;\n }\n\n let isMounted = true;\n\n scriptLoader\n .load()\n .then(() => {\n if (!isMounted) return;\n\n const client = window.google?.accounts?.oauth2?.initTokenClient({\n client_id: config.googleClientId!,\n scope: 'openid email profile',\n callback: handleTokenResponse,\n error_callback: handleTokenError,\n });\n\n if (client) {\n tokenClientRef.current = client;\n setIsInitialized(true);\n }\n })\n .catch(() => {\n if (isMounted) {\n setError({\n code: 'SERVER_ERROR',\n message: 'Unable to load Google sign-in. Please refresh and try again.',\n });\n }\n });\n\n return () => {\n isMounted = false;\n tokenClientRef.current = null;\n };\n }, [config.googleClientId, handleTokenResponse, handleTokenError]);\n\n const signIn = useCallback(async (): Promise<AuthResponse> => {\n if (!config.googleClientId) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Client ID not configured',\n };\n setError(err);\n throw err;\n }\n\n if (!isInitialized) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is not ready yet. Please wait a moment and try again.',\n };\n setError(err);\n throw err;\n }\n\n if (promiseCallbacksRef.current) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is already in progress.',\n };\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise<AuthResponse>((resolve, reject) => {\n promiseCallbacksRef.current = { resolve, reject };\n\n // Open the Google OAuth popup via initTokenClient.\n // This avoids One Tap's exponential cooldown after dismissal and works\n // in browsers that block One Tap (e.g., Brave).\n tokenClientRef.current?.requestAccessToken();\n });\n }, [config.googleClientId, isInitialized]);\n\n const clearError = useCallback(() => setError(null), []);\n const clearPendingLink = useCallback(() => setPendingLinkIdToken(null), []);\n\n return {\n signIn,\n isLoading,\n isInitialized,\n error,\n clearError,\n pendingLinkIdToken,\n clearPendingLink,\n };\n}\n\n/** Response from Google's initTokenClient callback */\ninterface GoogleTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n}\n\n/** Error from initTokenClient error_callback (popup closed/blocked) */\ninterface GoogleTokenErrorResponse {\n type: 'popup_failed_to_open' | 'popup_closed' | 'unknown';\n}\n\n/** Token client returned by google.accounts.oauth2.initTokenClient */\ninterface GoogleTokenClient {\n requestAccessToken: () => void;\n}\n\n// Type declaration for Google Identity Services\ndeclare global {\n interface Window {\n google?: {\n accounts?: {\n /** Used only to detect if the GIS script has loaded */\n id?: object;\n oauth2?: {\n initTokenClient: (config: {\n client_id: string;\n scope: string;\n callback: (response: GoogleTokenResponse) => void;\n error_callback?: (error: GoogleTokenErrorResponse) => void;\n }) => GoogleTokenClient;\n };\n };\n };\n }\n}\n","import { useGoogleAuth } from '../../hooks/useGoogleAuth';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface GoogleLoginButtonProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n className?: string;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\n/**\n * Google OAuth login button\n */\nexport function GoogleLoginButton({\n onSuccess,\n onError,\n className = '',\n variant = 'default',\n size = 'md',\n disabled = false,\n}: GoogleLoginButtonProps) {\n const { signIn, isLoading, isInitialized } = useGoogleAuth();\n\n const handleClick = async () => {\n try {\n await signIn();\n onSuccess?.();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error);\n }\n };\n\n const sizeClasses = {\n sm: 'cedros-button-sm',\n md: 'cedros-button-md',\n lg: 'cedros-button-lg',\n };\n\n const variantClasses = {\n default: 'cedros-button-social',\n outline: 'cedros-button-social-outline',\n };\n\n return (\n <button\n type=\"button\"\n className={`cedros-button ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}\n onClick={handleClick}\n disabled={disabled || !isInitialized || isLoading}\n aria-label=\"Sign in with Google\"\n >\n {isLoading ? (\n <LoadingSpinner size=\"sm\" />\n ) : (\n <svg\n className=\"cedros-button-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z\"\n fill=\"#EA4335\"\n />\n </svg>\n )}\n <span>Continue with Google</span>\n </button>\n );\n}\n"],"names":["scriptLoader","resolve","reject","existingScript","cb","script","error","useGoogleAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","useState","isInitialized","setIsInitialized","setError","pendingLinkIdToken","setPendingLinkIdToken","promiseCallbacksRef","useRef","configRef","tokenClientRef","apiClient","useMemo","ApiClient","useEffect","handleTokenResponse","useCallback","response","callbacks","err","data","authError","handleApiError","handleTokenError","isMounted","client","signIn","clearError","clearPendingLink","GoogleLoginButton","onSuccess","onError","className","variant","size","disabled","handleClick","sizeClasses","jsxs","jsx","LoadingSpinner"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GoogleLoginButton-BDCbxoCB.cjs","sources":["../src/hooks/useGoogleAuth.ts","../src/components/google/GoogleLoginButton.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport type { AuthResponse, AuthError } from '../types';\n\n/**\n * Module-level singleton for Google script loading (P-01)\n *\n * Prevents race conditions when multiple components mount simultaneously.\n * Uses a promise queue pattern to ensure the script is only loaded once.\n *\n * ## SSR Limitations (F-08)\n *\n * This singleton persists across the module lifecycle. In SSR environments:\n * - Module state persists between requests (potential cross-request leakage)\n * - Google Sign-In requires browser APIs (document, window)\n * - The hook guards against SSR with `googleClientId` checks\n *\n * For SSR frameworks (Next.js, Remix), ensure this hook is only used\n * in client-side components.\n *\n * ## Test Isolation\n *\n * For test isolation, call `scriptLoader._reset()` in test setup/teardown.\n *\n * @internal\n */\nconst scriptLoader = {\n loading: false,\n loaded: false,\n error: null as Error | null,\n callbacks: [] as Array<{ resolve: () => void; reject: (err: Error) => void }>,\n\n load(): Promise<void> {\n // SSR guard: avoid touching browser globals when running in Node/SSR.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('Google Sign-In script loader cannot run in SSR'));\n }\n\n // Already loaded\n if (this.loaded) {\n return Promise.resolve();\n }\n\n // Loading in progress - queue callback\n if (this.loading) {\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n });\n }\n\n // Start loading\n this.loading = true;\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n\n // Check if script already exists (from previous session or SSR)\n const existingScript = document.getElementById('google-gsi-script');\n if (existingScript) {\n if (window.google?.accounts?.id) {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n } else {\n existingScript.addEventListener('load', () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n });\n }\n return;\n }\n\n const script = document.createElement('script');\n script.src = 'https://accounts.google.com/gsi/client';\n script.async = true;\n script.defer = true;\n script.id = 'google-gsi-script';\n\n script.onload = () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n };\n\n script.onerror = () => {\n this.loading = false;\n // M-02: Remove failed script from DOM to allow retry on next load() call.\n // Without removal, retry finds existingScript and waits for a load event\n // that will never fire on an already-failed script.\n script.remove();\n const error = new Error('Failed to load Google Sign-In script');\n this.callbacks.forEach((cb) => cb.reject(error));\n this.callbacks = [];\n };\n\n document.head.appendChild(script);\n });\n },\n\n /**\n * Reset singleton state for test isolation (F-08)\n * @internal - Only use in test setup/teardown\n */\n _reset(): void {\n this.loading = false;\n this.loaded = false;\n this.error = null;\n this.callbacks = [];\n },\n};\n\n/** @internal */\nexport const _internalGoogleScriptLoader = scriptLoader;\n\nexport interface UseGoogleAuthReturn {\n signIn: () => Promise<AuthResponse>;\n isLoading: boolean;\n isInitialized: boolean;\n error: AuthError | null;\n clearError: () => void;\n /** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */\n pendingLinkIdToken: string | null;\n /** Clear the pending link state */\n clearPendingLink: () => void;\n}\n\ninterface PromiseCallbacks {\n resolve: (value: AuthResponse) => void;\n reject: (error: AuthError) => void;\n}\n\n/**\n * Hook for Google OAuth authentication.\n *\n * @example\n * ```tsx\n * function GoogleButton() {\n * const { signIn, isLoading, isInitialized, error } = useGoogleAuth();\n *\n * return (\n * <button onClick={signIn} disabled={!isInitialized || isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign in with Google'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useGoogleAuth(): UseGoogleAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n const [pendingLinkIdToken, setPendingLinkIdToken] = useState<string | null>(null);\n\n const promiseCallbacksRef = useRef<PromiseCallbacks | null>(null);\n const configRef = useRef(config);\n const tokenClientRef = useRef<GoogleTokenClient | null>(null);\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n // Keep config ref in sync\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Handle access token from OAuth popup (initTokenClient flow)\n const handleTokenResponse = useCallback(\n async (response: GoogleTokenResponse) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n if (response.error) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: response.error === 'access_denied'\n ? 'Google sign-in was cancelled.'\n : 'Unable to sign in with Google. Please try again.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n callbacks.reject(err);\n return;\n }\n\n try {\n const data = await apiClient.post<AuthResponse>('/google', {\n accessToken: response.access_token,\n });\n configRef.current.callbacks?.onLoginSuccess?.(data.user, 'google');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n setIsLoading(false);\n callbacks.resolve(data);\n } catch (err) {\n const authError = handleApiError(err, 'Unable to sign in with Google. Please try again.');\n if (authError.code === 'ACCOUNT_LINK_REQUIRED') {\n setPendingLinkIdToken(response.access_token ?? null);\n }\n setError(authError);\n setIsLoading(false);\n callbacks.reject(authError);\n } finally {\n promiseCallbacksRef.current = null;\n }\n },\n [apiClient, _internal]\n );\n\n // Handle popup closed / blocked without completing auth.\n // Google calls error_callback (not callback) when the user closes the popup.\n const handleTokenError = useCallback(\n (err: GoogleTokenErrorResponse) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n const authError: AuthError = {\n code: 'SERVER_ERROR',\n message: err.type === 'popup_failed_to_open'\n ? 'Google sign-in popup was blocked. Please allow popups for this site.'\n : 'Google sign-in was cancelled.',\n };\n setError(authError);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n callbacks.reject(authError);\n },\n []\n );\n\n // P-01: Initialize Google OAuth token client using singleton loader.\n // Uses initTokenClient (OAuth popup) instead of One Tap prompt() which\n // has exponential cooldown after dismissal and is blocked by Brave.\n useEffect(() => {\n if (!config.googleClientId) {\n return;\n }\n\n let isMounted = true;\n\n scriptLoader\n .load()\n .then(() => {\n if (!isMounted) return;\n\n const client = window.google?.accounts?.oauth2?.initTokenClient({\n client_id: config.googleClientId!,\n scope: 'openid email profile',\n callback: handleTokenResponse,\n error_callback: handleTokenError,\n });\n\n if (client) {\n tokenClientRef.current = client;\n setIsInitialized(true);\n }\n })\n .catch(() => {\n if (isMounted) {\n setError({\n code: 'SERVER_ERROR',\n message: 'Unable to load Google sign-in. Please refresh and try again.',\n });\n }\n });\n\n return () => {\n isMounted = false;\n tokenClientRef.current = null;\n };\n }, [config.googleClientId, handleTokenResponse, handleTokenError]);\n\n const signIn = useCallback(async (): Promise<AuthResponse> => {\n if (!config.googleClientId) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Client ID not configured',\n };\n setError(err);\n throw err;\n }\n\n if (!isInitialized) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is not ready yet. Please wait a moment and try again.',\n };\n setError(err);\n throw err;\n }\n\n if (promiseCallbacksRef.current) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is already in progress.',\n };\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise<AuthResponse>((resolve, reject) => {\n promiseCallbacksRef.current = { resolve, reject };\n\n // Open the Google OAuth popup via initTokenClient.\n // This avoids One Tap's exponential cooldown after dismissal and works\n // in browsers that block One Tap (e.g., Brave).\n tokenClientRef.current?.requestAccessToken();\n });\n }, [config.googleClientId, isInitialized]);\n\n const clearError = useCallback(() => setError(null), []);\n const clearPendingLink = useCallback(() => setPendingLinkIdToken(null), []);\n\n return {\n signIn,\n isLoading,\n isInitialized,\n error,\n clearError,\n pendingLinkIdToken,\n clearPendingLink,\n };\n}\n\n/** Response from Google's initTokenClient callback */\ninterface GoogleTokenResponse {\n access_token?: string;\n error?: string;\n error_description?: string;\n}\n\n/** Error from initTokenClient error_callback (popup closed/blocked) */\ninterface GoogleTokenErrorResponse {\n type: 'popup_failed_to_open' | 'popup_closed' | 'unknown';\n}\n\n/** Token client returned by google.accounts.oauth2.initTokenClient */\ninterface GoogleTokenClient {\n requestAccessToken: () => void;\n}\n\n// Type declaration for Google Identity Services\ndeclare global {\n interface Window {\n google?: {\n accounts?: {\n /** Used only to detect if the GIS script has loaded */\n id?: object;\n oauth2?: {\n initTokenClient: (config: {\n client_id: string;\n scope: string;\n callback: (response: GoogleTokenResponse) => void;\n error_callback?: (error: GoogleTokenErrorResponse) => void;\n }) => GoogleTokenClient;\n };\n };\n };\n }\n}\n","import { useGoogleAuth } from '../../hooks/useGoogleAuth';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface GoogleLoginButtonProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n className?: string;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\n/**\n * Google OAuth login button\n */\nexport function GoogleLoginButton({\n onSuccess,\n onError,\n className = '',\n variant = 'default',\n size = 'md',\n disabled = false,\n}: GoogleLoginButtonProps) {\n const { signIn, isLoading, isInitialized } = useGoogleAuth();\n\n const handleClick = async () => {\n try {\n await signIn();\n onSuccess?.();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error);\n }\n };\n\n const sizeClasses = {\n sm: 'cedros-button-sm',\n md: 'cedros-button-md',\n lg: 'cedros-button-lg',\n };\n\n const variantClasses = {\n default: 'cedros-button-social',\n outline: 'cedros-button-social-outline',\n };\n\n return (\n <button\n type=\"button\"\n className={`cedros-button ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}\n onClick={handleClick}\n disabled={disabled || !isInitialized || isLoading}\n aria-label=\"Sign in with Google\"\n >\n {isLoading ? (\n <LoadingSpinner size=\"sm\" />\n ) : (\n <svg\n className=\"cedros-button-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z\"\n fill=\"#EA4335\"\n />\n </svg>\n )}\n <span>Continue with Google</span>\n </button>\n );\n}\n"],"names":["scriptLoader","resolve","reject","existingScript","cb","script","error","useGoogleAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","useState","isInitialized","setIsInitialized","setError","pendingLinkIdToken","setPendingLinkIdToken","promiseCallbacksRef","useRef","configRef","tokenClientRef","apiClient","useMemo","ApiClient","useEffect","handleTokenResponse","useCallback","response","callbacks","err","data","authError","handleApiError","handleTokenError","isMounted","client","signIn","clearError","clearPendingLink","GoogleLoginButton","onSuccess","onError","className","variant","size","disabled","handleClick","sizeClasses","variantClasses","jsxs","jsx","LoadingSpinner"],"mappings":"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"}
@@ -1 +0,0 @@
1
- "use strict";const K=require("./useAuth-XZaciuLg.cjs");var dt=typeof document<"u"?document.currentScript:null;let F=null,ve=0;const nt=new Map;function Re(){return typeof Worker>"u"?null:(F||(F=new Worker(new URL(""+(typeof document>"u"?require("url").pathToFileURL(__dirname+"/assets/argon2Worker-Bi5TuQvD.js").href:new URL("assets/argon2Worker-Bi5TuQvD.js",document.currentScript&&document.currentScript.tagName.toUpperCase()==="SCRIPT"&&document.currentScript.src||document.baseURI).href),typeof document>"u"?require("url").pathToFileURL(__filename).href:dt&&dt.tagName.toUpperCase()==="SCRIPT"&&dt.src||new URL("shamir-DBpHm7WN.cjs",document.baseURI).href),{type:"module"}),F.onmessage=e=>{const{id:t,key:n,error:o}=e.data,r=nt.get(t);if(r){if(nt.delete(t),o){r.reject(new Error(o));return}if(!n){r.reject(new Error("Argon2 worker returned no key"));return}r.resolve(n)}},F.onerror=e=>{const t=e instanceof ErrorEvent?e.error:new Error("Argon2 worker error");for(const n of nt.values())n.reject(t instanceof Error?t:new Error(String(t)));nt.clear(),F?.terminate(),F=null}),F)}async function Ae(e,t,n=K.DEFAULT_KDF_PARAMS){K.validateKdfParams(n);const o=Re();return o?new Promise((r,s)=>{const c=ve++;nt.set(c,{resolve:r,reject:s});const u={id:c,password:e,salt:t,params:n};o.postMessage(u)}):K.argon2Derive(e,t,n)}function ne(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function Ie(e){if(Object.prototype.hasOwnProperty.call(e,"__esModule"))return e;var t=e.default;if(typeof t=="function"){var n=function o(){var r=!1;try{r=this instanceof o}catch{}return r?Reflect.construct(t,arguments,this.constructor):t.apply(this,arguments)};n.prototype=t.prototype}else n={};return Object.defineProperty(n,"__esModule",{value:!0}),Object.keys(e).forEach(function(o){var r=Object.getOwnPropertyDescriptor(e,o);Object.defineProperty(n,o,r.get?r:{enumerable:!0,get:function(){return e[o]}})}),n}var ct={exports:{}};const _e=globalThis.crypto,Ne=globalThis.crypto,Te=globalThis.crypto.subtle,Oe=globalThis.crypto.getRandomValues.bind(globalThis.crypto),Ce=globalThis.crypto.randomUUID.bind(globalThis.crypto),Le=Object.freeze(Object.defineProperty({__proto__:null,default:_e,getRandomValues:Oe,randomUUID:Ce,subtle:Te,webcrypto:Ne},Symbol.toStringTag,{value:"Module"})),Ue=Ie(Le);var He=ct.exports,Dt;function De(){return Dt||(Dt=1,(function(e,t){(function(n,o){e.exports=o(Ue)})(He,function(n){var o,r,s,c,u;function i(){o={bits:8,radix:16,minBits:3,maxBits:20,bytesPerChar:2,maxBytesPerChar:6,primitivePolynomials:[null,null,1,3,3,5,3,3,29,17,9,5,83,27,43,3,45,9,39,39,9,5,3,33,27,9,71,39,9,5,83]},r={},s=new Array(1024).join("0"),c=!0,u=["nodeCryptoRandomBytes","browserCryptoGetRandomValues","testRandom"]}function x(){return!!(r&&r.rng&&typeof r.rng=="function")}function y(a,h){var f;if(h===0||h===1)return a;if(h&&h>1024)throw new Error("Padding must be multiples of no larger than 1024 bits.");return h=h||r.bits,a&&(f=a.length%h),f?(s+a).slice(-(h-f+a.length)):a}function w(a){var h="",f,l;for(l=a.length-1;l>=0;l--){if(f=parseInt(a[l],16),isNaN(f))throw new Error("Invalid hex character.");h=y(f.toString(2),4)+h}return h}function S(a){var h="",f,l;for(a=y(a,4),l=a.length;l>=4;l-=4){if(f=parseInt(a.slice(l-4,l),2),isNaN(f))throw new Error("Invalid binary character.");h=f.toString(16)+h}return h}function I(){return!!(n&&typeof n=="object"&&(typeof n.getRandomValues=="function"||typeof n.getRandomValues=="object")&&(typeof Uint32Array=="function"||typeof Uint32Array=="object"))}function v(){return typeof n=="object"&&typeof n.randomBytes=="function"}function T(a){function h(b,g,m,B){var A=0,C,L="",q;for(g&&(C=g.length-1);A<C||L.length<b;)q=Math.abs(parseInt(g[A],m)),L=L+y(q.toString(2),B),A++;return L=L.substr(-b),(L.match(/0/g)||[]).length===L.length?null:L}function f(b){var g,m,B,A,C=null;for(B=16,A=4,m=Math.ceil(b/8);C===null;)g=n.randomBytes(m),C=h(b,g.toString("hex"),B,A);return C}function l(b){var g,m,B,A=null;for(m=10,B=32,g=Math.ceil(b/32);A===null;)A=h(b,n.getRandomValues(new Uint32Array(g)),m,B);return A}function d(b){var g,m,B,A,C,L=null;A=10,C=32,m=Math.ceil(b/32),B=123456789,g=new Uint32Array(m);for(var q=0;q<g.length;q++)g[q]=B;for(;L===null;)L=h(b,g,A,C);return L}if(a&&a==="testRandom")return r.typeCSPRNG=a,d;if(a&&a==="nodeCryptoRandomBytes")return r.typeCSPRNG=a,f;if(a&&a==="browserCryptoGetRandomValues")return r.typeCSPRNG=a,l;if(v())return r.typeCSPRNG="nodeCryptoRandomBytes",f;if(I())return r.typeCSPRNG="browserCryptoGetRandomValues",l}function _(a,h){var f=[],l;for(h&&(a=y(a,h)),l=a.length;l>r.bits;l-=r.bits)f.push(parseInt(a.slice(l-r.bits,l),2));return f.push(parseInt(a.slice(0,l),2)),f}function E(a,h){var f=r.logs[a],l=0,d;for(d=h.length-1;d>=0;d--)l!==0?l=r.exps[(f+r.logs[l])%r.maxShares]^h[d]:l=h[d];return l}function R(a,h,f){var l=0,d,b,g,m;for(g=0,d=h.length;g<d;g++)if(f[g]){for(b=r.logs[f[g]],m=0;m<d;m++)if(g!==m){if(a===h[m]){b=-1;break}b=(b+r.logs[a^h[m]]-r.logs[h[g]^h[m]]+r.maxShares)%r.maxShares}l=b===-1?l:l^r.exps[b]}return l}function p(a,h,f){var l=[],d=[a],b,g;for(b=1;b<f;b++)d[b]=parseInt(r.rng(r.bits),2);for(b=1,g=h+1;b<g;b++)l[b-1]={x:b,y:E(b,d)};return l}function N(a,h,f){var l,d,b,g,m;if(h=parseInt(h,r.radix),a=parseInt(a,10)||r.bits,l=a.toString(36).toUpperCase(),b=Math.pow(2,a)-1,g=b.toString(r.radix).length,d=y(h.toString(r.radix),g),typeof h!="number"||h%1!==0||h<1||h>b)throw new Error("Share id must be an integer between 1 and "+b+", inclusive.");return m=l+d+f,m}var O={init:function(a,h){var f=[],l=[],d=1,b,g;if(i(),a&&(typeof a!="number"||a%1!==0||a<o.minBits||a>o.maxBits))throw new Error("Number of bits must be an integer between "+o.minBits+" and "+o.maxBits+", inclusive.");if(h&&u.indexOf(h)===-1)throw new Error("Invalid RNG type argument : '"+h+"'");for(r.radix=o.radix,r.bits=a||o.bits,r.size=Math.pow(2,r.bits),r.maxShares=r.size-1,b=o.primitivePolynomials[r.bits],g=0;g<r.size;g++)l[g]=d,f[d]=g,d=d<<1,d>=r.size&&(d=d^b,d=d&r.maxShares);if(r.logs=f,r.exps=l,h&&this.setRNG(h),x()||this.setRNG(),!x()||!r.bits||!r.size||!r.maxShares||!r.logs||!r.exps||r.logs.length!==r.size||r.exps.length!==r.size)throw new Error("Initialization failed.")},combine:function(a,h){var f,l,d,b,g="",m,B,A,C=[],L=[];for(h=h||0,f=0,d=a.length;f<d;f++){if(B=this.extractShareComponents(a[f]),m===void 0)m=B.bits;else if(B.bits!==m)throw new Error("Mismatched shares: Different bit settings.");if(r.bits!==m&&this.init(m),C.indexOf(B.id)===-1)for(C.push(B.id),A=_(w(B.data)),l=0,b=A.length;l<b;l++)L[l]=L[l]||[],L[l][C.length-1]=A[l]}for(f=0,d=L.length;f<d;f++)g=y(R(h,C,L[f]).toString(2))+g;return S(h>=1?g:g.slice(g.indexOf("1")+1))},getConfig:function(){var a={};return a.radix=r.radix,a.bits=r.bits,a.maxShares=r.maxShares,a.hasCSPRNG=x(),a.typeCSPRNG=r.typeCSPRNG,a},extractShareComponents:function(a){var h,f,l,d,b={},g,m;if(h=parseInt(a.substr(0,1),36),h&&(typeof h!="number"||h%1!==0||h<o.minBits||h>o.maxBits))throw new Error("Invalid share : Number of bits must be an integer between "+o.minBits+" and "+o.maxBits+", inclusive.");if(d=Math.pow(2,h)-1,l=(Math.pow(2,h)-1).toString(r.radix).length,g="^([a-kA-K3-9]{1})([a-fA-F0-9]{"+l+"})([a-fA-F0-9]+)$",m=new RegExp(g).exec(a),m&&(f=parseInt(m[2],r.radix)),typeof f!="number"||f%1!==0||f<1||f>d)throw new Error("Invalid share : Share id must be an integer between 1 and "+r.maxShares+", inclusive.");if(m&&m[3])return b.bits=h,b.id=f,b.data=m[3],b;throw new Error("The share data provided is invalid : "+a)},setRNG:function(a){var h="Random number generator is invalid ",f=" Supply an CSPRNG of the form function(bits){} that returns a string containing 'bits' number of random 1's and 0's.";if(a&&typeof a=="string"&&u.indexOf(a)===-1)throw new Error("Invalid RNG type argument : '"+a+"'");if(a||(a=T()),a&&typeof a=="string"&&(a=T(a)),c){if(a&&typeof a!="function")throw new Error(h+"(Not a function)."+f);if(a&&typeof a(r.bits)!="string")throw new Error(h+"(Output is not a string)."+f);if(a&&!parseInt(a(r.bits),2))throw new Error(h+"(Binary string output not parseable to an Integer)."+f);if(a&&a(r.bits).length>r.bits)throw new Error(h+"(Output length is greater than config.bits)."+f);if(a&&a(r.bits).length<r.bits)throw new Error(h+"(Output length is less than config.bits)."+f)}return r.rng=a,!0},str2hex:function(a,h){var f,l,d="",b,g,m,B;if(typeof a!="string")throw new Error("Input must be a character string.");if(h||(h=o.bytesPerChar),typeof h!="number"||h<1||h>o.maxBytesPerChar||h%1!==0)throw new Error("Bytes per character must be an integer between 1 and "+o.maxBytesPerChar+", inclusive.");for(f=2*h,l=Math.pow(16,f)-1,m=0,B=a.length;m<B;m++){if(g=a[m].charCodeAt(),isNaN(g))throw new Error("Invalid character: "+a[m]);if(g>l)throw b=Math.ceil(Math.log(g+1)/Math.log(256)),new Error("Invalid character code ("+g+"). Maximum allowable is 256^bytes-1 ("+l+"). To convert this character, use at least "+b+" bytes.");d=y(g.toString(16),f)+d}return d},hex2str:function(a,h){var f,l="",d,b;if(typeof a!="string")throw new Error("Input must be a hexadecimal string.");if(h=h||o.bytesPerChar,typeof h!="number"||h%1!==0||h<1||h>o.maxBytesPerChar)throw new Error("Bytes per character must be an integer between 1 and "+o.maxBytesPerChar+", inclusive.");for(f=2*h,a=y(a,f),d=0,b=a.length;d<b;d+=f)l=String.fromCharCode(parseInt(a.slice(d,d+f),16))+l;return l},random:function(a){if(typeof a!="number"||a%1!==0||a<2||a>65536)throw new Error("Number of bits must be an Integer between 1 and 65536.");return S(r.rng(a))},share:function(a,h,f,l){var d,b,g=new Array(h),m=new Array(h),B,A,C;if(l=l||128,typeof a!="string")throw new Error("Secret must be a string.");if(typeof h!="number"||h%1!==0||h<2)throw new Error("Number of shares must be an integer between 2 and 2^bits-1 ("+r.maxShares+"), inclusive.");if(h>r.maxShares)throw d=Math.ceil(Math.log(h+1)/Math.LN2),new Error("Number of shares must be an integer between 2 and 2^bits-1 ("+r.maxShares+"), inclusive. To create "+h+" shares, use at least "+d+" bits.");if(typeof f!="number"||f%1!==0||f<2)throw new Error("Threshold number of shares must be an integer between 2 and 2^bits-1 ("+r.maxShares+"), inclusive.");if(f>r.maxShares)throw d=Math.ceil(Math.log(f+1)/Math.LN2),new Error("Threshold number of shares must be an integer between 2 and 2^bits-1 ("+r.maxShares+"), inclusive. To use a threshold of "+f+", use at least "+d+" bits.");if(f>h)throw new Error("Threshold number of shares was "+f+" but must be less than or equal to the "+h+" shares specified as the total to generate.");if(typeof l!="number"||l%1!==0||l<0||l>1024)throw new Error("Zero-pad length must be an integer between 0 and 1024 inclusive.");for(a="1"+w(a),a=_(a,l),B=0,C=a.length;B<C;B++)for(b=p(a[B],h,f),A=0;A<h;A++)g[A]=g[A]||b[A].x.toString(r.radix),m[A]=y(b[A].y.toString(2))+(m[A]||"");for(B=0;B<h;B++)g[B]=N(r.bits,g[B],S(m[B]));return g},newShare:function(a,h){var f,l;if(a&&typeof a=="string"&&(a=parseInt(a,r.radix)),l=a.toString(r.radix),a&&l&&h&&h[0])return f=this.extractShareComponents(h[0]),N(f.bits,l,this.combine(h,a));throw new Error("Invalid 'id' or 'shares' Array argument to newShare().")},_reset:i,_padLeft:y,_hex2bin:w,_bin2hex:S,_hasCryptoGetRandomValues:I,_hasCryptoRandomBytes:v,_getRNG:T,_isSetRNG:x,_splitNumStringToIntArray:_,_horner:E,_lagrange:R,_getShares:p,_constructPublicShareString:N};return O.init(),O})})(ct)),ct.exports}var qe=De();const re=ne(qe);function oe(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function _t(e,t=""){if(!Number.isSafeInteger(e)||e<0){const n=t&&`"${t}" `;throw new Error(`${n}expected integer >= 0, got ${e}`)}}function D(e,t,n=""){const o=oe(e),r=e?.length,s=t!==void 0;if(!o||s&&r!==t){const c=n&&`"${n}" `,u=s?` of length ${t}`:"",i=o?`length=${r}`:`type=${typeof e}`;throw new Error(c+"expected Uint8Array"+u+", got "+i)}return e}function qt(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Me(e,t){D(e,void 0,"digestInto() output");const n=t.outputLen;if(e.length<n)throw new Error('"digestInto() output" expected to be of length >='+n)}function Bt(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function bt(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}const se=typeof Uint8Array.from([]).toHex=="function"&&typeof Uint8Array.fromHex=="function",Ge=Array.from({length:256},(e,t)=>t.toString(16).padStart(2,"0"));function Nt(e){if(D(e),se)return e.toHex();let t="";for(let n=0;n<e.length;n++)t+=Ge[e[n]];return t}const V={_0:48,_9:57,A:65,F:70,a:97,f:102};function Mt(e){if(e>=V._0&&e<=V._9)return e-V._0;if(e>=V.A&&e<=V.F)return e-(V.A-10);if(e>=V.a&&e<=V.f)return e-(V.a-10)}function ie(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);if(se)return Uint8Array.fromHex(e);const t=e.length,n=t/2;if(t%2)throw new Error("hex string expected, got unpadded hex of length "+t);const o=new Uint8Array(n);for(let r=0,s=0;r<n;r++,s+=2){const c=Mt(e.charCodeAt(s)),u=Mt(e.charCodeAt(s+1));if(c===void 0||u===void 0){const i=e[s]+e[s+1];throw new Error('hex string expected, got non-hex character "'+i+'" at index '+s)}o[r]=c*16+u}return o}function Gt(...e){let t=0;for(let o=0;o<e.length;o++){const r=e[o];D(r),t+=r.length}const n=new Uint8Array(t);for(let o=0,r=0;o<e.length;o++){const s=e[o];n.set(s,r),r+=s.length}return n}function $e(e,t={}){const n=(r,s)=>e(s).update(r).digest(),o=e(void 0);return n.outputLen=o.outputLen,n.blockLen=o.blockLen,n.create=r=>e(r),Object.assign(n,t),Object.freeze(n)}function Ze(e=32){const t=typeof globalThis=="object"?globalThis.crypto:null;if(typeof t?.getRandomValues!="function")throw new Error("crypto.getRandomValues must be defined");return t.getRandomValues(new Uint8Array(e))}const je=e=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,e])});let Ve=class{blockLen;outputLen;padOffset;isLE;buffer;view;finished=!1;length=0;pos=0;destroyed=!1;constructor(t,n,o,r){this.blockLen=t,this.outputLen=n,this.padOffset=o,this.isLE=r,this.buffer=new Uint8Array(t),this.view=bt(this.buffer)}update(t){qt(this),D(t);const{view:n,buffer:o,blockLen:r}=this,s=t.length;for(let c=0;c<s;){const u=Math.min(r-this.pos,s-c);if(u===r){const i=bt(t);for(;r<=s-c;c+=r)this.process(i,c);continue}o.set(t.subarray(c,c+u),this.pos),this.pos+=u,c+=u,this.pos===r&&(this.process(n,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){qt(this),Me(t,this),this.finished=!0;const{buffer:n,view:o,blockLen:r,isLE:s}=this;let{pos:c}=this;n[c++]=128,Bt(this.buffer.subarray(c)),this.padOffset>r-c&&(this.process(o,0),c=0);for(let w=c;w<r;w++)n[w]=0;o.setBigUint64(r-8,BigInt(this.length*8),s),this.process(o,0);const u=bt(t),i=this.outputLen;if(i%4)throw new Error("_sha2: outputLen must be aligned to 32bit");const x=i/4,y=this.get();if(x>y.length)throw new Error("_sha2: outputLen bigger than state");for(let w=0;w<x;w++)u.setUint32(4*w,y[w],s)}digest(){const{buffer:t,outputLen:n}=this;this.digestInto(t);const o=t.slice(0,n);return this.destroy(),o}_cloneInto(t){t||=new this.constructor,t.set(...this.get());const{blockLen:n,buffer:o,length:r,finished:s,destroyed:c,pos:u}=this;return t.destroyed=c,t.finished=s,t.length=r,t.pos=u,r%n&&t.buffer.set(o),t}clone(){return this._cloneInto()}};const M=Uint32Array.from([1779033703,4089235720,3144134277,2227873595,1013904242,4271175723,2773480762,1595750129,1359893119,2917565137,2600822924,725511199,528734635,4215389547,1541459225,327033209]),ot=BigInt(2**32-1),$t=BigInt(32);function ke(e,t=!1){return t?{h:Number(e&ot),l:Number(e>>$t&ot)}:{h:Number(e>>$t&ot)|0,l:Number(e&ot)|0}}function Ke(e,t=!1){const n=e.length;let o=new Uint32Array(n),r=new Uint32Array(n);for(let s=0;s<n;s++){const{h:c,l:u}=ke(e[s],t);[o[s],r[s]]=[c,u]}return[o,r]}const Zt=(e,t,n)=>e>>>n,jt=(e,t,n)=>e<<32-n|t>>>n,tt=(e,t,n)=>e>>>n|t<<32-n,et=(e,t,n)=>e<<32-n|t>>>n,st=(e,t,n)=>e<<64-n|t>>>n-32,it=(e,t,n)=>e>>>n-32|t<<64-n;function k(e,t,n,o){const r=(t>>>0)+(o>>>0);return{h:e+n+(r/2**32|0)|0,l:r|0}}const Ye=(e,t,n)=>(e>>>0)+(t>>>0)+(n>>>0),ze=(e,t,n,o)=>t+n+o+(e/2**32|0)|0,We=(e,t,n,o)=>(e>>>0)+(t>>>0)+(n>>>0)+(o>>>0),Xe=(e,t,n,o,r)=>t+n+o+r+(e/2**32|0)|0,Pe=(e,t,n,o,r)=>(e>>>0)+(t>>>0)+(n>>>0)+(o>>>0)+(r>>>0),Fe=(e,t,n,o,r,s)=>t+n+o+r+s+(e/2**32|0)|0,ce=Ke(["0x428a2f98d728ae22","0x7137449123ef65cd","0xb5c0fbcfec4d3b2f","0xe9b5dba58189dbbc","0x3956c25bf348b538","0x59f111f1b605d019","0x923f82a4af194f9b","0xab1c5ed5da6d8118","0xd807aa98a3030242","0x12835b0145706fbe","0x243185be4ee4b28c","0x550c7dc3d5ffb4e2","0x72be5d74f27b896f","0x80deb1fe3b1696b1","0x9bdc06a725c71235","0xc19bf174cf692694","0xe49b69c19ef14ad2","0xefbe4786384f25e3","0x0fc19dc68b8cd5b5","0x240ca1cc77ac9c65","0x2de92c6f592b0275","0x4a7484aa6ea6e483","0x5cb0a9dcbd41fbd4","0x76f988da831153b5","0x983e5152ee66dfab","0xa831c66d2db43210","0xb00327c898fb213f","0xbf597fc7beef0ee4","0xc6e00bf33da88fc2","0xd5a79147930aa725","0x06ca6351e003826f","0x142929670a0e6e70","0x27b70a8546d22ffc","0x2e1b21385c26c926","0x4d2c6dfc5ac42aed","0x53380d139d95b3df","0x650a73548baf63de","0x766a0abb3c77b2a8","0x81c2c92e47edaee6","0x92722c851482353b","0xa2bfe8a14cf10364","0xa81a664bbc423001","0xc24b8b70d0f89791","0xc76c51a30654be30","0xd192e819d6ef5218","0xd69906245565a910","0xf40e35855771202a","0x106aa07032bbd1b8","0x19a4c116b8d2d0c8","0x1e376c085141ab53","0x2748774cdf8eeb99","0x34b0bcb5e19b48a8","0x391c0cb3c5c95a63","0x4ed8aa4ae3418acb","0x5b9cca4f7763e373","0x682e6ff3d6b2b8a3","0x748f82ee5defb2fc","0x78a5636f43172f60","0x84c87814a1f0ab72","0x8cc702081a6439ec","0x90befffa23631e28","0xa4506cebde82bde9","0xbef9a3f7b2c67915","0xc67178f2e372532b","0xca273eceea26619c","0xd186b8c721c0c207","0xeada7dd6cde0eb1e","0xf57d4f7fee6ed178","0x06f067aa72176fba","0x0a637dc5a2c898a6","0x113f9804bef90dae","0x1b710b35131c471b","0x28db77f523047d84","0x32caab7b40c72493","0x3c9ebe0a15c9bebc","0x431d67c49c100d4c","0x4cc5d4becb3e42b6","0x597f299cfc657e2a","0x5fcb6fab3ad6faec","0x6c44198c4a475817"].map(e=>BigInt(e))),Qe=ce[0],Je=ce[1],Y=new Uint32Array(80),z=new Uint32Array(80);class tn extends Ve{constructor(t){super(128,t,16,!1)}get(){const{Ah:t,Al:n,Bh:o,Bl:r,Ch:s,Cl:c,Dh:u,Dl:i,Eh:x,El:y,Fh:w,Fl:S,Gh:I,Gl:v,Hh:T,Hl:_}=this;return[t,n,o,r,s,c,u,i,x,y,w,S,I,v,T,_]}set(t,n,o,r,s,c,u,i,x,y,w,S,I,v,T,_){this.Ah=t|0,this.Al=n|0,this.Bh=o|0,this.Bl=r|0,this.Ch=s|0,this.Cl=c|0,this.Dh=u|0,this.Dl=i|0,this.Eh=x|0,this.El=y|0,this.Fh=w|0,this.Fl=S|0,this.Gh=I|0,this.Gl=v|0,this.Hh=T|0,this.Hl=_|0}process(t,n){for(let p=0;p<16;p++,n+=4)Y[p]=t.getUint32(n),z[p]=t.getUint32(n+=4);for(let p=16;p<80;p++){const N=Y[p-15]|0,O=z[p-15]|0,a=tt(N,O,1)^tt(N,O,8)^Zt(N,O,7),h=et(N,O,1)^et(N,O,8)^jt(N,O,7),f=Y[p-2]|0,l=z[p-2]|0,d=tt(f,l,19)^st(f,l,61)^Zt(f,l,6),b=et(f,l,19)^it(f,l,61)^jt(f,l,6),g=We(h,b,z[p-7],z[p-16]),m=Xe(g,a,d,Y[p-7],Y[p-16]);Y[p]=m|0,z[p]=g|0}let{Ah:o,Al:r,Bh:s,Bl:c,Ch:u,Cl:i,Dh:x,Dl:y,Eh:w,El:S,Fh:I,Fl:v,Gh:T,Gl:_,Hh:E,Hl:R}=this;for(let p=0;p<80;p++){const N=tt(w,S,14)^tt(w,S,18)^st(w,S,41),O=et(w,S,14)^et(w,S,18)^it(w,S,41),a=w&I^~w&T,h=S&v^~S&_,f=Pe(R,O,h,Je[p],z[p]),l=Fe(f,E,N,a,Qe[p],Y[p]),d=f|0,b=tt(o,r,28)^st(o,r,34)^st(o,r,39),g=et(o,r,28)^it(o,r,34)^it(o,r,39),m=o&s^o&u^s&u,B=r&c^r&i^c&i;E=T|0,R=_|0,T=I|0,_=v|0,I=w|0,v=S|0,{h:w,l:S}=k(x|0,y|0,l|0,d|0),x=u|0,y=i|0,u=s|0,i=c|0,s=o|0,c=r|0;const A=Ye(d,g,B);o=ze(A,l,b,m),r=A|0}({h:o,l:r}=k(this.Ah|0,this.Al|0,o|0,r|0)),{h:s,l:c}=k(this.Bh|0,this.Bl|0,s|0,c|0),{h:u,l:i}=k(this.Ch|0,this.Cl|0,u|0,i|0),{h:x,l:y}=k(this.Dh|0,this.Dl|0,x|0,y|0),{h:w,l:S}=k(this.Eh|0,this.El|0,w|0,S|0),{h:I,l:v}=k(this.Fh|0,this.Fl|0,I|0,v|0),{h:T,l:_}=k(this.Gh|0,this.Gl|0,T|0,_|0),{h:E,l:R}=k(this.Hh|0,this.Hl|0,E|0,R|0),this.set(o,r,s,c,u,i,x,y,w,S,I,v,T,_,E,R)}roundClean(){Bt(Y,z)}destroy(){Bt(this.buffer),this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)}}class en extends tn{Ah=M[0]|0;Al=M[1]|0;Bh=M[2]|0;Bl=M[3]|0;Ch=M[4]|0;Cl=M[5]|0;Dh=M[6]|0;Dl=M[7]|0;Eh=M[8]|0;El=M[9]|0;Fh=M[10]|0;Fl=M[11]|0;Gh=M[12]|0;Gl=M[13]|0;Hh=M[14]|0;Hl=M[15]|0;constructor(){super(64)}}const nn=$e(()=>new en,je(3));const fe=BigInt(0),Vt=BigInt(1);function St(e,t=""){if(typeof e!="boolean"){const n=t&&`"${t}" `;throw new Error(n+"expected boolean, got type="+typeof e)}return e}function rn(e){if(typeof e=="bigint"){if(!ft(e))throw new Error("positive bigint expected, got "+e)}else _t(e);return e}function ae(e){if(typeof e!="string")throw new Error("hex string expected, got "+typeof e);return e===""?fe:BigInt("0x"+e)}function on(e){return ae(Nt(e))}function at(e){return ae(Nt(vt(D(e)).reverse()))}function ue(e,t){_t(t),e=rn(e);const n=ie(e.toString(16).padStart(t*2,"0"));if(n.length!==t)throw new Error("number too large");return n}function sn(e,t){return ue(e,t).reverse()}function vt(e){return Uint8Array.from(e)}const ft=e=>typeof e=="bigint"&&fe<=e;function cn(e,t,n){return ft(e)&&ft(t)&&ft(n)&&t<=e&&e<n}function kt(e,t,n,o){if(!cn(t,n,o))throw new Error("expected valid "+e+": "+n+" <= n < "+o+", got "+t)}const fn=e=>(Vt<<BigInt(e))-Vt;function Tt(e,t={},n={}){if(!e||typeof e!="object")throw new Error("expected valid options object");function o(s,c,u){const i=e[s];if(u&&i===void 0)return;const x=typeof i;if(x!==c||i===null)throw new Error(`param "${s}" is invalid: expected ${c}, got ${x}`)}const r=(s,c)=>Object.entries(s).forEach(([u,i])=>o(u,i,c));r(t,!1),r(n,!0)}function Kt(e){const t=new WeakMap;return(n,...o)=>{const r=t.get(n);if(r!==void 0)return r;const s=e(n,...o);return t.set(n,s),s}}const $=BigInt(0),G=BigInt(1),Q=BigInt(2),he=BigInt(3),le=BigInt(4),de=BigInt(5),an=BigInt(7),be=BigInt(8),un=BigInt(9),ge=BigInt(16);function U(e,t){const n=e%t;return n>=$?n:t+n}function Z(e,t,n){let o=e;for(;t-- >$;)o*=o,o%=n;return o}function Yt(e,t){if(e===$)throw new Error("invert: expected non-zero number");if(t<=$)throw new Error("invert: expected positive modulus, got "+t);let n=U(e,t),o=t,r=$,s=G;for(;n!==$;){const u=o/n,i=o%n,x=r-s*u;o=n,n=i,r=s,s=x}if(o!==G)throw new Error("invert: does not exist");return U(r,t)}function Ot(e,t,n){if(!e.eql(e.sqr(t),n))throw new Error("Cannot find square root")}function we(e,t){const n=(e.ORDER+G)/le,o=e.pow(t,n);return Ot(e,o,t),o}function hn(e,t){const n=(e.ORDER-de)/be,o=e.mul(t,Q),r=e.pow(o,n),s=e.mul(t,r),c=e.mul(e.mul(s,Q),r),u=e.mul(s,e.sub(c,e.ONE));return Ot(e,u,t),u}function ln(e){const t=Ct(e),n=xe(e),o=n(t,t.neg(t.ONE)),r=n(t,o),s=n(t,t.neg(o)),c=(e+an)/ge;return(u,i)=>{let x=u.pow(i,c),y=u.mul(x,o);const w=u.mul(x,r),S=u.mul(x,s),I=u.eql(u.sqr(y),i),v=u.eql(u.sqr(w),i);x=u.cmov(x,y,I),y=u.cmov(S,w,v);const T=u.eql(u.sqr(y),i),_=u.cmov(x,y,T);return Ot(u,_,i),_}}function xe(e){if(e<he)throw new Error("sqrt is not defined for small field");let t=e-G,n=0;for(;t%Q===$;)t/=Q,n++;let o=Q;const r=Ct(e);for(;zt(r,o)===1;)if(o++>1e3)throw new Error("Cannot find square root: probably non-prime P");if(n===1)return we;let s=r.pow(o,t);const c=(t+G)/Q;return function(i,x){if(i.is0(x))return x;if(zt(i,x)!==1)throw new Error("Cannot find square root");let y=n,w=i.mul(i.ONE,s),S=i.pow(x,t),I=i.pow(x,c);for(;!i.eql(S,i.ONE);){if(i.is0(S))return i.ZERO;let v=1,T=i.sqr(S);for(;!i.eql(T,i.ONE);)if(v++,T=i.sqr(T),v===y)throw new Error("Cannot find square root");const _=G<<BigInt(y-v-1),E=i.pow(w,_);y=v,w=i.sqr(E),S=i.mul(S,w),I=i.mul(I,E)}return I}}function dn(e){return e%le===he?we:e%be===de?hn:e%ge===un?ln(e):xe(e)}const bn=(e,t)=>(U(e,t)&G)===G,gn=["create","isValid","is0","neg","inv","sqrt","sqr","eql","add","sub","mul","pow","div","addN","subN","mulN","sqrN"];function wn(e){const t={ORDER:"bigint",BYTES:"number",BITS:"number"},n=gn.reduce((o,r)=>(o[r]="function",o),t);return Tt(e,n),e}function xn(e,t,n){if(n<$)throw new Error("invalid exponent, negatives unsupported");if(n===$)return e.ONE;if(n===G)return t;let o=e.ONE,r=t;for(;n>$;)n&G&&(o=e.mul(o,r)),r=e.sqr(r),n>>=G;return o}function pe(e,t,n=!1){const o=new Array(t.length).fill(n?e.ZERO:void 0),r=t.reduce((c,u,i)=>e.is0(u)?c:(o[i]=c,e.mul(c,u)),e.ONE),s=e.inv(r);return t.reduceRight((c,u,i)=>e.is0(u)?c:(o[i]=e.mul(c,o[i]),e.mul(c,u)),s),o}function zt(e,t){const n=(e.ORDER-G)/Q,o=e.pow(t,n),r=e.eql(o,e.ONE),s=e.eql(o,e.ZERO),c=e.eql(o,e.neg(e.ONE));if(!r&&!s&&!c)throw new Error("invalid Legendre symbol result");return r?1:s?0:-1}function pn(e,t){t!==void 0&&_t(t);const n=t!==void 0?t:e.toString(2).length,o=Math.ceil(n/8);return{nBitLength:n,nByteLength:o}}class mn{ORDER;BITS;BYTES;isLE;ZERO=$;ONE=G;_lengths;_sqrt;_mod;constructor(t,n={}){if(t<=$)throw new Error("invalid field: expected ORDER > 0, got "+t);let o;this.isLE=!1,n!=null&&typeof n=="object"&&(typeof n.BITS=="number"&&(o=n.BITS),typeof n.sqrt=="function"&&(this.sqrt=n.sqrt),typeof n.isLE=="boolean"&&(this.isLE=n.isLE),n.allowedLengths&&(this._lengths=n.allowedLengths?.slice()),typeof n.modFromBytes=="boolean"&&(this._mod=n.modFromBytes));const{nBitLength:r,nByteLength:s}=pn(t,o);if(s>2048)throw new Error("invalid field: expected ORDER of <= 2048 bytes");this.ORDER=t,this.BITS=r,this.BYTES=s,this._sqrt=void 0,Object.preventExtensions(this)}create(t){return U(t,this.ORDER)}isValid(t){if(typeof t!="bigint")throw new Error("invalid field element: expected bigint, got "+typeof t);return $<=t&&t<this.ORDER}is0(t){return t===$}isValidNot0(t){return!this.is0(t)&&this.isValid(t)}isOdd(t){return(t&G)===G}neg(t){return U(-t,this.ORDER)}eql(t,n){return t===n}sqr(t){return U(t*t,this.ORDER)}add(t,n){return U(t+n,this.ORDER)}sub(t,n){return U(t-n,this.ORDER)}mul(t,n){return U(t*n,this.ORDER)}pow(t,n){return xn(this,t,n)}div(t,n){return U(t*Yt(n,this.ORDER),this.ORDER)}sqrN(t){return t*t}addN(t,n){return t+n}subN(t,n){return t-n}mulN(t,n){return t*n}inv(t){return Yt(t,this.ORDER)}sqrt(t){return this._sqrt||(this._sqrt=dn(this.ORDER)),this._sqrt(this,t)}toBytes(t){return this.isLE?sn(t,this.BYTES):ue(t,this.BYTES)}fromBytes(t,n=!1){D(t);const{_lengths:o,BYTES:r,isLE:s,ORDER:c,_mod:u}=this;if(o){if(!o.includes(t.length)||t.length>r)throw new Error("Field.fromBytes: expected "+o+" bytes, got "+t.length);const x=new Uint8Array(r);x.set(t,s?0:x.length-t.length),t=x}if(t.length!==r)throw new Error("Field.fromBytes: expected "+r+" bytes, got "+t.length);let i=s?at(t):on(t);if(u&&(i=U(i,c)),!n&&!this.isValid(i))throw new Error("invalid field element: outside of range 0..ORDER");return i}invertBatch(t){return pe(this,t)}cmov(t,n,o){return o?n:t}}function Ct(e,t={}){return new mn(e,t)}const ut=BigInt(0),Rt=BigInt(1);function Wt(e,t){const n=t.negate();return e?n:t}function gt(e,t){const n=pe(e.Fp,t.map(o=>o.Z));return t.map((o,r)=>e.fromAffine(o.toAffine(n[r])))}function me(e,t){if(!Number.isSafeInteger(e)||e<=0||e>t)throw new Error("invalid window size, expected [1.."+t+"], got W="+e)}function wt(e,t){me(e,t);const n=Math.ceil(t/e)+1,o=2**(e-1),r=2**e,s=fn(e),c=BigInt(e);return{windows:n,windowSize:o,mask:s,maxNumber:r,shiftBy:c}}function Xt(e,t,n){const{windowSize:o,mask:r,maxNumber:s,shiftBy:c}=n;let u=Number(e&r),i=e>>c;u>o&&(u-=s,i+=Rt);const x=t*o,y=x+Math.abs(u)-1,w=u===0,S=u<0,I=t%2!==0;return{nextN:i,offset:y,isZero:w,isNeg:S,isNegF:I,offsetF:x}}const xt=new WeakMap,ye=new WeakMap;function pt(e){return ye.get(e)||1}function Pt(e){if(e!==ut)throw new Error("invalid wNAF")}class yn{BASE;ZERO;Fn;bits;constructor(t,n){this.BASE=t.BASE,this.ZERO=t.ZERO,this.Fn=t.Fn,this.bits=n}_unsafeLadder(t,n,o=this.ZERO){let r=t;for(;n>ut;)n&Rt&&(o=o.add(r)),r=r.double(),n>>=Rt;return o}precomputeWindow(t,n){const{windows:o,windowSize:r}=wt(n,this.bits),s=[];let c=t,u=c;for(let i=0;i<o;i++){u=c,s.push(u);for(let x=1;x<r;x++)u=u.add(c),s.push(u);c=u.double()}return s}wNAF(t,n,o){if(!this.Fn.isValid(o))throw new Error("invalid scalar");let r=this.ZERO,s=this.BASE;const c=wt(t,this.bits);for(let u=0;u<c.windows;u++){const{nextN:i,offset:x,isZero:y,isNeg:w,isNegF:S,offsetF:I}=Xt(o,u,c);o=i,y?s=s.add(Wt(S,n[I])):r=r.add(Wt(w,n[x]))}return Pt(o),{p:r,f:s}}wNAFUnsafe(t,n,o,r=this.ZERO){const s=wt(t,this.bits);for(let c=0;c<s.windows&&o!==ut;c++){const{nextN:u,offset:i,isZero:x,isNeg:y}=Xt(o,c,s);if(o=u,!x){const w=n[i];r=r.add(y?w.negate():w)}}return Pt(o),r}getPrecomputes(t,n,o){let r=xt.get(n);return r||(r=this.precomputeWindow(n,t),t!==1&&(typeof o=="function"&&(r=o(r)),xt.set(n,r))),r}cached(t,n,o){const r=pt(t);return this.wNAF(r,this.getPrecomputes(r,t,o),n)}unsafe(t,n,o,r){const s=pt(t);return s===1?this._unsafeLadder(t,n,r):this.wNAFUnsafe(s,this.getPrecomputes(s,t,o),n,r)}createCache(t,n){me(n,this.bits),ye.set(t,n),xt.delete(t)}hasCache(t){return pt(t)!==1}}function Ft(e,t,n){if(t){if(t.ORDER!==e)throw new Error("Field.ORDER must match order: Fp == p, Fn == n");return wn(t),t}else return Ct(e,{isLE:n})}function En(e,t,n={},o){if(o===void 0&&(o=e==="edwards"),!t||typeof t!="object")throw new Error(`expected valid ${e} CURVE object`);for(const i of["p","n","h"]){const x=t[i];if(!(typeof x=="bigint"&&x>ut))throw new Error(`CURVE.${i} must be positive bigint`)}const r=Ft(t.p,n.Fp,o),s=Ft(t.n,n.Fn,o),u=["Gx","Gy","a","d"];for(const i of u)if(!r.isValid(t[i]))throw new Error(`CURVE.${i} must be valid field element of CURVE.Fp`);return t=Object.freeze(Object.assign({},t)),{CURVE:t,Fp:r,Fn:s}}function Bn(e,t){return function(o){const r=e(o);return{secretKey:r,publicKey:t(r)}}}const W=BigInt(0),H=BigInt(1),mt=BigInt(2),Sn=BigInt(8);function vn(e,t,n,o){const r=e.sqr(n),s=e.sqr(o),c=e.add(e.mul(t.a,r),s),u=e.add(e.ONE,e.mul(t.d,e.mul(r,s)));return e.eql(c,u)}function Rn(e,t={}){const n=En("edwards",e,t,t.FpFnLE),{Fp:o,Fn:r}=n;let s=n.CURVE;const{h:c}=s;Tt(t,{},{uvRatio:"function"});const u=mt<<BigInt(r.BYTES*8)-H,i=_=>o.create(_),x=t.uvRatio||((_,E)=>{try{return{isValid:!0,value:o.sqrt(o.div(_,E))}}catch{return{isValid:!1,value:W}}});if(!vn(o,s,s.Gx,s.Gy))throw new Error("bad curve params: generator point");function y(_,E,R=!1){const p=R?H:W;return kt("coordinate "+_,E,p,u),E}function w(_){if(!(_ instanceof v))throw new Error("EdwardsPoint expected")}const S=Kt((_,E)=>{const{X:R,Y:p,Z:N}=_,O=_.is0();E==null&&(E=O?Sn:o.inv(N));const a=i(R*E),h=i(p*E),f=o.mul(N,E);if(O)return{x:W,y:H};if(f!==H)throw new Error("invZ was invalid");return{x:a,y:h}}),I=Kt(_=>{const{a:E,d:R}=s;if(_.is0())throw new Error("bad point: ZERO");const{X:p,Y:N,Z:O,T:a}=_,h=i(p*p),f=i(N*N),l=i(O*O),d=i(l*l),b=i(h*E),g=i(l*i(b+f)),m=i(d+i(R*i(h*f)));if(g!==m)throw new Error("bad point: equation left != right (1)");const B=i(p*N),A=i(O*a);if(B!==A)throw new Error("bad point: equation left != right (2)");return!0});class v{static BASE=new v(s.Gx,s.Gy,H,i(s.Gx*s.Gy));static ZERO=new v(W,H,H,W);static Fp=o;static Fn=r;X;Y;Z;T;constructor(E,R,p,N){this.X=y("x",E),this.Y=y("y",R),this.Z=y("z",p,!0),this.T=y("t",N),Object.freeze(this)}static CURVE(){return s}static fromAffine(E){if(E instanceof v)throw new Error("extended point not allowed");const{x:R,y:p}=E||{};return y("x",R),y("y",p),new v(R,p,H,i(R*p))}static fromBytes(E,R=!1){const p=o.BYTES,{a:N,d:O}=s;E=vt(D(E,p,"point")),St(R,"zip215");const a=vt(E),h=E[p-1];a[p-1]=h&-129;const f=at(a),l=R?u:o.ORDER;kt("point.y",f,W,l);const d=i(f*f),b=i(d-H),g=i(O*d-N);let{isValid:m,value:B}=x(b,g);if(!m)throw new Error("bad point: invalid y coordinate");const A=(B&H)===H,C=(h&128)!==0;if(!R&&B===W&&C)throw new Error("bad point: x=0 and x_0=1");return C!==A&&(B=i(-B)),v.fromAffine({x:B,y:f})}static fromHex(E,R=!1){return v.fromBytes(ie(E),R)}get x(){return this.toAffine().x}get y(){return this.toAffine().y}precompute(E=8,R=!0){return T.createCache(this,E),R||this.multiply(mt),this}assertValidity(){I(this)}equals(E){w(E);const{X:R,Y:p,Z:N}=this,{X:O,Y:a,Z:h}=E,f=i(R*h),l=i(O*N),d=i(p*h),b=i(a*N);return f===l&&d===b}is0(){return this.equals(v.ZERO)}negate(){return new v(i(-this.X),this.Y,this.Z,i(-this.T))}double(){const{a:E}=s,{X:R,Y:p,Z:N}=this,O=i(R*R),a=i(p*p),h=i(mt*i(N*N)),f=i(E*O),l=R+p,d=i(i(l*l)-O-a),b=f+a,g=b-h,m=f-a,B=i(d*g),A=i(b*m),C=i(d*m),L=i(g*b);return new v(B,A,L,C)}add(E){w(E);const{a:R,d:p}=s,{X:N,Y:O,Z:a,T:h}=this,{X:f,Y:l,Z:d,T:b}=E,g=i(N*f),m=i(O*l),B=i(h*p*b),A=i(a*d),C=i((N+O)*(f+l)-g-m),L=A-B,q=A+B,J=i(m-R*g),rt=i(C*L),lt=i(q*J),Ut=i(C*J),Ht=i(L*q);return new v(rt,lt,Ht,Ut)}subtract(E){return this.add(E.negate())}multiply(E){if(!r.isValidNot0(E))throw new Error("invalid scalar: expected 1 <= sc < curve.n");const{p:R,f:p}=T.cached(this,E,N=>gt(v,N));return gt(v,[R,p])[0]}multiplyUnsafe(E,R=v.ZERO){if(!r.isValid(E))throw new Error("invalid scalar: expected 0 <= sc < curve.n");return E===W?v.ZERO:this.is0()||E===H?this:T.unsafe(this,E,p=>gt(v,p),R)}isSmallOrder(){return this.multiplyUnsafe(c).is0()}isTorsionFree(){return T.unsafe(this,s.n).is0()}toAffine(E){return S(this,E)}clearCofactor(){return c===H?this:this.multiplyUnsafe(c)}toBytes(){const{x:E,y:R}=this.toAffine(),p=o.toBytes(R);return p[p.length-1]|=E&H?128:0,p}toHex(){return Nt(this.toBytes())}toString(){return`<Point ${this.is0()?"ZERO":this.toHex()}>`}}const T=new yn(v,r.BITS);return v.BASE.precompute(8),v}function An(e,t,n={}){if(typeof t!="function")throw new Error('"hash" function param is required');Tt(n,{},{adjustScalarBytes:"function",randomBytes:"function",domain:"function",prehash:"function",mapToCurve:"function"});const{prehash:o}=n,{BASE:r,Fp:s,Fn:c}=e,u=n.randomBytes||Ze,i=n.adjustScalarBytes||(f=>f),x=n.domain||((f,l,d)=>{if(St(d,"phflag"),l.length||d)throw new Error("Contexts/pre-hash are not supported");return f});function y(f){return c.create(at(f))}function w(f){const l=p.secretKey;D(f,p.secretKey,"secretKey");const d=D(t(f),2*l,"hashedSecretKey"),b=i(d.slice(0,l)),g=d.slice(l,2*l),m=y(b);return{head:b,prefix:g,scalar:m}}function S(f){const{head:l,prefix:d,scalar:b}=w(f),g=r.multiply(b),m=g.toBytes();return{head:l,prefix:d,scalar:b,point:g,pointBytes:m}}function I(f){return S(f).pointBytes}function v(f=Uint8Array.of(),...l){const d=Gt(...l);return y(t(x(d,D(f,void 0,"context"),!!o)))}function T(f,l,d={}){f=D(f,void 0,"message"),o&&(f=o(f));const{prefix:b,scalar:g,pointBytes:m}=S(l),B=v(d.context,b,f),A=r.multiply(B).toBytes(),C=v(d.context,A,m,f),L=c.create(B+C*g);if(!c.isValid(L))throw new Error("sign failed: invalid s");const q=Gt(A,c.toBytes(L));return D(q,p.signature,"result")}const _={zip215:!0};function E(f,l,d,b=_){const{context:g,zip215:m}=b,B=p.signature;f=D(f,B,"signature"),l=D(l,void 0,"message"),d=D(d,p.publicKey,"publicKey"),m!==void 0&&St(m,"zip215"),o&&(l=o(l));const A=B/2,C=f.subarray(0,A),L=at(f.subarray(A,B));let q,J,rt;try{q=e.fromBytes(d,m),J=e.fromBytes(C,m),rt=r.multiplyUnsafe(L)}catch{return!1}if(!m&&q.isSmallOrder())return!1;const lt=v(g,J.toBytes(),q.toBytes(),l);return J.add(q.multiplyUnsafe(lt)).subtract(rt).clearCofactor().is0()}const R=s.BYTES,p={secretKey:R,publicKey:R,signature:2*R,seed:R};function N(f=u(p.seed)){return D(f,p.seed,"seed")}function O(f){return oe(f)&&f.length===c.BYTES}function a(f,l){try{return!!e.fromBytes(f,l)}catch{return!1}}const h={getExtendedPublicKey:S,randomSecretKey:N,isValidSecretKey:O,isValidPublicKey:a,toMontgomery(f){const{y:l}=e.fromBytes(f),d=p.publicKey,b=d===32;if(!b&&d!==57)throw new Error("only defined for 25519 and 448");const g=b?s.div(H+l,H-l):s.div(l-H,l+H);return s.toBytes(g)},toMontgomerySecret(f){const l=p.secretKey;D(f,l);const d=t(f.subarray(0,l));return i(d).subarray(0,l)}};return Object.freeze({keygen:Bn(N,I),getPublicKey:I,sign:T,verify:E,utils:h,Point:e,lengths:p})}const In=BigInt(1),Qt=BigInt(2),_n=BigInt(5),Nn=BigInt(8),Lt=BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed"),Tn={p:Lt,n:BigInt("0x1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed"),h:Nn,a:BigInt("0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffec"),d:BigInt("0x52036cee2b6ffe738cc740797779e89800700a4d4141d8ab75eb4dca135978a3"),Gx:BigInt("0x216936d3cd6e53fec0a4e231fdd6dc5c692cc7609525a7b2c9562d608f25d51a"),Gy:BigInt("0x6666666666666666666666666666666666666666666666666666666666666658")};function On(e){const t=BigInt(10),n=BigInt(20),o=BigInt(40),r=BigInt(80),s=Lt,u=e*e%s*e%s,i=Z(u,Qt,s)*u%s,x=Z(i,In,s)*e%s,y=Z(x,_n,s)*x%s,w=Z(y,t,s)*y%s,S=Z(w,n,s)*w%s,I=Z(S,o,s)*S%s,v=Z(I,r,s)*I%s,T=Z(v,r,s)*I%s,_=Z(T,t,s)*y%s;return{pow_p_5_8:Z(_,Qt,s)*e%s,b2:u}}function Cn(e){return e[0]&=248,e[31]&=127,e[31]|=64,e}const Jt=BigInt("19681161376707505956807079304988542015446066515923890162744021073123829784752");function Ln(e,t){const n=Lt,o=U(t*t*t,n),r=U(o*o*t,n),s=On(e*r).pow_p_5_8;let c=U(e*o*s,n);const u=U(t*c*c,n),i=c,x=U(c*Jt,n),y=u===e,w=u===U(-e,n),S=u===U(-e*Jt,n);return y&&(c=i),(w||S)&&(c=x),bn(c,n)&&(c=U(-c,n)),{isValid:y||w,value:c}}const Un=Rn(Tn,{uvRatio:Ln});function Hn(e){return An(Un,nn,Object.assign({adjustScalarBytes:Cn},e))}const Dn=Hn({});function qn(e){return e instanceof Uint8Array||ArrayBuffer.isView(e)&&e.constructor.name==="Uint8Array"}function ht(e,...t){if(!qn(e))throw new Error("Uint8Array expected");if(t.length>0&&!t.includes(e.length))throw new Error("Uint8Array expected of length "+t+", got length="+e.length)}function te(e,t=!0){if(e.destroyed)throw new Error("Hash instance has been destroyed");if(t&&e.finished)throw new Error("Hash#digest() has already been called")}function Mn(e,t){ht(e);const n=t.outputLen;if(e.length<n)throw new Error("digestInto() expects output buffer of length at least "+n)}function At(...e){for(let t=0;t<e.length;t++)e[t].fill(0)}function yt(e){return new DataView(e.buffer,e.byteOffset,e.byteLength)}function j(e,t){return e<<32-t|e>>>t}function Gn(e){if(typeof e!="string")throw new Error("string expected");return new Uint8Array(new TextEncoder().encode(e))}function Ee(e){return typeof e=="string"&&(e=Gn(e)),ht(e),e}class $n{}function Zn(e){const t=o=>e().update(Ee(o)).digest(),n=e();return t.outputLen=n.outputLen,t.blockLen=n.blockLen,t.create=()=>e(),t}function jn(e,t,n,o){if(typeof e.setBigUint64=="function")return e.setBigUint64(t,n,o);const r=BigInt(32),s=BigInt(4294967295),c=Number(n>>r&s),u=Number(n&s),i=o?4:0,x=o?0:4;e.setUint32(t+i,c,o),e.setUint32(t+x,u,o)}function Vn(e,t,n){return e&t^~e&n}function kn(e,t,n){return e&t^e&n^t&n}class Kn extends $n{constructor(t,n,o,r){super(),this.finished=!1,this.length=0,this.pos=0,this.destroyed=!1,this.blockLen=t,this.outputLen=n,this.padOffset=o,this.isLE=r,this.buffer=new Uint8Array(t),this.view=yt(this.buffer)}update(t){te(this),t=Ee(t),ht(t);const{view:n,buffer:o,blockLen:r}=this,s=t.length;for(let c=0;c<s;){const u=Math.min(r-this.pos,s-c);if(u===r){const i=yt(t);for(;r<=s-c;c+=r)this.process(i,c);continue}o.set(t.subarray(c,c+u),this.pos),this.pos+=u,c+=u,this.pos===r&&(this.process(n,0),this.pos=0)}return this.length+=t.length,this.roundClean(),this}digestInto(t){te(this),Mn(t,this),this.finished=!0;const{buffer:n,view:o,blockLen:r,isLE:s}=this;let{pos:c}=this;n[c++]=128,At(this.buffer.subarray(c)),this.padOffset>r-c&&(this.process(o,0),c=0);for(let w=c;w<r;w++)n[w]=0;jn(o,r-8,BigInt(this.length*8),s),this.process(o,0);const u=yt(t),i=this.outputLen;if(i%4)throw new Error("_sha2: outputLen should be aligned to 32bit");const x=i/4,y=this.get();if(x>y.length)throw new Error("_sha2: outputLen bigger than state");for(let w=0;w<x;w++)u.setUint32(4*w,y[w],s)}digest(){const{buffer:t,outputLen:n}=this;this.digestInto(t);const o=t.slice(0,n);return this.destroy(),o}_cloneInto(t){t||(t=new this.constructor),t.set(...this.get());const{blockLen:n,buffer:o,length:r,finished:s,destroyed:c,pos:u}=this;return t.destroyed=c,t.finished=s,t.length=r,t.pos=u,r%n&&t.buffer.set(o),t}clone(){return this._cloneInto()}}const X=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]),Yn=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),P=new Uint32Array(64);class zn extends Kn{constructor(t=32){super(64,t,8,!1),this.A=X[0]|0,this.B=X[1]|0,this.C=X[2]|0,this.D=X[3]|0,this.E=X[4]|0,this.F=X[5]|0,this.G=X[6]|0,this.H=X[7]|0}get(){const{A:t,B:n,C:o,D:r,E:s,F:c,G:u,H:i}=this;return[t,n,o,r,s,c,u,i]}set(t,n,o,r,s,c,u,i){this.A=t|0,this.B=n|0,this.C=o|0,this.D=r|0,this.E=s|0,this.F=c|0,this.G=u|0,this.H=i|0}process(t,n){for(let w=0;w<16;w++,n+=4)P[w]=t.getUint32(n,!1);for(let w=16;w<64;w++){const S=P[w-15],I=P[w-2],v=j(S,7)^j(S,18)^S>>>3,T=j(I,17)^j(I,19)^I>>>10;P[w]=T+P[w-7]+v+P[w-16]|0}let{A:o,B:r,C:s,D:c,E:u,F:i,G:x,H:y}=this;for(let w=0;w<64;w++){const S=j(u,6)^j(u,11)^j(u,25),I=y+S+Vn(u,i,x)+Yn[w]+P[w]|0,T=(j(o,2)^j(o,13)^j(o,22))+kn(o,r,s)|0;y=x,x=i,i=u,u=c+I|0,c=s,s=r,r=o,o=I+T|0}o=o+this.A|0,r=r+this.B|0,s=s+this.C|0,c=c+this.D|0,u=u+this.E|0,i=i+this.F|0,x=x+this.G|0,y=y+this.H|0,this.set(o,r,s,c,u,i,x,y)}roundClean(){At(P)}destroy(){this.set(0,0,0,0,0,0,0,0),At(this.buffer)}}const Be=Zn(()=>new zn),Wn=Be,Xn="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";function Pn(e){if(e.length!==16)throw new Error(`Invalid seed length: expected 16, got ${e.length}`);const t=Wn(e),n=Dn.getPublicKey(t),o=new Uint8Array(64);return o.set(t,0),o.set(n,32),K.wipeBytes(t),{publicKey:n,secretKey:o}}function Fn(e){const t=Pn(e),n=t.publicKey;return K.wipeBytes(t.secretKey),n}function Qn(e){if(e.length!==32)throw new Error(`Invalid public key length: expected 32, got ${e.length}`);return Jn(e)}function Jn(e){let t=0;for(let r=0;r<e.length&&e[r]===0;r++)t++;let n=0n;for(let r=0;r<e.length;r++)n=n*256n+BigInt(e[r]);let o="";for(;n>0n;){const r=Number(n%58n);o=Xn[r]+o,n=n/58n}return"1".repeat(t)+o}const tr=2,er=3;function nr(e){if(e.length!==16)throw new Error(`Invalid seed length: expected 16, got ${e.length}`);const t=It(e),n=re.share(t,er,tr);if(n.length!==3)throw new Error(`Unexpected share count: ${n.length}`);const o=Et(n[0]),r=Et(n[1]),s=Et(n[2]);return{shareA:K.toShamirShare(o),shareB:K.toShamirShare(r),shareC:K.toShamirShare(s)}}function rr(e,t,n){const o=ee(e),r=ee(t);try{const s=re.combine([o,r]),c=Se(s);if(c.length!==16)throw new Error(`Reconstructed seed has wrong length: ${c.length}`);return K.toSeed(c)}catch(s){throw s instanceof Error&&s.message.startsWith("Reconstructed seed")||s instanceof Error&&s.message.startsWith("Invalid expectedPublicKey")||s instanceof Error&&s.message.startsWith("Reconstructed seed does not match")?s:new Error("Failed to reconstruct seed from shares")}}function It(e){return Array.from(e).map(t=>t.toString(16).padStart(2,"0")).join("")}function Se(e){if(!/^[0-9a-fA-F]*$/.test(e))throw new Error("Invalid hex string: contains non-hex characters");if(e.length%2!==0)throw new Error(`Invalid hex string: length ${e.length} is odd (must be even)`);const t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}function Et(e){const t=e.length%2!==0,n=t?"0"+e:e,o=Se(n),r=new Uint8Array(1+o.length);return r[0]=t?1:0,r.set(o,1),r}function ee(e){const t=e[0];if(t===0||t===1){const o=t===1,r=e.subarray(1),s=It(r),c=o?s.substring(1):s;if(/^[0-9a-f]/.test(c))return c}const n=It(e);return n.startsWith("0")&&!n.startsWith("00")?n.substring(1):n}exports.abytes=ht;exports.argon2DeriveInWorker=Ae;exports.combineShares=rr;exports.getDefaultExportFromCjs=ne;exports.getPublicKeyFromSeed=Fn;exports.publicKeyToBase58=Qn;exports.sha256=Be;exports.splitSecret=nr;