@b3dotfun/sdk 0.1.69-alpha.23 → 0.1.69-alpha.24

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 (42) hide show
  1. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
  2. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +2 -2
  3. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
  4. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.js +85 -0
  5. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
  6. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -2
  7. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
  8. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +2 -2
  9. package/dist/cjs/global-account/react/components/index.d.ts +1 -0
  10. package/dist/cjs/global-account/react/components/index.js +5 -3
  11. package/dist/cjs/global-account/react/hooks/useBetterAuth.d.ts +1 -1
  12. package/dist/cjs/global-account/react/hooks/useBetterAuth.js +5 -4
  13. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +2 -0
  14. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
  15. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +2 -2
  16. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
  17. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.js +82 -0
  18. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
  19. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -2
  20. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
  21. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +2 -2
  22. package/dist/esm/global-account/react/components/index.d.ts +1 -0
  23. package/dist/esm/global-account/react/components/index.js +1 -0
  24. package/dist/esm/global-account/react/hooks/useBetterAuth.d.ts +1 -1
  25. package/dist/esm/global-account/react/hooks/useBetterAuth.js +5 -4
  26. package/dist/esm/global-account/react/stores/useModalStore.d.ts +2 -0
  27. package/dist/styles/index.css +1 -1
  28. package/dist/types/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
  29. package/dist/types/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
  30. package/dist/types/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
  31. package/dist/types/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
  32. package/dist/types/global-account/react/components/index.d.ts +1 -0
  33. package/dist/types/global-account/react/hooks/useBetterAuth.d.ts +1 -1
  34. package/dist/types/global-account/react/stores/useModalStore.d.ts +2 -0
  35. package/package.json +1 -1
  36. package/src/global-account/react/components/SignInWithB3/BetterAuthSignIn.tsx +7 -1
  37. package/src/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.tsx +155 -0
  38. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +8 -1
  39. package/src/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.tsx +4 -2
  40. package/src/global-account/react/components/index.ts +5 -0
  41. package/src/global-account/react/hooks/useBetterAuth.ts +5 -4
  42. package/src/global-account/react/stores/useModalStore.ts +2 -0
@@ -10,6 +10,11 @@ export interface BetterAuthSignInProps {
10
10
  showEmail?: boolean;
11
11
  /** URL to redirect to after password reset link is clicked. Token is appended as ?token=... */
12
12
  passwordResetRedirectTo?: string;
13
+ /**
14
+ * URL Better Auth redirects to after server-side email verification. Render
15
+ * `BetterAuthVerifyEmail` at this route so the user gets a confirmation page.
16
+ */
17
+ verifyEmailRedirectTo?: string;
13
18
  /** Called after successful authentication */
14
19
  onSuccess?: () => void;
15
20
  /** Called on authentication error */
@@ -31,4 +36,4 @@ export interface BetterAuthSignInProps {
31
36
  * />
32
37
  * ```
33
38
  */
34
- export declare function BetterAuthSignIn({ title, subtitle, socialProviders, showEmail, passwordResetRedirectTo, onSuccess, onError, className, }: BetterAuthSignInProps): import("react/jsx-runtime").JSX.Element | null;
39
+ export declare function BetterAuthSignIn({ title, subtitle, socialProviders, showEmail, passwordResetRedirectTo, verifyEmailRedirectTo, onSuccess, onError, className, }: BetterAuthSignInProps): import("react/jsx-runtime").JSX.Element | null;
@@ -31,7 +31,7 @@ const DEFAULT_SOCIAL_PROVIDERS = [
31
31
  * />
32
32
  * ```
33
33
  */
34
- function BetterAuthSignIn({ title, subtitle = "Enter your credentials to access your account", socialProviders = DEFAULT_SOCIAL_PROVIDERS.map(p => p.id), showEmail = true, passwordResetRedirectTo, onSuccess, onError, className, }) {
34
+ function BetterAuthSignIn({ title, subtitle = "Enter your credentials to access your account", socialProviders = DEFAULT_SOCIAL_PROVIDERS.map(p => p.id), showEmail = true, passwordResetRedirectTo, verifyEmailRedirectTo, onSuccess, onError, className, }) {
35
35
  const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = (0, useBetterAuth_1.useBetterAuth)();
36
36
  const isAuthenticated = (0, react_1.useAuthStore)(state => state.isAuthenticated);
37
37
  const isAuthenticating = (0, react_1.useAuthStore)(state => state.isAuthenticating);
@@ -101,7 +101,7 @@ function BetterAuthSignIn({ title, subtitle = "Enter your credentials to access
101
101
  setIsLoading(true);
102
102
  setError(null);
103
103
  if (mode === "sign-up") {
104
- await signUpWithEmail(normalizedEmail, password, name.trim());
104
+ await signUpWithEmail(normalizedEmail, password, name.trim(), verifyEmailRedirectTo);
105
105
  }
106
106
  else {
107
107
  await signInWithEmail(normalizedEmail, password);
@@ -0,0 +1,37 @@
1
+ export type BetterAuthVerifyEmailState = "success" | "expired" | "invalid" | "already-verified" | "error";
2
+ export interface BetterAuthVerifyEmailProps {
3
+ /**
4
+ * Error code from the callback URL's `?error=` query param. Pass `null` /
5
+ * `undefined` when the user landed here cleanly (successful verification).
6
+ * Better Auth appends this param when server-side verification fails.
7
+ */
8
+ errorCode?: string | null;
9
+ /** Called when the user clicks the "Go to sign in" button. */
10
+ onGoToSignIn?: () => void;
11
+ /** Fallback href used when `onGoToSignIn` is not provided. Defaults to "/login". */
12
+ signInHref?: string;
13
+ /** Optional override for the success headline. */
14
+ successTitle?: string;
15
+ /** Optional override for the success body text. */
16
+ successMessage?: string;
17
+ /** Optional class name for the root container. */
18
+ className?: string;
19
+ }
20
+ /**
21
+ * Standalone email-verification confirmation page. Render on the route you
22
+ * set as `callbackURL` when calling `betterAuthClient.sendVerificationEmail`
23
+ * (or the `verifyCallbackURL` arg on `useBetterAuth().signUpWithEmail`).
24
+ *
25
+ * Better Auth verifies the token server-side before redirecting here. This
26
+ * component only displays the outcome based on the `?error=` query param.
27
+ *
28
+ * Usage:
29
+ * ```tsx
30
+ * const error = new URLSearchParams(window.location.search).get("error");
31
+ * <BetterAuthVerifyEmail
32
+ * errorCode={error}
33
+ * onGoToSignIn={() => router.push("/login")}
34
+ * />
35
+ * ```
36
+ */
37
+ export declare function BetterAuthVerifyEmail({ errorCode, onGoToSignIn, signInHref, successTitle, successMessage, className, }: BetterAuthVerifyEmailProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BetterAuthVerifyEmail = BetterAuthVerifyEmail;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("../../../../global-account/react");
6
+ const debug_1 = require("../../../../shared/utils/debug");
7
+ const debug = (0, debug_1.debugB3React)("BetterAuthVerifyEmail");
8
+ function classifyError(code) {
9
+ if (!code)
10
+ return "success";
11
+ const normalized = code.toLowerCase();
12
+ // Exact matches for Better Auth's documented verification error codes.
13
+ if (normalized === "expired_token")
14
+ return "expired";
15
+ if (normalized === "invalid_token")
16
+ return "invalid";
17
+ if (normalized === "already_verified" || normalized === "email_already_verified")
18
+ return "already-verified";
19
+ // Loose fallbacks for close variants. Order matters — check "already" before
20
+ // "verified" so `email_already_verified` maps to already-verified, not invalid.
21
+ if (normalized.includes("expired"))
22
+ return "expired";
23
+ if (normalized.includes("already"))
24
+ return "already-verified";
25
+ if (normalized.includes("invalid"))
26
+ return "invalid";
27
+ return "error";
28
+ }
29
+ const COPY = {
30
+ success: {
31
+ title: "Email verified",
32
+ message: "Your email is confirmed. You can now sign in to your account.",
33
+ },
34
+ expired: {
35
+ title: "Link expired",
36
+ message: "This verification link has expired. Request a new one from the sign-in page.",
37
+ },
38
+ invalid: {
39
+ title: "Invalid link",
40
+ message: "This verification link is invalid or has already been used. Try signing in or request a new link.",
41
+ },
42
+ "already-verified": {
43
+ title: "Already verified",
44
+ message: "Your email was already confirmed. You can sign in now.",
45
+ },
46
+ error: {
47
+ title: "Verification failed",
48
+ message: "We couldn't verify your email. Request a new link from the sign-in page.",
49
+ },
50
+ };
51
+ /**
52
+ * Standalone email-verification confirmation page. Render on the route you
53
+ * set as `callbackURL` when calling `betterAuthClient.sendVerificationEmail`
54
+ * (or the `verifyCallbackURL` arg on `useBetterAuth().signUpWithEmail`).
55
+ *
56
+ * Better Auth verifies the token server-side before redirecting here. This
57
+ * component only displays the outcome based on the `?error=` query param.
58
+ *
59
+ * Usage:
60
+ * ```tsx
61
+ * const error = new URLSearchParams(window.location.search).get("error");
62
+ * <BetterAuthVerifyEmail
63
+ * errorCode={error}
64
+ * onGoToSignIn={() => router.push("/login")}
65
+ * />
66
+ * ```
67
+ */
68
+ function BetterAuthVerifyEmail({ errorCode, onGoToSignIn, signInHref = "/login", successTitle, successMessage, className, }) {
69
+ const state = classifyError(errorCode);
70
+ const isSuccess = state === "success" || state === "already-verified";
71
+ const copy = COPY[state];
72
+ const title = isSuccess && successTitle ? successTitle : copy.title;
73
+ const message = isSuccess && successMessage ? successMessage : copy.message;
74
+ debug("Rendering verify-email state", { state, errorCode });
75
+ const handleClick = () => {
76
+ if (onGoToSignIn) {
77
+ onGoToSignIn();
78
+ return;
79
+ }
80
+ if (typeof window !== "undefined") {
81
+ window.location.href = signInHref;
82
+ }
83
+ };
84
+ return ((0, jsx_runtime_1.jsx)("div", { className: `w-full max-w-[400px] px-6 ${className || ""}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "space-y-6 text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: `mx-auto flex h-12 w-12 items-center justify-center rounded-full ${isSuccess ? "bg-green-100" : "bg-red-100"}`, children: isSuccess ? ((0, jsx_runtime_1.jsx)("svg", { className: "h-6 w-6 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })) : ((0, jsx_runtime_1.jsx)("svg", { className: "h-6 w-6 text-red-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: title }), (0, jsx_runtime_1.jsx)("p", { className: "mt-3 text-[15px] text-gray-500 dark:text-gray-400", children: message })] }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: handleClick, className: "h-11 w-full bg-gray-900 text-[15px] font-medium text-white hover:bg-gray-800 dark:bg-white dark:text-gray-900 dark:hover:bg-gray-100", children: isSuccess ? "Go to sign in" : "Back to sign in" })] }) }));
85
+ }
@@ -3,4 +3,4 @@ import { SignInWithB3ModalProps } from "../../../../global-account/react";
3
3
  * Component that manages the authentication flow for Sign In With B3
4
4
  * Handles different login providers, authentication steps, and session key management
5
5
  */
6
- export declare function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin, source, signersEnabled, }: SignInWithB3ModalProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export declare function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin, source, signersEnabled, verifyEmailRedirectTo, }: SignInWithB3ModalProps): import("react/jsx-runtime").JSX.Element | null;
@@ -16,7 +16,7 @@ const MAX_REFETCH_ATTEMPTS = 20;
16
16
  * Component that manages the authentication flow for Sign In With B3
17
17
  * Handles different login providers, authentication steps, and session key management
18
18
  */
19
- function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin = false, source = "signInWithB3Button", signersEnabled = false, }) {
19
+ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin = false, source = "signInWithB3Button", signersEnabled = false, verifyEmailRedirectTo, }) {
20
20
  const { automaticallySetFirstEoa, authStrategy } = (0, react_1.useB3Config)();
21
21
  // skipAutoConnect: this component intentionally logs out on mount to show a fresh login screen.
22
22
  // AuthenticationProvider is the sole owner of useAutoConnect to avoid competing auth cycles.
@@ -247,7 +247,7 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
247
247
  // Better Auth manages its own loading/verification states internally.
248
248
  // Don't gate on isAuthenticating — it would unmount the component
249
249
  // and lose verification state when setIsAuthenticating(false) fires.
250
- content = (0, jsx_runtime_1.jsx)(LoginStepBetterAuth_1.LoginStepBetterAuth, { onSuccess: () => handleLoginSuccess({}), onError: onError });
250
+ content = ((0, jsx_runtime_1.jsx)(LoginStepBetterAuth_1.LoginStepBetterAuth, { onSuccess: () => handleLoginSuccess({}), onError: onError, verifyEmailRedirectTo: verifyEmailRedirectTo }));
251
251
  }
252
252
  else if (!readyToShowLogin || isAuthenticating || isFetchingSigners) {
253
253
  content = ((0, jsx_runtime_1.jsx)(LoginStep_1.LoginStepContainer, { partnerId: partnerId, children: (0, jsx_runtime_1.jsx)("div", { className: "my-8 flex min-h-[350px] items-center justify-center", children: (0, jsx_runtime_1.jsx)(react_1.Loading, { variant: "white", size: "lg" }) }) }));
@@ -1,6 +1,8 @@
1
1
  interface LoginStepBetterAuthProps {
2
2
  onSuccess?: () => void;
3
3
  onError?: (error: Error) => Promise<void>;
4
+ /** URL Better Auth redirects to after server-side email verification. */
5
+ verifyEmailRedirectTo?: string;
4
6
  }
5
- export declare function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function LoginStepBetterAuth({ onSuccess, onError, verifyEmailRedirectTo }: LoginStepBetterAuthProps): import("react/jsx-runtime").JSX.Element;
6
8
  export {};
@@ -17,7 +17,7 @@ const SOCIAL_PROVIDERS = [
17
17
  { id: "microsoft", label: "Microsoft" },
18
18
  { id: "slack", label: "Slack" },
19
19
  ];
20
- function LoginStepBetterAuth({ onSuccess, onError }) {
20
+ function LoginStepBetterAuth({ onSuccess, onError, verifyEmailRedirectTo }) {
21
21
  const { partnerId } = (0, react_1.useB3Config)();
22
22
  const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = (0, useBetterAuth_1.useBetterAuth)();
23
23
  const [mode, setMode] = (0, react_2.useState)("sign-in");
@@ -48,7 +48,7 @@ function LoginStepBetterAuth({ onSuccess, onError }) {
48
48
  setError(null);
49
49
  if (mode === "sign-up") {
50
50
  debug("Signing up", { email: normalizedEmail, name: name.trim() });
51
- await signUpWithEmail(normalizedEmail, password, name.trim());
51
+ await signUpWithEmail(normalizedEmail, password, name.trim(), verifyEmailRedirectTo);
52
52
  }
53
53
  else {
54
54
  debug("Signing in", { email: normalizedEmail });
@@ -8,6 +8,7 @@ export { useB3Config } from "./B3Provider/useB3Config";
8
8
  export { StyleRoot } from "./StyleRoot";
9
9
  export { BetterAuthResetPassword, type BetterAuthResetPasswordProps } from "./SignInWithB3/BetterAuthResetPassword";
10
10
  export { BetterAuthSignIn, type BetterAuthSignInProps } from "./SignInWithB3/BetterAuthSignIn";
11
+ export { BetterAuthVerifyEmail, type BetterAuthVerifyEmailProps, type BetterAuthVerifyEmailState, } from "./SignInWithB3/BetterAuthVerifyEmail";
11
12
  export { AuthButton } from "./SignInWithB3/components/AuthButton";
12
13
  export { PermissionItem } from "./SignInWithB3/components/PermissionItem";
13
14
  export { WalletRow } from "./SignInWithB3/components/WalletRow";
@@ -3,9 +3,9 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.DialogClose = exports.Dialog = exports.CommandShortcut = exports.CommandSeparator = exports.CommandList = exports.CommandItem = exports.CommandInput = exports.CommandGroup = exports.CommandEmpty = exports.CommandDialog = exports.Command = exports.buttonVariants = exports.Button = exports.badgeVariants = exports.Badge = exports.WalletConnectorIcon = exports.StaggeredFadeLoader = exports.CopyToClipboard = exports.ClientOnly = exports.customButtonVariants = exports.CustomButton = exports.SingleUserSearchSelector = exports.SendERC20Button = exports.SendETHButton = exports.MintButton = exports.AccountAssets = exports.RequestPermissionsButton = exports.RequestPermissions = exports.IPFSMediaRenderer = exports.Send = exports.Deposit = exports.ManageAccount = exports.isWalletType = exports.getConnectOptionsFromStrategy = exports.LoginStepContainer = exports.SignInWithB3Privy = exports.SignInWithB3Flow = exports.SignInWithB3 = exports.WalletRow = exports.PermissionItem = exports.AuthButton = exports.BetterAuthSignIn = exports.BetterAuthResetPassword = exports.StyleRoot = exports.useB3Config = exports.useB3Account = exports.useB3 = exports.RelayKitProviderWrapper = exports.B3Provider = exports.B3DynamicModal = void 0;
7
- exports.TransitionPanel = exports.TooltipTrigger = exports.TooltipProvider = exports.TooltipContent = exports.Tooltip = exports.TextShimmer = exports.TextLoop = exports.TabTrigger = exports.TabsTransitionWrapper = exports.TabsList = exports.TabsContent = exports.Tabs = exports.TabTriggerPrimitive = exports.TabsPrimitive = exports.TabsListPrimitive = exports.TabsContentPrimitive = exports.Skeleton = exports.ShinyButton = exports.ScrollBar = exports.ScrollArea = exports.PopoverTrigger = exports.PopoverContent = exports.Popover = exports.Loading = exports.Input = exports.GlareCardRounded = exports.GlareCard = exports.DropdownMenuTrigger = exports.DropdownMenuSeparator = exports.DropdownMenuItem = exports.DropdownMenuContent = exports.DropdownMenu = exports.DrawerTrigger = exports.DrawerTitle = exports.DrawerPortal = exports.DrawerOverlay = exports.DrawerHeader = exports.DrawerFooter = exports.DrawerDescription = exports.DrawerContent = exports.DrawerClose = exports.Drawer = exports.DialogTrigger = exports.DialogTitle = exports.DialogPortal = exports.DialogOverlay = exports.DialogHeader = exports.DialogFooter = exports.DialogDescription = exports.DialogContent = void 0;
8
- exports.WalletImage = exports.useToastContext = exports.ToastProvider = exports.ToastContainer = exports.Toast = exports.toast = exports.AnimatedLottie = void 0;
6
+ exports.Dialog = exports.CommandShortcut = exports.CommandSeparator = exports.CommandList = exports.CommandItem = exports.CommandInput = exports.CommandGroup = exports.CommandEmpty = exports.CommandDialog = exports.Command = exports.buttonVariants = exports.Button = exports.badgeVariants = exports.Badge = exports.WalletConnectorIcon = exports.StaggeredFadeLoader = exports.CopyToClipboard = exports.ClientOnly = exports.customButtonVariants = exports.CustomButton = exports.SingleUserSearchSelector = exports.SendERC20Button = exports.SendETHButton = exports.MintButton = exports.AccountAssets = exports.RequestPermissionsButton = exports.RequestPermissions = exports.IPFSMediaRenderer = exports.Send = exports.Deposit = exports.ManageAccount = exports.isWalletType = exports.getConnectOptionsFromStrategy = exports.LoginStepContainer = exports.SignInWithB3Privy = exports.SignInWithB3Flow = exports.SignInWithB3 = exports.WalletRow = exports.PermissionItem = exports.AuthButton = exports.BetterAuthVerifyEmail = exports.BetterAuthSignIn = exports.BetterAuthResetPassword = exports.StyleRoot = exports.useB3Config = exports.useB3Account = exports.useB3 = exports.RelayKitProviderWrapper = exports.B3Provider = exports.B3DynamicModal = void 0;
7
+ exports.TooltipTrigger = exports.TooltipProvider = exports.TooltipContent = exports.Tooltip = exports.TextShimmer = exports.TextLoop = exports.TabTrigger = exports.TabsTransitionWrapper = exports.TabsList = exports.TabsContent = exports.Tabs = exports.TabTriggerPrimitive = exports.TabsPrimitive = exports.TabsListPrimitive = exports.TabsContentPrimitive = exports.Skeleton = exports.ShinyButton = exports.ScrollBar = exports.ScrollArea = exports.PopoverTrigger = exports.PopoverContent = exports.Popover = exports.Loading = exports.Input = exports.GlareCardRounded = exports.GlareCard = exports.DropdownMenuTrigger = exports.DropdownMenuSeparator = exports.DropdownMenuItem = exports.DropdownMenuContent = exports.DropdownMenu = exports.DrawerTrigger = exports.DrawerTitle = exports.DrawerPortal = exports.DrawerOverlay = exports.DrawerHeader = exports.DrawerFooter = exports.DrawerDescription = exports.DrawerContent = exports.DrawerClose = exports.Drawer = exports.DialogTrigger = exports.DialogTitle = exports.DialogPortal = exports.DialogOverlay = exports.DialogHeader = exports.DialogFooter = exports.DialogDescription = exports.DialogContent = exports.DialogClose = void 0;
8
+ exports.WalletImage = exports.useToastContext = exports.ToastProvider = exports.ToastContainer = exports.Toast = exports.toast = exports.AnimatedLottie = exports.TransitionPanel = void 0;
9
9
  // TODO woj: Barrel file for all components, this might be reason of bundle size issues
10
10
  // Core Components
11
11
  var B3DynamicModal_1 = require("./B3DynamicModal");
@@ -27,6 +27,8 @@ var BetterAuthResetPassword_1 = require("./SignInWithB3/BetterAuthResetPassword"
27
27
  Object.defineProperty(exports, "BetterAuthResetPassword", { enumerable: true, get: function () { return BetterAuthResetPassword_1.BetterAuthResetPassword; } });
28
28
  var BetterAuthSignIn_1 = require("./SignInWithB3/BetterAuthSignIn");
29
29
  Object.defineProperty(exports, "BetterAuthSignIn", { enumerable: true, get: function () { return BetterAuthSignIn_1.BetterAuthSignIn; } });
30
+ var BetterAuthVerifyEmail_1 = require("./SignInWithB3/BetterAuthVerifyEmail");
31
+ Object.defineProperty(exports, "BetterAuthVerifyEmail", { enumerable: true, get: function () { return BetterAuthVerifyEmail_1.BetterAuthVerifyEmail; } });
30
32
  var AuthButton_1 = require("./SignInWithB3/components/AuthButton");
31
33
  Object.defineProperty(exports, "AuthButton", { enumerable: true, get: function () { return AuthButton_1.AuthButton; } });
32
34
  var PermissionItem_1 = require("./SignInWithB3/components/PermissionItem");
@@ -13,7 +13,7 @@ export declare class EmailVerificationRequiredError extends Error {
13
13
  */
14
14
  export declare function useBetterAuth(): {
15
15
  signInWithEmail: (email: string, password: string) => Promise<import("@feathersjs/authentication").AuthenticationResult>;
16
- signUpWithEmail: (email: string, password: string, name: string) => Promise<import("@feathersjs/authentication").AuthenticationResult>;
16
+ signUpWithEmail: (email: string, password: string, name: string, verifyCallbackURL?: string) => Promise<import("@feathersjs/authentication").AuthenticationResult>;
17
17
  signInWithSocial: (provider: BetterAuthSocialProvider) => Promise<void>;
18
18
  requestPasswordReset: (email: string, redirectTo?: string) => Promise<{
19
19
  data: {
@@ -73,7 +73,7 @@ function useBetterAuth() {
73
73
  throw error;
74
74
  }
75
75
  }, [exchangeForFeathersJWT, setIsAuthenticating, setHasStartedConnecting]);
76
- const signUpWithEmail = (0, react_2.useCallback)(async (email, password, name) => {
76
+ const signUpWithEmail = (0, react_2.useCallback)(async (email, password, name, verifyCallbackURL) => {
77
77
  debug("Signing up with email", { email, name });
78
78
  setHasStartedConnecting(true);
79
79
  setIsAuthenticating(true);
@@ -84,11 +84,12 @@ function useBetterAuth() {
84
84
  }
85
85
  const token = result.data?.token;
86
86
  if (!token) {
87
- // requireEmailVerification is enabled — send verification email
88
- // with the client's origin as callbackURL so the user returns here
87
+ // requireEmailVerification is enabled — send verification email with
88
+ // a callbackURL Better Auth redirects to after server-side verify.
89
+ // Pass verifyCallbackURL to land on a dedicated confirmation page.
89
90
  await better_auth_client_1.betterAuthClient.sendVerificationEmail({
90
91
  email,
91
- callbackURL: `${window.location.origin}?authStrategy=better-auth`,
92
+ callbackURL: verifyCallbackURL || `${window.location.origin}?authStrategy=better-auth`,
92
93
  });
93
94
  throw new EmailVerificationRequiredError();
94
95
  }
@@ -41,6 +41,8 @@ export interface SignInWithB3ModalProps extends BaseModalProps {
41
41
  source?: "signInWithB3Button" | "requestPermissions";
42
42
  /** Whether to show the signers enabled modal */
43
43
  signersEnabled?: boolean;
44
+ /** URL Better Auth redirects to after server-side email verification. */
45
+ verifyEmailRedirectTo?: string;
44
46
  }
45
47
  /**
46
48
  * Props for the Request Permissions modal
@@ -10,6 +10,11 @@ export interface BetterAuthSignInProps {
10
10
  showEmail?: boolean;
11
11
  /** URL to redirect to after password reset link is clicked. Token is appended as ?token=... */
12
12
  passwordResetRedirectTo?: string;
13
+ /**
14
+ * URL Better Auth redirects to after server-side email verification. Render
15
+ * `BetterAuthVerifyEmail` at this route so the user gets a confirmation page.
16
+ */
17
+ verifyEmailRedirectTo?: string;
13
18
  /** Called after successful authentication */
14
19
  onSuccess?: () => void;
15
20
  /** Called on authentication error */
@@ -31,4 +36,4 @@ export interface BetterAuthSignInProps {
31
36
  * />
32
37
  * ```
33
38
  */
34
- export declare function BetterAuthSignIn({ title, subtitle, socialProviders, showEmail, passwordResetRedirectTo, onSuccess, onError, className, }: BetterAuthSignInProps): import("react/jsx-runtime").JSX.Element | null;
39
+ export declare function BetterAuthSignIn({ title, subtitle, socialProviders, showEmail, passwordResetRedirectTo, verifyEmailRedirectTo, onSuccess, onError, className, }: BetterAuthSignInProps): import("react/jsx-runtime").JSX.Element | null;
@@ -28,7 +28,7 @@ const DEFAULT_SOCIAL_PROVIDERS = [
28
28
  * />
29
29
  * ```
30
30
  */
31
- export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to access your account", socialProviders = DEFAULT_SOCIAL_PROVIDERS.map(p => p.id), showEmail = true, passwordResetRedirectTo, onSuccess, onError, className, }) {
31
+ export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to access your account", socialProviders = DEFAULT_SOCIAL_PROVIDERS.map(p => p.id), showEmail = true, passwordResetRedirectTo, verifyEmailRedirectTo, onSuccess, onError, className, }) {
32
32
  const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = useBetterAuth();
33
33
  const isAuthenticated = useAuthStore(state => state.isAuthenticated);
34
34
  const isAuthenticating = useAuthStore(state => state.isAuthenticating);
@@ -98,7 +98,7 @@ export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to
98
98
  setIsLoading(true);
99
99
  setError(null);
100
100
  if (mode === "sign-up") {
101
- await signUpWithEmail(normalizedEmail, password, name.trim());
101
+ await signUpWithEmail(normalizedEmail, password, name.trim(), verifyEmailRedirectTo);
102
102
  }
103
103
  else {
104
104
  await signInWithEmail(normalizedEmail, password);
@@ -0,0 +1,37 @@
1
+ export type BetterAuthVerifyEmailState = "success" | "expired" | "invalid" | "already-verified" | "error";
2
+ export interface BetterAuthVerifyEmailProps {
3
+ /**
4
+ * Error code from the callback URL's `?error=` query param. Pass `null` /
5
+ * `undefined` when the user landed here cleanly (successful verification).
6
+ * Better Auth appends this param when server-side verification fails.
7
+ */
8
+ errorCode?: string | null;
9
+ /** Called when the user clicks the "Go to sign in" button. */
10
+ onGoToSignIn?: () => void;
11
+ /** Fallback href used when `onGoToSignIn` is not provided. Defaults to "/login". */
12
+ signInHref?: string;
13
+ /** Optional override for the success headline. */
14
+ successTitle?: string;
15
+ /** Optional override for the success body text. */
16
+ successMessage?: string;
17
+ /** Optional class name for the root container. */
18
+ className?: string;
19
+ }
20
+ /**
21
+ * Standalone email-verification confirmation page. Render on the route you
22
+ * set as `callbackURL` when calling `betterAuthClient.sendVerificationEmail`
23
+ * (or the `verifyCallbackURL` arg on `useBetterAuth().signUpWithEmail`).
24
+ *
25
+ * Better Auth verifies the token server-side before redirecting here. This
26
+ * component only displays the outcome based on the `?error=` query param.
27
+ *
28
+ * Usage:
29
+ * ```tsx
30
+ * const error = new URLSearchParams(window.location.search).get("error");
31
+ * <BetterAuthVerifyEmail
32
+ * errorCode={error}
33
+ * onGoToSignIn={() => router.push("/login")}
34
+ * />
35
+ * ```
36
+ */
37
+ export declare function BetterAuthVerifyEmail({ errorCode, onGoToSignIn, signInHref, successTitle, successMessage, className, }: BetterAuthVerifyEmailProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,82 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button } from "../../../../global-account/react/index.js";
3
+ import { debugB3React } from "../../../../shared/utils/debug.js";
4
+ const debug = debugB3React("BetterAuthVerifyEmail");
5
+ function classifyError(code) {
6
+ if (!code)
7
+ return "success";
8
+ const normalized = code.toLowerCase();
9
+ // Exact matches for Better Auth's documented verification error codes.
10
+ if (normalized === "expired_token")
11
+ return "expired";
12
+ if (normalized === "invalid_token")
13
+ return "invalid";
14
+ if (normalized === "already_verified" || normalized === "email_already_verified")
15
+ return "already-verified";
16
+ // Loose fallbacks for close variants. Order matters — check "already" before
17
+ // "verified" so `email_already_verified` maps to already-verified, not invalid.
18
+ if (normalized.includes("expired"))
19
+ return "expired";
20
+ if (normalized.includes("already"))
21
+ return "already-verified";
22
+ if (normalized.includes("invalid"))
23
+ return "invalid";
24
+ return "error";
25
+ }
26
+ const COPY = {
27
+ success: {
28
+ title: "Email verified",
29
+ message: "Your email is confirmed. You can now sign in to your account.",
30
+ },
31
+ expired: {
32
+ title: "Link expired",
33
+ message: "This verification link has expired. Request a new one from the sign-in page.",
34
+ },
35
+ invalid: {
36
+ title: "Invalid link",
37
+ message: "This verification link is invalid or has already been used. Try signing in or request a new link.",
38
+ },
39
+ "already-verified": {
40
+ title: "Already verified",
41
+ message: "Your email was already confirmed. You can sign in now.",
42
+ },
43
+ error: {
44
+ title: "Verification failed",
45
+ message: "We couldn't verify your email. Request a new link from the sign-in page.",
46
+ },
47
+ };
48
+ /**
49
+ * Standalone email-verification confirmation page. Render on the route you
50
+ * set as `callbackURL` when calling `betterAuthClient.sendVerificationEmail`
51
+ * (or the `verifyCallbackURL` arg on `useBetterAuth().signUpWithEmail`).
52
+ *
53
+ * Better Auth verifies the token server-side before redirecting here. This
54
+ * component only displays the outcome based on the `?error=` query param.
55
+ *
56
+ * Usage:
57
+ * ```tsx
58
+ * const error = new URLSearchParams(window.location.search).get("error");
59
+ * <BetterAuthVerifyEmail
60
+ * errorCode={error}
61
+ * onGoToSignIn={() => router.push("/login")}
62
+ * />
63
+ * ```
64
+ */
65
+ export function BetterAuthVerifyEmail({ errorCode, onGoToSignIn, signInHref = "/login", successTitle, successMessage, className, }) {
66
+ const state = classifyError(errorCode);
67
+ const isSuccess = state === "success" || state === "already-verified";
68
+ const copy = COPY[state];
69
+ const title = isSuccess && successTitle ? successTitle : copy.title;
70
+ const message = isSuccess && successMessage ? successMessage : copy.message;
71
+ debug("Rendering verify-email state", { state, errorCode });
72
+ const handleClick = () => {
73
+ if (onGoToSignIn) {
74
+ onGoToSignIn();
75
+ return;
76
+ }
77
+ if (typeof window !== "undefined") {
78
+ window.location.href = signInHref;
79
+ }
80
+ };
81
+ return (_jsx("div", { className: `w-full max-w-[400px] px-6 ${className || ""}`, children: _jsxs("div", { className: "space-y-6 text-center", children: [_jsx("div", { className: `mx-auto flex h-12 w-12 items-center justify-center rounded-full ${isSuccess ? "bg-green-100" : "bg-red-100"}`, children: isSuccess ? (_jsx("svg", { className: "h-6 w-6 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) })) : (_jsx("svg", { className: "h-6 w-6 text-red-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", "aria-hidden": "true", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })) }), _jsxs("div", { children: [_jsx("h1", { className: "text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: title }), _jsx("p", { className: "mt-3 text-[15px] text-gray-500 dark:text-gray-400", children: message })] }), _jsx(Button, { onClick: handleClick, className: "h-11 w-full bg-gray-900 text-[15px] font-medium text-white hover:bg-gray-800 dark:bg-white dark:text-gray-900 dark:hover:bg-gray-100", children: isSuccess ? "Go to sign in" : "Back to sign in" })] }) }));
82
+ }
@@ -3,4 +3,4 @@ import { SignInWithB3ModalProps } from "../../../../global-account/react";
3
3
  * Component that manages the authentication flow for Sign In With B3
4
4
  * Handles different login providers, authentication steps, and session key management
5
5
  */
6
- export declare function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin, source, signersEnabled, }: SignInWithB3ModalProps): import("react/jsx-runtime").JSX.Element | null;
6
+ export declare function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin, source, signersEnabled, verifyEmailRedirectTo, }: SignInWithB3ModalProps): import("react/jsx-runtime").JSX.Element | null;
@@ -13,7 +13,7 @@ const MAX_REFETCH_ATTEMPTS = 20;
13
13
  * Component that manages the authentication flow for Sign In With B3
14
14
  * Handles different login providers, authentication steps, and session key management
15
15
  */
16
- export function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin = false, source = "signInWithB3Button", signersEnabled = false, }) {
16
+ export function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin = false, source = "signInWithB3Button", signersEnabled = false, verifyEmailRedirectTo, }) {
17
17
  const { automaticallySetFirstEoa, authStrategy } = useB3Config();
18
18
  // skipAutoConnect: this component intentionally logs out on mount to show a fresh login screen.
19
19
  // AuthenticationProvider is the sole owner of useAutoConnect to avoid competing auth cycles.
@@ -244,7 +244,7 @@ export function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySucce
244
244
  // Better Auth manages its own loading/verification states internally.
245
245
  // Don't gate on isAuthenticating — it would unmount the component
246
246
  // and lose verification state when setIsAuthenticating(false) fires.
247
- content = _jsx(LoginStepBetterAuth, { onSuccess: () => handleLoginSuccess({}), onError: onError });
247
+ content = (_jsx(LoginStepBetterAuth, { onSuccess: () => handleLoginSuccess({}), onError: onError, verifyEmailRedirectTo: verifyEmailRedirectTo }));
248
248
  }
249
249
  else if (!readyToShowLogin || isAuthenticating || isFetchingSigners) {
250
250
  content = (_jsx(LoginStepContainer, { partnerId: partnerId, children: _jsx("div", { className: "my-8 flex min-h-[350px] items-center justify-center", children: _jsx(Loading, { variant: "white", size: "lg" }) }) }));
@@ -1,6 +1,8 @@
1
1
  interface LoginStepBetterAuthProps {
2
2
  onSuccess?: () => void;
3
3
  onError?: (error: Error) => Promise<void>;
4
+ /** URL Better Auth redirects to after server-side email verification. */
5
+ verifyEmailRedirectTo?: string;
4
6
  }
5
- export declare function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthProps): import("react/jsx-runtime").JSX.Element;
7
+ export declare function LoginStepBetterAuth({ onSuccess, onError, verifyEmailRedirectTo }: LoginStepBetterAuthProps): import("react/jsx-runtime").JSX.Element;
6
8
  export {};
@@ -14,7 +14,7 @@ const SOCIAL_PROVIDERS = [
14
14
  { id: "microsoft", label: "Microsoft" },
15
15
  { id: "slack", label: "Slack" },
16
16
  ];
17
- export function LoginStepBetterAuth({ onSuccess, onError }) {
17
+ export function LoginStepBetterAuth({ onSuccess, onError, verifyEmailRedirectTo }) {
18
18
  const { partnerId } = useB3Config();
19
19
  const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = useBetterAuth();
20
20
  const [mode, setMode] = useState("sign-in");
@@ -45,7 +45,7 @@ export function LoginStepBetterAuth({ onSuccess, onError }) {
45
45
  setError(null);
46
46
  if (mode === "sign-up") {
47
47
  debug("Signing up", { email: normalizedEmail, name: name.trim() });
48
- await signUpWithEmail(normalizedEmail, password, name.trim());
48
+ await signUpWithEmail(normalizedEmail, password, name.trim(), verifyEmailRedirectTo);
49
49
  }
50
50
  else {
51
51
  debug("Signing in", { email: normalizedEmail });
@@ -8,6 +8,7 @@ export { useB3Config } from "./B3Provider/useB3Config";
8
8
  export { StyleRoot } from "./StyleRoot";
9
9
  export { BetterAuthResetPassword, type BetterAuthResetPasswordProps } from "./SignInWithB3/BetterAuthResetPassword";
10
10
  export { BetterAuthSignIn, type BetterAuthSignInProps } from "./SignInWithB3/BetterAuthSignIn";
11
+ export { BetterAuthVerifyEmail, type BetterAuthVerifyEmailProps, type BetterAuthVerifyEmailState, } from "./SignInWithB3/BetterAuthVerifyEmail";
11
12
  export { AuthButton } from "./SignInWithB3/components/AuthButton";
12
13
  export { PermissionItem } from "./SignInWithB3/components/PermissionItem";
13
14
  export { WalletRow } from "./SignInWithB3/components/WalletRow";
@@ -10,6 +10,7 @@ export { StyleRoot } from "./StyleRoot.js";
10
10
  // SignInWithB3 Components
11
11
  export { BetterAuthResetPassword } from "./SignInWithB3/BetterAuthResetPassword.js";
12
12
  export { BetterAuthSignIn } from "./SignInWithB3/BetterAuthSignIn.js";
13
+ export { BetterAuthVerifyEmail, } from "./SignInWithB3/BetterAuthVerifyEmail.js";
13
14
  export { AuthButton } from "./SignInWithB3/components/AuthButton.js";
14
15
  export { PermissionItem } from "./SignInWithB3/components/PermissionItem.js";
15
16
  export { WalletRow } from "./SignInWithB3/components/WalletRow.js";
@@ -13,7 +13,7 @@ export declare class EmailVerificationRequiredError extends Error {
13
13
  */
14
14
  export declare function useBetterAuth(): {
15
15
  signInWithEmail: (email: string, password: string) => Promise<import("@feathersjs/authentication").AuthenticationResult>;
16
- signUpWithEmail: (email: string, password: string, name: string) => Promise<import("@feathersjs/authentication").AuthenticationResult>;
16
+ signUpWithEmail: (email: string, password: string, name: string, verifyCallbackURL?: string) => Promise<import("@feathersjs/authentication").AuthenticationResult>;
17
17
  signInWithSocial: (provider: BetterAuthSocialProvider) => Promise<void>;
18
18
  requestPasswordReset: (email: string, redirectTo?: string) => Promise<{
19
19
  data: {
@@ -65,7 +65,7 @@ export function useBetterAuth() {
65
65
  throw error;
66
66
  }
67
67
  }, [exchangeForFeathersJWT, setIsAuthenticating, setHasStartedConnecting]);
68
- const signUpWithEmail = useCallback(async (email, password, name) => {
68
+ const signUpWithEmail = useCallback(async (email, password, name, verifyCallbackURL) => {
69
69
  debug("Signing up with email", { email, name });
70
70
  setHasStartedConnecting(true);
71
71
  setIsAuthenticating(true);
@@ -76,11 +76,12 @@ export function useBetterAuth() {
76
76
  }
77
77
  const token = result.data?.token;
78
78
  if (!token) {
79
- // requireEmailVerification is enabled — send verification email
80
- // with the client's origin as callbackURL so the user returns here
79
+ // requireEmailVerification is enabled — send verification email with
80
+ // a callbackURL Better Auth redirects to after server-side verify.
81
+ // Pass verifyCallbackURL to land on a dedicated confirmation page.
81
82
  await betterAuthClient.sendVerificationEmail({
82
83
  email,
83
- callbackURL: `${window.location.origin}?authStrategy=better-auth`,
84
+ callbackURL: verifyCallbackURL || `${window.location.origin}?authStrategy=better-auth`,
84
85
  });
85
86
  throw new EmailVerificationRequiredError();
86
87
  }
@@ -41,6 +41,8 @@ export interface SignInWithB3ModalProps extends BaseModalProps {
41
41
  source?: "signInWithB3Button" | "requestPermissions";
42
42
  /** Whether to show the signers enabled modal */
43
43
  signersEnabled?: boolean;
44
+ /** URL Better Auth redirects to after server-side email verification. */
45
+ verifyEmailRedirectTo?: string;
44
46
  }
45
47
  /**
46
48
  * Props for the Request Permissions modal