@b3dotfun/sdk 0.1.69-alpha.17 → 0.1.69-alpha.18

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 (71) hide show
  1. package/dist/cjs/anyspend/utils/chain.js +1 -1
  2. package/dist/cjs/global-account/better-auth-client.d.ts +1883 -0
  3. package/dist/cjs/global-account/better-auth-client.js +17 -0
  4. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +4 -1
  5. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +2 -1
  6. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  7. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +3 -2
  8. package/dist/cjs/global-account/react/components/B3Provider/BetterAuthProvider.d.ts +16 -0
  9. package/dist/cjs/global-account/react/components/B3Provider/BetterAuthProvider.js +120 -0
  10. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthResetPassword.d.ts +21 -0
  11. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthResetPassword.js +67 -0
  12. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +34 -0
  13. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +149 -0
  14. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +9 -3
  15. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +6 -0
  16. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +123 -0
  17. package/dist/cjs/global-account/react/components/SignInWithB3/utils/signInUtils.js +5 -1
  18. package/dist/cjs/global-account/react/components/index.d.ts +3 -0
  19. package/dist/cjs/global-account/react/components/index.js +7 -3
  20. package/dist/cjs/global-account/react/hooks/index.d.ts +1 -0
  21. package/dist/cjs/global-account/react/hooks/index.js +4 -2
  22. package/dist/cjs/global-account/react/hooks/useBetterAuth.d.ts +969 -0
  23. package/dist/cjs/global-account/react/hooks/useBetterAuth.js +142 -0
  24. package/dist/esm/anyspend/utils/chain.js +1 -1
  25. package/dist/esm/global-account/better-auth-client.d.ts +1883 -0
  26. package/dist/esm/global-account/better-auth-client.js +13 -0
  27. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +4 -1
  28. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +2 -1
  29. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  30. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +3 -2
  31. package/dist/esm/global-account/react/components/B3Provider/BetterAuthProvider.d.ts +16 -0
  32. package/dist/esm/global-account/react/components/B3Provider/BetterAuthProvider.js +115 -0
  33. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthResetPassword.d.ts +21 -0
  34. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthResetPassword.js +64 -0
  35. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +34 -0
  36. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +146 -0
  37. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +9 -3
  38. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +6 -0
  39. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +120 -0
  40. package/dist/esm/global-account/react/components/SignInWithB3/utils/signInUtils.js +5 -1
  41. package/dist/esm/global-account/react/components/index.d.ts +3 -0
  42. package/dist/esm/global-account/react/components/index.js +2 -0
  43. package/dist/esm/global-account/react/hooks/index.d.ts +1 -0
  44. package/dist/esm/global-account/react/hooks/index.js +1 -0
  45. package/dist/esm/global-account/react/hooks/useBetterAuth.d.ts +969 -0
  46. package/dist/esm/global-account/react/hooks/useBetterAuth.js +136 -0
  47. package/dist/styles/index.css +1 -1
  48. package/dist/types/global-account/better-auth-client.d.ts +1883 -0
  49. package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +4 -1
  50. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +4 -1
  51. package/dist/types/global-account/react/components/B3Provider/BetterAuthProvider.d.ts +16 -0
  52. package/dist/types/global-account/react/components/SignInWithB3/BetterAuthResetPassword.d.ts +21 -0
  53. package/dist/types/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +34 -0
  54. package/dist/types/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +6 -0
  55. package/dist/types/global-account/react/components/index.d.ts +3 -0
  56. package/dist/types/global-account/react/hooks/index.d.ts +1 -0
  57. package/dist/types/global-account/react/hooks/useBetterAuth.d.ts +969 -0
  58. package/package.json +2 -1
  59. package/src/anyspend/utils/chain.ts +1 -2
  60. package/src/global-account/better-auth-client.ts +17 -0
  61. package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +6 -0
  62. package/src/global-account/react/components/B3Provider/B3Provider.tsx +15 -5
  63. package/src/global-account/react/components/B3Provider/BetterAuthProvider.tsx +127 -0
  64. package/src/global-account/react/components/SignInWithB3/BetterAuthResetPassword.tsx +146 -0
  65. package/src/global-account/react/components/SignInWithB3/BetterAuthSignIn.tsx +375 -0
  66. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +9 -3
  67. package/src/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.tsx +263 -0
  68. package/src/global-account/react/components/SignInWithB3/utils/signInUtils.ts +5 -1
  69. package/src/global-account/react/components/index.ts +3 -0
  70. package/src/global-account/react/hooks/index.ts +1 -0
  71. package/src/global-account/react/hooks/useBetterAuth.ts +177 -0
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.betterAuthClient = void 0;
4
+ exports.createB3BetterAuthClient = createB3BetterAuthClient;
5
+ const client_1 = require("better-auth/client");
6
+ const app_shared_1 = require("../app.shared");
7
+ function createB3BetterAuthClient(baseURL = app_shared_1.B3_API_URL) {
8
+ return (0, client_1.createAuthClient)({
9
+ baseURL,
10
+ basePath: "/auth",
11
+ fetchOptions: {
12
+ credentials: "include",
13
+ },
14
+ });
15
+ }
16
+ // Default singleton for standard usage
17
+ exports.betterAuthClient = createB3BetterAuthClient();
@@ -3,6 +3,7 @@ import { CreateOrderParams } from "../../../../anyspend/react/hooks/useAnyspendC
3
3
  import { PermissionsConfig } from "../../../../global-account/types/permissions";
4
4
  import { Account } from "thirdweb/wallets";
5
5
  import { ClientType } from "../../../client-manager";
6
+ export type AuthStrategy = "thirdweb" | "better-auth";
6
7
  export interface B3ConfigContextType {
7
8
  accountOverride?: Account;
8
9
  automaticallySetFirstEoa: boolean;
@@ -13,8 +14,9 @@ export interface B3ConfigContextType {
13
14
  partnerId: string;
14
15
  stripePublishableKey?: string;
15
16
  createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
17
+ authStrategy: AuthStrategy;
16
18
  }
17
- export declare function B3ConfigProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, stripePublishableKey, createClientReferenceId, }: {
19
+ export declare function B3ConfigProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, stripePublishableKey, createClientReferenceId, authStrategy, }: {
18
20
  children: React.ReactNode;
19
21
  accountOverride?: Account;
20
22
  environment?: "development" | "production";
@@ -25,5 +27,6 @@ export declare function B3ConfigProvider({ children, accountOverride, environmen
25
27
  partnerId: string;
26
28
  stripePublishableKey?: string;
27
29
  createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
30
+ authStrategy?: AuthStrategy;
28
31
  }): import("react/jsx-runtime").JSX.Element;
29
32
  export declare function useB3Config(): B3ConfigContextType;
@@ -14,7 +14,7 @@ const DEFAULT_PERMISSIONS = {
14
14
  endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
15
15
  };
16
16
  const B3ConfigContext = (0, react_1.createContext)(null);
17
- function B3ConfigProvider({ children, accountOverride, environment = "development", defaultPermissions = DEFAULT_PERMISSIONS, automaticallySetFirstEoa = false, theme = "light", clientType = "rest", partnerId, stripePublishableKey, createClientReferenceId, }) {
17
+ function B3ConfigProvider({ children, accountOverride, environment = "development", defaultPermissions = DEFAULT_PERMISSIONS, automaticallySetFirstEoa = false, theme = "light", clientType = "rest", partnerId, stripePublishableKey, createClientReferenceId, authStrategy = "thirdweb", }) {
18
18
  return ((0, jsx_runtime_1.jsx)(B3ConfigContext.Provider, { value: {
19
19
  accountOverride,
20
20
  environment,
@@ -25,6 +25,7 @@ function B3ConfigProvider({ children, accountOverride, environment = "developmen
25
25
  partnerId,
26
26
  stripePublishableKey,
27
27
  createClientReferenceId,
28
+ authStrategy,
28
29
  }, children: children }));
29
30
  }
30
31
  function useB3Config() {
@@ -1,6 +1,7 @@
1
1
  import { CreateOnrampOrderParams } from "../../../../anyspend/react/hooks/useAnyspendCreateOnrampOrder";
2
2
  import { CreateOrderParams } from "../../../../anyspend/react/hooks/useAnyspendCreateOrder";
3
3
  import { PermissionsConfig } from "../../../../global-account/types/permissions";
4
+ import type { AuthStrategy } from "./B3ConfigProvider";
4
5
  import "@relayprotocol/relay-kit-ui/styles.css";
5
6
  import { QueryClient } from "@tanstack/react-query";
6
7
  import { Account, EIP1193, Wallet } from "thirdweb/wallets";
@@ -9,7 +10,7 @@ import { ClientType } from "../../../client-manager";
9
10
  /**
10
11
  * Main B3Provider component
11
12
  */
12
- export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, defaultEoaProvider, simDuneApiKey, toaster: _toaster, clientType, rpcUrls, partnerId, stripePublishableKey, onConnect, onLogout, connectors, overrideDefaultConnectors, createClientReferenceId, defaultPermissions, disableBSMNTAuthentication, queryClient, }: {
13
+ export declare function B3Provider({ theme, children, accountOverride, environment, automaticallySetFirstEoa, defaultEoaProvider, simDuneApiKey, toaster: _toaster, clientType, rpcUrls, partnerId, stripePublishableKey, onConnect, onLogout, connectors, overrideDefaultConnectors, createClientReferenceId, defaultPermissions, disableBSMNTAuthentication, queryClient, authStrategy, }: {
13
14
  theme: "light" | "dark";
14
15
  children: React.ReactNode;
15
16
  accountOverride?: Account;
@@ -36,4 +37,6 @@ export declare function B3Provider({ theme, children, accountOverride, environme
36
37
  disableBSMNTAuthentication?: boolean;
37
38
  /** Provide your own QueryClient for React Query. If omitted, WalletProvider creates one internally. */
38
39
  queryClient?: QueryClient;
40
+ /** Auth strategy: "thirdweb" (default, ecosystem wallet) or "better-auth" (email/password via Better Auth) */
41
+ authStrategy?: AuthStrategy;
39
42
  }): import("react/jsx-runtime").JSX.Element;
@@ -16,13 +16,14 @@ const StyleRoot_1 = require("../StyleRoot");
16
16
  const index_1 = require("../Toast/index");
17
17
  const AuthenticationProvider_1 = __importDefault(require("./AuthenticationProvider"));
18
18
  const B3ConfigProvider_1 = require("./B3ConfigProvider");
19
+ const BetterAuthProvider_1 = __importDefault(require("./BetterAuthProvider"));
19
20
  const LocalSDKProvider_1 = require("./LocalSDKProvider");
20
21
  /**
21
22
  * Main B3Provider component
22
23
  */
23
24
  function B3Provider({ theme = "light", children, accountOverride, environment, automaticallySetFirstEoa, defaultEoaProvider, simDuneApiKey,
24
25
  // deprecated since v0.0.87
25
- toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey, onConnect, onLogout, connectors, overrideDefaultConnectors = false, createClientReferenceId, defaultPermissions, disableBSMNTAuthentication = false, queryClient, }) {
26
+ toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey, onConnect, onLogout, connectors, overrideDefaultConnectors = false, createClientReferenceId, defaultPermissions, disableBSMNTAuthentication = false, queryClient, authStrategy = "thirdweb", }) {
26
27
  // Initialize Google Analytics on mount
27
28
  (0, react_3.useEffect)(() => {
28
29
  (0, analytics_1.loadGA4Script)();
@@ -32,7 +33,7 @@ toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey
32
33
  (0, client_manager_1.setClientType)(clientType);
33
34
  }, [clientType]);
34
35
  const wagmiConfig = (0, react_3.useMemo)(() => (0, createWagmiConfig_1.createWagmiConfig)({ partnerId, rpcUrls, connectors, overrideDefaultConnectors }), [partnerId, rpcUrls, connectors, overrideDefaultConnectors]);
35
- return ((0, jsx_runtime_1.jsx)(react_2.WalletProvider, { wagmiConfig: wagmiConfig, queryClient: queryClient, children: (0, jsx_runtime_1.jsx)(react_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(index_1.ToastProvider, { children: (0, jsx_runtime_1.jsx)(LocalSDKProvider_1.LocalSDKProvider, { onConnectCallback: onConnect, onLogoutCallback: onLogout, disableBSMNTAuthentication: disableBSMNTAuthentication, children: (0, jsx_runtime_1.jsxs)(B3ConfigProvider_1.B3ConfigProvider, { accountOverride: accountOverride, environment: environment, automaticallySetFirstEoa: !!automaticallySetFirstEoa, theme: theme, clientType: clientType, partnerId: partnerId, stripePublishableKey: stripePublishableKey, createClientReferenceId: createClientReferenceId, defaultPermissions: defaultPermissions, children: [(0, jsx_runtime_1.jsx)(ToastContextConnector, {}), (0, jsx_runtime_1.jsxs)(react_1.RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, (0, jsx_runtime_1.jsx)(StyleRoot_1.StyleRoot, { id: "b3-root" })] }), (0, jsx_runtime_1.jsx)(AuthenticationProvider_1.default, { partnerId: partnerId, automaticallySetFirstEoa: !!automaticallySetFirstEoa, defaultEoaProvider: defaultEoaProvider })] }) }) }) }) }));
36
+ return ((0, jsx_runtime_1.jsx)(react_2.WalletProvider, { wagmiConfig: wagmiConfig, queryClient: queryClient, children: (0, jsx_runtime_1.jsx)(react_1.TooltipProvider, { children: (0, jsx_runtime_1.jsx)(index_1.ToastProvider, { children: (0, jsx_runtime_1.jsx)(LocalSDKProvider_1.LocalSDKProvider, { onConnectCallback: onConnect, onLogoutCallback: onLogout, disableBSMNTAuthentication: disableBSMNTAuthentication, children: (0, jsx_runtime_1.jsxs)(B3ConfigProvider_1.B3ConfigProvider, { accountOverride: accountOverride, environment: environment, automaticallySetFirstEoa: !!automaticallySetFirstEoa, theme: theme, clientType: clientType, partnerId: partnerId, stripePublishableKey: stripePublishableKey, createClientReferenceId: createClientReferenceId, defaultPermissions: defaultPermissions, authStrategy: authStrategy, children: [(0, jsx_runtime_1.jsx)(ToastContextConnector, {}), (0, jsx_runtime_1.jsxs)(react_1.RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, (0, jsx_runtime_1.jsx)(StyleRoot_1.StyleRoot, { id: "b3-root" })] }), authStrategy === "better-auth" ? ((0, jsx_runtime_1.jsx)(BetterAuthProvider_1.default, { partnerId: partnerId })) : ((0, jsx_runtime_1.jsx)(AuthenticationProvider_1.default, { partnerId: partnerId, automaticallySetFirstEoa: !!automaticallySetFirstEoa, defaultEoaProvider: defaultEoaProvider }))] }) }) }) }) }));
36
37
  }
37
38
  /**
38
39
  * Component to connect the toast context to the global toast API
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Parallel to AuthenticationProvider for Better Auth strategy.
3
+ *
4
+ * Manages the isAuthenticating lifecycle for Better Auth:
5
+ * 1. On mount, try to restore an existing Feathers JWT (from a previous login)
6
+ * 2. If no Feathers JWT, check for a Better Auth session (e.g. after OAuth redirect)
7
+ * and exchange it for a Feathers JWT
8
+ * 3. If neither exists, set isAuthenticating: false so the login UI renders
9
+ *
10
+ * Also patches app.logout() so any code path that calls it (useAuthentication,
11
+ * useAuth, SignIn component, etc.) automatically clears the Better Auth session.
12
+ */
13
+ declare const BetterAuthProvider: ({ partnerId }: {
14
+ partnerId: string;
15
+ }) => null;
16
+ export default BetterAuthProvider;
@@ -0,0 +1,120 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const app_1 = __importDefault(require("../../../../global-account/app"));
7
+ const react_1 = require("../../../../global-account/react");
8
+ const constants_1 = require("../../../../shared/constants");
9
+ const debug_1 = require("../../../../shared/utils/debug");
10
+ const js_cookie_1 = __importDefault(require("js-cookie"));
11
+ const react_2 = require("react");
12
+ const better_auth_client_1 = require("../../../better-auth-client");
13
+ const useUserQuery_1 = require("../../hooks/useUserQuery");
14
+ const debug = (0, debug_1.debugB3React)("BetterAuthProvider");
15
+ /**
16
+ * Parallel to AuthenticationProvider for Better Auth strategy.
17
+ *
18
+ * Manages the isAuthenticating lifecycle for Better Auth:
19
+ * 1. On mount, try to restore an existing Feathers JWT (from a previous login)
20
+ * 2. If no Feathers JWT, check for a Better Auth session (e.g. after OAuth redirect)
21
+ * and exchange it for a Feathers JWT
22
+ * 3. If neither exists, set isAuthenticating: false so the login UI renders
23
+ *
24
+ * Also patches app.logout() so any code path that calls it (useAuthentication,
25
+ * useAuth, SignIn component, etc.) automatically clears the Better Auth session.
26
+ */
27
+ const BetterAuthProvider = ({ partnerId }) => {
28
+ const setIsAuthenticated = (0, react_1.useAuthStore)(state => state.setIsAuthenticated);
29
+ const setIsAuthenticating = (0, react_1.useAuthStore)(state => state.setIsAuthenticating);
30
+ const setIsConnected = (0, react_1.useAuthStore)(state => state.setIsConnected);
31
+ const { setUser } = (0, useUserQuery_1.useUserQuery)();
32
+ const hasAttemptedRestore = (0, react_2.useRef)(false);
33
+ const hasPatched = (0, react_2.useRef)(false);
34
+ // Patch app.logout() to also clear the Better Auth session.
35
+ // This ensures any existing logout path (useAuthentication, useAuth, SignIn
36
+ // dropdown, etc.) clears both the Feathers JWT and the Better Auth session.
37
+ // Patch app.logout() to also clear the Better Auth session.
38
+ // Only handles Better Auth signOut — state cleanup (isAuthenticated, isConnected,
39
+ // setUser, localStorage) is handled by useAuthentication/useAuth's own logout.
40
+ (0, react_2.useEffect)(() => {
41
+ if (hasPatched.current)
42
+ return;
43
+ hasPatched.current = true;
44
+ const originalLogout = app_1.default.logout.bind(app_1.default);
45
+ app_1.default.logout = async () => {
46
+ debug("Patched logout: clearing Better Auth session");
47
+ try {
48
+ await better_auth_client_1.betterAuthClient.signOut();
49
+ }
50
+ catch {
51
+ debug("Better Auth signOut failed (non-critical)");
52
+ }
53
+ return originalLogout();
54
+ };
55
+ return () => {
56
+ app_1.default.logout = originalLogout;
57
+ hasPatched.current = false;
58
+ };
59
+ }, []);
60
+ // Session restore on mount
61
+ (0, react_2.useEffect)(() => {
62
+ if (hasAttemptedRestore.current)
63
+ return;
64
+ hasAttemptedRestore.current = true;
65
+ const restoreSession = async () => {
66
+ debug("Attempting session restore");
67
+ // 1. Try existing Feathers JWT first (fastest — no network call to Better Auth)
68
+ try {
69
+ const response = await app_1.default.reAuthenticate();
70
+ if (response?.user) {
71
+ debug("Feathers JWT restored", { userId: response.user.userId });
72
+ setUser(response.user);
73
+ setIsAuthenticated(true);
74
+ setIsConnected(true);
75
+ setIsAuthenticating(false);
76
+ return;
77
+ }
78
+ }
79
+ catch {
80
+ debug("No existing Feathers JWT");
81
+ }
82
+ // 2. Check for a Better Auth session (e.g. after OAuth redirect sets a cookie)
83
+ try {
84
+ const session = await better_auth_client_1.betterAuthClient.getSession();
85
+ if (session.data?.session?.token) {
86
+ debug("Better Auth session found, exchanging for Feathers JWT", {
87
+ betterAuthUserId: session.data.user?.id,
88
+ });
89
+ const response = await app_1.default.authenticate({
90
+ strategy: "better-auth",
91
+ accessToken: session.data.session.token,
92
+ partnerId,
93
+ });
94
+ if (response.accessToken) {
95
+ js_cookie_1.default.set(constants_1.B3_AUTH_COOKIE_NAME, response.accessToken, {
96
+ secure: true,
97
+ sameSite: "Lax",
98
+ });
99
+ }
100
+ if (response.user) {
101
+ setUser(response.user);
102
+ setIsAuthenticated(true);
103
+ setIsConnected(true);
104
+ }
105
+ debug("OAuth session exchanged for Feathers JWT", { userId: response.user?.userId });
106
+ setIsAuthenticating(false);
107
+ return;
108
+ }
109
+ }
110
+ catch {
111
+ debug("No Better Auth session to restore");
112
+ }
113
+ // 3. Nothing found — show login UI
114
+ setIsAuthenticating(false);
115
+ };
116
+ restoreSession();
117
+ }, [setIsAuthenticated, setIsAuthenticating, setIsConnected, setUser, partnerId]);
118
+ return null;
119
+ };
120
+ exports.default = BetterAuthProvider;
@@ -0,0 +1,21 @@
1
+ export interface BetterAuthResetPasswordProps {
2
+ /** The reset token from the URL query param */
3
+ token: string;
4
+ /** Called after password is successfully reset */
5
+ onSuccess?: () => void;
6
+ /** Called on error */
7
+ onError?: (error: Error) => void;
8
+ /** Optional class name */
9
+ className?: string;
10
+ }
11
+ /**
12
+ * Standalone reset password form. Render this on your reset password page.
13
+ * Reads the token from props (extract it from the URL query string).
14
+ *
15
+ * Usage:
16
+ * ```tsx
17
+ * const token = new URLSearchParams(window.location.search).get("token");
18
+ * <BetterAuthResetPassword token={token} onSuccess={() => navigate("/login")} />
19
+ * ```
20
+ */
21
+ export declare function BetterAuthResetPassword({ token, onSuccess, onError, className }: BetterAuthResetPasswordProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,67 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BetterAuthResetPassword = BetterAuthResetPassword;
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 react_2 = require("react");
8
+ const useBetterAuth_1 = require("../../hooks/useBetterAuth");
9
+ const debug = (0, debug_1.debugB3React)("BetterAuthResetPassword");
10
+ /**
11
+ * Standalone reset password form. Render this on your reset password page.
12
+ * Reads the token from props (extract it from the URL query string).
13
+ *
14
+ * Usage:
15
+ * ```tsx
16
+ * const token = new URLSearchParams(window.location.search).get("token");
17
+ * <BetterAuthResetPassword token={token} onSuccess={() => navigate("/login")} />
18
+ * ```
19
+ */
20
+ function BetterAuthResetPassword({ token, onSuccess, onError, className }) {
21
+ const { resetPassword } = (0, useBetterAuth_1.useBetterAuth)();
22
+ const [password, setPassword] = (0, react_2.useState)("");
23
+ const [confirmPassword, setConfirmPassword] = (0, react_2.useState)("");
24
+ const [isLoading, setIsLoading] = (0, react_2.useState)(false);
25
+ const [error, setError] = (0, react_2.useState)(null);
26
+ const [success, setSuccess] = (0, react_2.useState)(false);
27
+ const handleSubmit = async () => {
28
+ if (!password) {
29
+ setError("Please enter a new password");
30
+ return;
31
+ }
32
+ if (password.length < 8) {
33
+ setError("Password must be at least 8 characters");
34
+ return;
35
+ }
36
+ if (password !== confirmPassword) {
37
+ setError("Passwords do not match");
38
+ return;
39
+ }
40
+ try {
41
+ setIsLoading(true);
42
+ setError(null);
43
+ await resetPassword(password, token);
44
+ setSuccess(true);
45
+ debug("Password reset successful");
46
+ onSuccess?.();
47
+ }
48
+ catch (err) {
49
+ const message = err instanceof Error ? err.message : "Password reset failed";
50
+ setError(message);
51
+ debug("Password reset failed", err);
52
+ onError?.(err);
53
+ }
54
+ finally {
55
+ setPassword("");
56
+ setConfirmPassword("");
57
+ setIsLoading(false);
58
+ }
59
+ };
60
+ if (!token) {
61
+ return ((0, jsx_runtime_1.jsx)("div", { className: `w-full max-w-[400px] px-6 text-center ${className || ""}`, children: (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-red-500", children: "Invalid or missing reset token." }) }));
62
+ }
63
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `w-full max-w-[400px] px-6 ${className || ""}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-10 text-center", children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: success ? "Password reset" : "Set new password" }), (0, jsx_runtime_1.jsx)("p", { className: "mt-3 text-[15px] text-gray-500 dark:text-gray-400", children: success ? "Your password has been updated." : "Enter your new password below." })] }), success ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4 text-center", children: (0, jsx_runtime_1.jsx)("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100", children: (0, jsx_runtime_1.jsx)("svg", { className: "h-6 w-6 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }) })) : ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-5", children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "New password" }), (0, jsx_runtime_1.jsx)(react_1.Input, { type: "password", placeholder: "At least 8 characters", value: password, onChange: e => setPassword(e.target.value), disabled: isLoading, className: "h-11 px-4 text-[15px]" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Confirm password" }), (0, jsx_runtime_1.jsx)(react_1.Input, { type: "password", placeholder: "Repeat your password", value: confirmPassword, onChange: e => setConfirmPassword(e.target.value), disabled: isLoading, onKeyDown: e => {
64
+ if (e.key === "Enter")
65
+ handleSubmit();
66
+ }, className: "h-11 px-4 text-[15px]" })] }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-red-500", children: error }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: handleSubmit, disabled: isLoading, 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: isLoading ? "Resetting..." : "Reset password" })] }))] }));
67
+ }
@@ -0,0 +1,34 @@
1
+ import { type BetterAuthSocialProvider } from "../../hooks/useBetterAuth";
2
+ export interface BetterAuthSignInProps {
3
+ /** Title displayed above the form. Default: "Welcome back" for sign-in, "Create an account" for sign-up */
4
+ title?: string;
5
+ /** Subtitle displayed below the title */
6
+ subtitle?: string;
7
+ /** Which social providers to show. Defaults to all. Pass empty array to hide. */
8
+ socialProviders?: BetterAuthSocialProvider[];
9
+ /** Show email/password form. Default: true */
10
+ showEmail?: boolean;
11
+ /** URL to redirect to after password reset link is clicked. Token is appended as ?token=... */
12
+ passwordResetRedirectTo?: string;
13
+ /** Called after successful authentication */
14
+ onSuccess?: () => void;
15
+ /** Called on authentication error */
16
+ onError?: (error: Error) => void;
17
+ /** Optional class name for the root container */
18
+ className?: string;
19
+ }
20
+ /**
21
+ * Standalone inline sign-in component for Better Auth.
22
+ *
23
+ * Renders directly — no modal, no button wrapper. Designed for full-page
24
+ * sign-in layouts (e.g., B3OS web with branding on the left, form on the right).
25
+ *
26
+ * Usage:
27
+ * ```tsx
28
+ * <BetterAuthSignIn
29
+ * socialProviders={["google", "github"]}
30
+ * onSuccess={() => router.push("/dashboard")}
31
+ * />
32
+ * ```
33
+ */
34
+ export declare function BetterAuthSignIn({ title, subtitle, socialProviders, showEmail, passwordResetRedirectTo, onSuccess, onError, className, }: BetterAuthSignInProps): import("react/jsx-runtime").JSX.Element | null;
@@ -0,0 +1,149 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BetterAuthSignIn = BetterAuthSignIn;
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 react_2 = require("react");
8
+ const useBetterAuth_1 = require("../../hooks/useBetterAuth");
9
+ const signInUtils_1 = require("./utils/signInUtils");
10
+ const debug = (0, debug_1.debugB3React)("BetterAuthSignIn");
11
+ const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
12
+ const DEFAULT_SOCIAL_PROVIDERS = [
13
+ { id: "google", label: "Google" },
14
+ { id: "github", label: "GitHub" },
15
+ { id: "discord", label: "Discord" },
16
+ { id: "microsoft", label: "Microsoft" },
17
+ { id: "slack", label: "Slack" },
18
+ ];
19
+ /**
20
+ * Standalone inline sign-in component for Better Auth.
21
+ *
22
+ * Renders directly — no modal, no button wrapper. Designed for full-page
23
+ * sign-in layouts (e.g., B3OS web with branding on the left, form on the right).
24
+ *
25
+ * Usage:
26
+ * ```tsx
27
+ * <BetterAuthSignIn
28
+ * socialProviders={["google", "github"]}
29
+ * onSuccess={() => router.push("/dashboard")}
30
+ * />
31
+ * ```
32
+ */
33
+ 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
+ const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = (0, useBetterAuth_1.useBetterAuth)();
35
+ const isAuthenticated = (0, react_1.useAuthStore)(state => state.isAuthenticated);
36
+ const [mode, setMode] = (0, react_2.useState)("sign-in");
37
+ const [email, setEmail] = (0, react_2.useState)("");
38
+ const [password, setPassword] = (0, react_2.useState)("");
39
+ const [name, setName] = (0, react_2.useState)("");
40
+ const [isLoading, setIsLoading] = (0, react_2.useState)(false);
41
+ const [loadingProvider, setLoadingProvider] = (0, react_2.useState)(null);
42
+ const [error, setError] = (0, react_2.useState)(null);
43
+ const [resetEmailSent, setResetEmailSent] = (0, react_2.useState)(false);
44
+ const resolvedTitle = title ||
45
+ (mode === "forgot-password" ? "Reset password" : mode === "sign-in" ? "Welcome back" : "Create an account");
46
+ const resolvedSubtitle = mode === "forgot-password"
47
+ ? "Enter your email and we'll send you a reset link"
48
+ : subtitle || "Enter your credentials to access your account";
49
+ const handleForgotPassword = async () => {
50
+ const normalizedEmail = email.trim().toLowerCase();
51
+ if (!EMAIL_REGEX.test(normalizedEmail)) {
52
+ setError("Please enter a valid email address");
53
+ return;
54
+ }
55
+ try {
56
+ setIsLoading(true);
57
+ setError(null);
58
+ await requestPasswordReset(normalizedEmail, passwordResetRedirectTo);
59
+ setResetEmailSent(true);
60
+ }
61
+ catch (err) {
62
+ const message = err instanceof Error ? err.message : "Failed to send reset email";
63
+ setError(message);
64
+ }
65
+ finally {
66
+ setIsLoading(false);
67
+ }
68
+ };
69
+ const providers = socialProviders
70
+ .map(id => DEFAULT_SOCIAL_PROVIDERS.find(p => p.id === id))
71
+ .filter((p) => !!p);
72
+ if (isAuthenticated) {
73
+ return null;
74
+ }
75
+ const handleEmailSubmit = async () => {
76
+ const normalizedEmail = email.trim().toLowerCase();
77
+ if (!EMAIL_REGEX.test(normalizedEmail)) {
78
+ setError("Please enter a valid email address");
79
+ return;
80
+ }
81
+ if (!password) {
82
+ setError("Please enter a password");
83
+ return;
84
+ }
85
+ if (mode === "sign-up" && !name.trim()) {
86
+ setError("Please enter your name");
87
+ return;
88
+ }
89
+ try {
90
+ setIsLoading(true);
91
+ setError(null);
92
+ if (mode === "sign-up") {
93
+ await signUpWithEmail(normalizedEmail, password, name.trim());
94
+ }
95
+ else {
96
+ await signInWithEmail(normalizedEmail, password);
97
+ }
98
+ debug("Auth successful");
99
+ onSuccess?.();
100
+ }
101
+ catch (err) {
102
+ const message = err instanceof Error ? err.message : "Authentication failed";
103
+ setError(message);
104
+ debug("Auth failed", err);
105
+ onError?.(err);
106
+ }
107
+ finally {
108
+ setPassword("");
109
+ setIsLoading(false);
110
+ }
111
+ };
112
+ const handleSocialSignIn = async (provider) => {
113
+ try {
114
+ setIsLoading(true);
115
+ setLoadingProvider(provider);
116
+ setError(null);
117
+ await signInWithSocial(provider);
118
+ }
119
+ catch (err) {
120
+ const message = err instanceof Error ? err.message : `Sign in failed`;
121
+ setError(message);
122
+ onError?.(err);
123
+ setIsLoading(false);
124
+ setLoadingProvider(null);
125
+ }
126
+ };
127
+ return ((0, jsx_runtime_1.jsxs)("div", { className: `w-full max-w-[400px] px-6 ${className || ""}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-10 text-center", children: [(0, jsx_runtime_1.jsx)("h1", { className: "text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: resolvedTitle }), (0, jsx_runtime_1.jsx)("p", { className: "mt-3 text-[15px] text-gray-500 dark:text-gray-400", children: resolvedSubtitle })] }), mode === "forgot-password" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-5", children: [resetEmailSent ? ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4 text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100", children: (0, jsx_runtime_1.jsx)("svg", { className: "h-6 w-6 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }), (0, jsx_runtime_1.jsx)("p", { className: "text-[15px] text-gray-600 dark:text-gray-300", children: "Check your email for a reset link." })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Email" }), (0, jsx_runtime_1.jsx)(react_1.Input, { type: "email", placeholder: "name@company.com", value: email, onChange: e => setEmail(e.target.value), disabled: isLoading, onKeyDown: e => {
128
+ if (e.key === "Enter")
129
+ handleForgotPassword();
130
+ }, className: "h-11 px-4 text-[15px]" })] }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-red-500", children: error }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: handleForgotPassword, disabled: isLoading, 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: isLoading ? "Sending..." : "Send reset link" })] })), (0, jsx_runtime_1.jsx)("p", { className: "mt-8 text-center text-[14px] text-gray-500 dark:text-gray-400", children: (0, jsx_runtime_1.jsx)("button", { onClick: () => {
131
+ setMode("sign-in");
132
+ setError(null);
133
+ setResetEmailSent(false);
134
+ }, className: "font-medium text-blue-600 hover:text-blue-500 dark:text-blue-400", children: "Back to sign in" }) })] })), showEmail && mode !== "forgot-password" && ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-5", children: [mode === "sign-up" && ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Name" }), (0, jsx_runtime_1.jsx)(react_1.Input, { type: "text", placeholder: "Your name", value: name, onChange: e => setName(e.target.value), disabled: isLoading, className: "h-11 px-4 text-[15px]" })] })), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Email" }), (0, jsx_runtime_1.jsx)(react_1.Input, { type: "email", placeholder: "name@company.com", value: email, onChange: e => setEmail(e.target.value), disabled: isLoading, className: "h-11 px-4 text-[15px]" })] }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "mb-2 flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("label", { className: "block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Password" }), mode === "sign-in" && ((0, jsx_runtime_1.jsx)("button", { type: "button", onClick: () => {
135
+ setMode("forgot-password");
136
+ setError(null);
137
+ }, className: "text-xs font-medium text-blue-600 hover:text-blue-500 dark:text-blue-400", children: "Forgot password?" }))] }), (0, jsx_runtime_1.jsx)(react_1.Input, { type: "password", placeholder: "Password", value: password, onChange: e => setPassword(e.target.value), disabled: isLoading, onKeyDown: e => {
138
+ if (e.key === "Enter")
139
+ handleEmailSubmit();
140
+ }, className: "h-11 px-4 text-[15px]" })] }), error && (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-red-500", children: error }), (0, jsx_runtime_1.jsx)(react_1.Button, { onClick: handleEmailSubmit, disabled: isLoading, 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: isLoading ? "Loading..." : mode === "sign-in" ? "Sign in" : "Sign up" })] })), providers.length > 0 && mode !== "forgot-password" && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [showEmail && ((0, jsx_runtime_1.jsxs)("div", { className: "my-8 flex items-center gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" }), (0, jsx_runtime_1.jsx)("span", { className: "text-xs text-gray-400", children: "Or continue with" }), (0, jsx_runtime_1.jsx)("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" })] })), (0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: providers.map(provider => {
141
+ const icon = signInUtils_1.strategyIcons[provider.id];
142
+ const label = signInUtils_1.strategyLabels[provider.id] || provider.label;
143
+ const isProviderLoading = loadingProvider === provider.id;
144
+ return ((0, jsx_runtime_1.jsxs)("button", { onClick: () => handleSocialSignIn(provider.id), disabled: isLoading, style: { paddingTop: "12px", paddingBottom: "12px" }, className: "flex w-full items-center justify-center gap-3 rounded-lg border border-gray-200 bg-white px-4 text-[14px] font-medium text-gray-700 transition-colors hover:bg-gray-50 disabled:opacity-50 dark:border-gray-700 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700", children: [isProviderLoading ? ((0, jsx_runtime_1.jsxs)("svg", { className: "h-5 w-5 animate-spin text-gray-400", viewBox: "0 0 24 24", fill: "none", children: [(0, jsx_runtime_1.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), (0, jsx_runtime_1.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] })) : (icon && (0, jsx_runtime_1.jsx)("img", { src: icon, alt: "", className: "h-5 w-5" })), (0, jsx_runtime_1.jsx)("span", { children: isProviderLoading ? "Redirecting..." : label })] }, provider.id));
145
+ }) })] })), showEmail && mode !== "forgot-password" && ((0, jsx_runtime_1.jsxs)("p", { className: "mt-8 text-center text-[14px] text-gray-500 dark:text-gray-400", children: [mode === "sign-in" ? "Don't have an account? " : "Already have an account? ", (0, jsx_runtime_1.jsx)("button", { onClick: () => {
146
+ setMode(mode === "sign-in" ? "sign-up" : "sign-in");
147
+ setError(null);
148
+ }, disabled: isLoading, className: "font-medium text-blue-600 hover:text-blue-500 dark:text-blue-400", children: mode === "sign-in" ? "Sign up" : "Sign in" })] }))] }));
149
+ }
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SignInWithB3Flow = SignInWithB3Flow;
4
4
  const jsx_runtime_1 = require("react/jsx-runtime");
5
5
  const react_1 = require("../../../../global-account/react");
6
+ const LoginStepBetterAuth_1 = require("./steps/LoginStepBetterAuth");
6
7
  const debug_1 = require("../../../../shared/utils/debug");
7
8
  const react_2 = require("react");
8
9
  const react_3 = require("thirdweb/react");
@@ -16,18 +17,20 @@ const MAX_REFETCH_ATTEMPTS = 20;
16
17
  * Handles different login providers, authentication steps, and session key management
17
18
  */
18
19
  function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onError, chain, sessionKeyAddress, partnerId, closeAfterLogin = false, source = "signInWithB3Button", signersEnabled = false, }) {
19
- const { automaticallySetFirstEoa } = (0, react_1.useB3Config)();
20
+ const { automaticallySetFirstEoa, authStrategy } = (0, react_1.useB3Config)();
20
21
  // skipAutoConnect: this component intentionally logs out on mount to show a fresh login screen.
21
22
  // AuthenticationProvider is the sole owner of useAutoConnect to avoid competing auth cycles.
22
23
  const { user, logout } = (0, react_1.useAuthentication)(partnerId, { skipAutoConnect: true });
23
24
  // Tracks whether the pre-login logout has finished.
24
25
  // We must not render ConnectEmbed until logout (wallet disconnect) completes,
25
26
  // otherwise the wallet state disrupts ConnectEmbed causing a blank modal.
26
- const [readyToShowLogin, setReadyToShowLogin] = (0, react_2.useState)(source === "requestPermissions");
27
+ const [readyToShowLogin, setReadyToShowLogin] = (0, react_2.useState)(source === "requestPermissions" || authStrategy === "better-auth");
27
28
  const hasLoggedOutRef = (0, react_2.useRef)(false);
28
29
  (0, react_2.useEffect)(() => {
29
30
  if (hasLoggedOutRef.current)
30
31
  return;
32
+ if (authStrategy === "better-auth")
33
+ return;
31
34
  if (source !== "requestPermissions") {
32
35
  debug("Logging out before login");
33
36
  hasLoggedOutRef.current = true;
@@ -35,7 +38,7 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
35
38
  setReadyToShowLogin(true);
36
39
  });
37
40
  }
38
- }, [source, logout]);
41
+ }, [source, logout, authStrategy]);
39
42
  const [step, setStep] = (0, react_2.useState)(source === "requestPermissions" ? null : "login");
40
43
  const [sessionKeyAdded, setSessionKeyAdded] = (0, react_2.useState)(source === "requestPermissions" ? true : false);
41
44
  const { setB3ModalContentType, setB3ModalOpen, isOpen, contentType } = (0, react_1.useModalStore)();
@@ -243,6 +246,9 @@ function SignInWithB3Flow({ strategies, onLoginSuccess, onSessionKeySuccess, onE
243
246
  if (!readyToShowLogin || isAuthenticating || isFetchingSigners) {
244
247
  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" }) }) }));
245
248
  }
249
+ else if (authStrategy === "better-auth") {
250
+ content = (0, jsx_runtime_1.jsx)(LoginStepBetterAuth_1.LoginStepBetterAuth, { onSuccess: () => handleLoginSuccess({}), onError: onError });
251
+ }
246
252
  else {
247
253
  // Custom strategy
248
254
  if (strategies?.[0] === "privy") {
@@ -0,0 +1,6 @@
1
+ interface LoginStepBetterAuthProps {
2
+ onSuccess?: () => void;
3
+ onError?: (error: Error) => Promise<void>;
4
+ }
5
+ export declare function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthProps): import("react/jsx-runtime").JSX.Element;
6
+ export {};