@b3dotfun/sdk 0.1.69-test.0 → 0.1.70-alpha.1

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 (190) hide show
  1. package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -0
  2. package/dist/cjs/anyspend/react/components/AnySpend.js +12 -4
  3. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +5 -1
  4. package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +2 -2
  5. package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +2 -0
  6. package/dist/cjs/anyspend/react/components/AnySpendCustom.js +7 -3
  7. package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  8. package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +3 -3
  9. package/dist/cjs/anyspend/react/components/AnySpendNFT.d.ts +3 -1
  10. package/dist/cjs/anyspend/react/components/AnySpendNFT.js +2 -2
  11. package/dist/cjs/anyspend/react/components/AnySpendStakeUpside.d.ts +3 -1
  12. package/dist/cjs/anyspend/react/components/AnySpendStakeUpside.js +2 -2
  13. package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.js +6 -5
  14. package/dist/cjs/anyspend/react/components/checkout/CartItemRow.d.ts +2 -1
  15. package/dist/cjs/anyspend/react/components/checkout/CartSummary.d.ts +6 -4
  16. package/dist/cjs/anyspend/react/components/checkout/CartSummary.js +13 -11
  17. package/dist/cjs/anyspend/react/components/checkout/CheckoutCartPanel.d.ts +3 -1
  18. package/dist/cjs/anyspend/react/components/checkout/CheckoutCartPanel.js +5 -4
  19. package/dist/cjs/anyspend/react/components/checkout/CheckoutFormPanel.d.ts +3 -1
  20. package/dist/cjs/anyspend/react/components/checkout/CheckoutFormPanel.js +2 -2
  21. package/dist/cjs/anyspend/react/components/checkout/DiscountCodeInput.d.ts +3 -1
  22. package/dist/cjs/anyspend/react/components/checkout/DiscountCodeInput.js +3 -6
  23. package/dist/cjs/anyspend/react/components/checkout/PriceSkeleton.d.ts +5 -0
  24. package/dist/cjs/anyspend/react/components/checkout/PriceSkeleton.js +9 -0
  25. package/dist/cjs/anyspend/react/components/checkout/ShippingSelector.d.ts +3 -1
  26. package/dist/cjs/anyspend/react/components/checkout/ShippingSelector.js +3 -2
  27. package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +3 -1
  28. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +5 -1
  29. package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +2 -1
  30. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +17 -1
  31. package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +3 -2
  32. package/dist/cjs/global-account/react/components/B3Provider/BetterAuthClientProvider.d.ts +17 -0
  33. package/dist/cjs/global-account/react/components/B3Provider/BetterAuthClientProvider.js +31 -0
  34. package/dist/cjs/global-account/react/components/B3Provider/BetterAuthProvider.js +6 -5
  35. package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +4 -2
  36. package/dist/cjs/global-account/react/components/ManageAccount/Header.js +36 -4
  37. package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.js +4 -1
  38. package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +6 -0
  39. package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +5 -3
  40. package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +3 -1
  41. package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +25 -14
  42. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthResetPassword.js +3 -2
  43. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
  44. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +15 -5
  45. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
  46. package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.js +85 -0
  47. package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +14 -4
  48. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
  49. package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -2
  50. package/dist/cjs/global-account/react/components/SignInWithB3/components/PasswordInput.d.ts +10 -0
  51. package/dist/cjs/global-account/react/components/SignInWithB3/components/PasswordInput.js +10 -0
  52. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
  53. package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +8 -5
  54. package/dist/cjs/global-account/react/components/UserAvatar/UserAvatar.d.ts +18 -0
  55. package/dist/cjs/global-account/react/components/UserAvatar/UserAvatar.js +27 -0
  56. package/dist/cjs/global-account/react/components/index.d.ts +3 -0
  57. package/dist/cjs/global-account/react/components/index.js +10 -3
  58. package/dist/cjs/global-account/react/hooks/useBetterAuth.d.ts +1 -1
  59. package/dist/cjs/global-account/react/hooks/useBetterAuth.js +19 -17
  60. package/dist/cjs/global-account/react/stores/useModalStore.d.ts +4 -0
  61. package/dist/cjs/shared/constants/index.d.ts +1 -0
  62. package/dist/cjs/shared/constants/index.js +2 -1
  63. package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -0
  64. package/dist/esm/anyspend/react/components/AnySpend.js +12 -4
  65. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +5 -1
  66. package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +2 -2
  67. package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +2 -0
  68. package/dist/esm/anyspend/react/components/AnySpendCustom.js +7 -3
  69. package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  70. package/dist/esm/anyspend/react/components/AnySpendDeposit.js +3 -3
  71. package/dist/esm/anyspend/react/components/AnySpendNFT.d.ts +3 -1
  72. package/dist/esm/anyspend/react/components/AnySpendNFT.js +2 -2
  73. package/dist/esm/anyspend/react/components/AnySpendStakeUpside.d.ts +3 -1
  74. package/dist/esm/anyspend/react/components/AnySpendStakeUpside.js +2 -2
  75. package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.js +6 -5
  76. package/dist/esm/anyspend/react/components/checkout/CartItemRow.d.ts +2 -1
  77. package/dist/esm/anyspend/react/components/checkout/CartSummary.d.ts +6 -4
  78. package/dist/esm/anyspend/react/components/checkout/CartSummary.js +13 -11
  79. package/dist/esm/anyspend/react/components/checkout/CheckoutCartPanel.d.ts +3 -1
  80. package/dist/esm/anyspend/react/components/checkout/CheckoutCartPanel.js +5 -4
  81. package/dist/esm/anyspend/react/components/checkout/CheckoutFormPanel.d.ts +3 -1
  82. package/dist/esm/anyspend/react/components/checkout/CheckoutFormPanel.js +2 -2
  83. package/dist/esm/anyspend/react/components/checkout/DiscountCodeInput.d.ts +3 -1
  84. package/dist/esm/anyspend/react/components/checkout/DiscountCodeInput.js +3 -6
  85. package/dist/esm/anyspend/react/components/checkout/PriceSkeleton.d.ts +5 -0
  86. package/dist/esm/anyspend/react/components/checkout/PriceSkeleton.js +6 -0
  87. package/dist/esm/anyspend/react/components/checkout/ShippingSelector.d.ts +3 -1
  88. package/dist/esm/anyspend/react/components/checkout/ShippingSelector.js +3 -2
  89. package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +3 -1
  90. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +5 -1
  91. package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +2 -1
  92. package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +17 -1
  93. package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +3 -2
  94. package/dist/esm/global-account/react/components/B3Provider/BetterAuthClientProvider.d.ts +17 -0
  95. package/dist/esm/global-account/react/components/B3Provider/BetterAuthClientProvider.js +27 -0
  96. package/dist/esm/global-account/react/components/B3Provider/BetterAuthProvider.js +4 -3
  97. package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +5 -3
  98. package/dist/esm/global-account/react/components/ManageAccount/Header.js +37 -5
  99. package/dist/esm/global-account/react/components/ManageAccount/HomeContent.js +4 -1
  100. package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +7 -1
  101. package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +6 -4
  102. package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +5 -3
  103. package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +25 -14
  104. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthResetPassword.js +4 -3
  105. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
  106. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +16 -6
  107. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
  108. package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.js +82 -0
  109. package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +15 -5
  110. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
  111. package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -2
  112. package/dist/esm/global-account/react/components/SignInWithB3/components/PasswordInput.d.ts +10 -0
  113. package/dist/esm/global-account/react/components/SignInWithB3/components/PasswordInput.js +7 -0
  114. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
  115. package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +8 -5
  116. package/dist/esm/global-account/react/components/UserAvatar/UserAvatar.d.ts +18 -0
  117. package/dist/esm/global-account/react/components/UserAvatar/UserAvatar.js +21 -0
  118. package/dist/esm/global-account/react/components/index.d.ts +3 -0
  119. package/dist/esm/global-account/react/components/index.js +4 -0
  120. package/dist/esm/global-account/react/hooks/useBetterAuth.d.ts +1 -1
  121. package/dist/esm/global-account/react/hooks/useBetterAuth.js +12 -10
  122. package/dist/esm/global-account/react/stores/useModalStore.d.ts +4 -0
  123. package/dist/esm/shared/constants/index.d.ts +1 -0
  124. package/dist/esm/shared/constants/index.js +1 -0
  125. package/dist/styles/index.css +1 -1
  126. package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -0
  127. package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +5 -1
  128. package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +2 -0
  129. package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
  130. package/dist/types/anyspend/react/components/AnySpendNFT.d.ts +3 -1
  131. package/dist/types/anyspend/react/components/AnySpendStakeUpside.d.ts +3 -1
  132. package/dist/types/anyspend/react/components/checkout/CartItemRow.d.ts +2 -1
  133. package/dist/types/anyspend/react/components/checkout/CartSummary.d.ts +6 -4
  134. package/dist/types/anyspend/react/components/checkout/CheckoutCartPanel.d.ts +3 -1
  135. package/dist/types/anyspend/react/components/checkout/CheckoutFormPanel.d.ts +3 -1
  136. package/dist/types/anyspend/react/components/checkout/DiscountCodeInput.d.ts +3 -1
  137. package/dist/types/anyspend/react/components/checkout/PriceSkeleton.d.ts +5 -0
  138. package/dist/types/anyspend/react/components/checkout/ShippingSelector.d.ts +3 -1
  139. package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +5 -1
  140. package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +17 -1
  141. package/dist/types/global-account/react/components/B3Provider/BetterAuthClientProvider.d.ts +17 -0
  142. package/dist/types/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
  143. package/dist/types/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
  144. package/dist/types/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
  145. package/dist/types/global-account/react/components/SignInWithB3/components/PasswordInput.d.ts +10 -0
  146. package/dist/types/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
  147. package/dist/types/global-account/react/components/UserAvatar/UserAvatar.d.ts +18 -0
  148. package/dist/types/global-account/react/components/index.d.ts +3 -0
  149. package/dist/types/global-account/react/hooks/useBetterAuth.d.ts +1 -1
  150. package/dist/types/global-account/react/stores/useModalStore.d.ts +4 -0
  151. package/dist/types/shared/constants/index.d.ts +1 -0
  152. package/package.json +1 -1
  153. package/src/anyspend/react/components/AnySpend.tsx +24 -12
  154. package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +6 -0
  155. package/src/anyspend/react/components/AnySpendCustom.tsx +12 -2
  156. package/src/anyspend/react/components/AnySpendDeposit.tsx +38 -31
  157. package/src/anyspend/react/components/AnySpendNFT.tsx +4 -0
  158. package/src/anyspend/react/components/AnySpendStakeUpside.tsx +4 -0
  159. package/src/anyspend/react/components/checkout/AnySpendCheckout.tsx +10 -4
  160. package/src/anyspend/react/components/checkout/CartItemRow.tsx +2 -1
  161. package/src/anyspend/react/components/checkout/CartSummary.tsx +24 -20
  162. package/src/anyspend/react/components/checkout/CheckoutCartPanel.tsx +12 -3
  163. package/src/anyspend/react/components/checkout/CheckoutFormPanel.tsx +5 -0
  164. package/src/anyspend/react/components/checkout/DiscountCodeInput.tsx +15 -5
  165. package/src/anyspend/react/components/checkout/PriceSkeleton.tsx +19 -0
  166. package/src/anyspend/react/components/checkout/ShippingSelector.tsx +5 -1
  167. package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +3 -1
  168. package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +6 -0
  169. package/src/global-account/react/components/B3Provider/B3Provider.tsx +36 -15
  170. package/src/global-account/react/components/B3Provider/BetterAuthClientProvider.tsx +40 -0
  171. package/src/global-account/react/components/B3Provider/BetterAuthProvider.tsx +4 -3
  172. package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +18 -14
  173. package/src/global-account/react/components/ManageAccount/Header.tsx +71 -4
  174. package/src/global-account/react/components/ManageAccount/HomeContent.tsx +25 -19
  175. package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +13 -0
  176. package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +14 -7
  177. package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +15 -32
  178. package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +29 -20
  179. package/src/global-account/react/components/SignInWithB3/BetterAuthResetPassword.tsx +6 -7
  180. package/src/global-account/react/components/SignInWithB3/BetterAuthSignIn.tsx +27 -7
  181. package/src/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.tsx +155 -0
  182. package/src/global-account/react/components/SignInWithB3/SignIn.tsx +42 -13
  183. package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +8 -1
  184. package/src/global-account/react/components/SignInWithB3/components/PasswordInput.tsx +62 -0
  185. package/src/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.tsx +13 -6
  186. package/src/global-account/react/components/UserAvatar/UserAvatar.tsx +45 -0
  187. package/src/global-account/react/components/index.ts +9 -0
  188. package/src/global-account/react/hooks/useBetterAuth.ts +12 -10
  189. package/src/global-account/react/stores/useModalStore.ts +4 -0
  190. package/src/shared/constants/index.ts +2 -0
@@ -15,8 +15,10 @@ export interface B3ConfigContextType {
15
15
  stripePublishableKey?: string;
16
16
  createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
17
17
  authStrategy: AuthStrategy;
18
+ /** Override the API base URL for all auth operations (Better Auth client, Feathers JWT exchange). */
19
+ apiUrl?: string;
18
20
  }
19
- export declare function B3ConfigProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, stripePublishableKey, createClientReferenceId, authStrategy, }: {
21
+ export declare function B3ConfigProvider({ children, accountOverride, environment, defaultPermissions, automaticallySetFirstEoa, theme, clientType, partnerId, stripePublishableKey, createClientReferenceId, authStrategy, apiUrl, }: {
20
22
  children: React.ReactNode;
21
23
  accountOverride?: Account;
22
24
  environment?: "development" | "production";
@@ -28,5 +30,7 @@ export declare function B3ConfigProvider({ children, accountOverride, environmen
28
30
  stripePublishableKey?: string;
29
31
  createClientReferenceId?: (params: CreateOrderParams | CreateOnrampOrderParams) => Promise<string>;
30
32
  authStrategy?: AuthStrategy;
33
+ /** Override the API base URL for all auth operations (Better Auth client, Feathers JWT exchange). */
34
+ apiUrl?: string;
31
35
  }): import("react/jsx-runtime").JSX.Element;
32
36
  export declare function useB3Config(): B3ConfigContextType;
@@ -10,7 +10,7 @@ const DEFAULT_PERMISSIONS = {
10
10
  endDate: new Date(Date.now() + 1000 * 60 * 60 * 24 * 365), // 1 year from now
11
11
  };
12
12
  const B3ConfigContext = createContext(null);
13
- export function B3ConfigProvider({ children, accountOverride, environment = "development", defaultPermissions = DEFAULT_PERMISSIONS, automaticallySetFirstEoa = false, theme = "light", clientType = "rest", partnerId, stripePublishableKey, createClientReferenceId, authStrategy = "thirdweb", }) {
13
+ export function B3ConfigProvider({ children, accountOverride, environment = "development", defaultPermissions = DEFAULT_PERMISSIONS, automaticallySetFirstEoa = false, theme = "light", clientType = "rest", partnerId, stripePublishableKey, createClientReferenceId, authStrategy = "thirdweb", apiUrl, }) {
14
14
  return (_jsx(B3ConfigContext.Provider, { value: {
15
15
  accountOverride,
16
16
  environment,
@@ -22,6 +22,7 @@ export function B3ConfigProvider({ children, accountOverride, environment = "dev
22
22
  stripePublishableKey,
23
23
  createClientReferenceId,
24
24
  authStrategy,
25
+ apiUrl,
25
26
  }, children: children }));
26
27
  }
27
28
  export function useB3Config() {
@@ -10,7 +10,7 @@ import { ClientType } from "../../../client-manager";
10
10
  /**
11
11
  * Main B3Provider component
12
12
  */
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
+ 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, apiUrl, }: {
14
14
  theme: "light" | "dark";
15
15
  children: React.ReactNode;
16
16
  accountOverride?: Account;
@@ -39,4 +39,20 @@ export declare function B3Provider({ theme, children, accountOverride, environme
39
39
  queryClient?: QueryClient;
40
40
  /** Auth strategy: "thirdweb" (default, ecosystem wallet) or "better-auth" (email/password via Better Auth) */
41
41
  authStrategy?: AuthStrategy;
42
+ /**
43
+ * Override the API base URL for Better Auth operations.
44
+ *
45
+ * When set, the Better Auth client (signIn, signUp, signOut, getSession) will
46
+ * target this URL instead of the default `B3_API_URL` / `NEXT_PUBLIC_B3_API`.
47
+ *
48
+ * Useful for local development where the frontend runs on localhost:3003 and
49
+ * the b3-api runs on localhost:3031 — keeps the entire OAuth flow local so
50
+ * sessions, cookies, and token exchange all hit the same server.
51
+ *
52
+ * @example
53
+ * ```tsx
54
+ * <B3Provider apiUrl="http://localhost:3031" ... />
55
+ * ```
56
+ */
57
+ apiUrl?: string;
42
58
  }): import("react/jsx-runtime").JSX.Element;
@@ -10,6 +10,7 @@ import { StyleRoot } from "../StyleRoot.js";
10
10
  import { setToastContext, ToastProvider, useToastContext } from "../Toast/index.js";
11
11
  import AuthenticationProvider from "./AuthenticationProvider.js";
12
12
  import { B3ConfigProvider } from "./B3ConfigProvider.js";
13
+ import { BetterAuthClientProvider } from "./BetterAuthClientProvider.js";
13
14
  import BetterAuthProvider from "./BetterAuthProvider.js";
14
15
  import { LocalSDKProvider } from "./LocalSDKProvider.js";
15
16
  /**
@@ -17,7 +18,7 @@ import { LocalSDKProvider } from "./LocalSDKProvider.js";
17
18
  */
18
19
  export function B3Provider({ theme = "light", children, accountOverride, environment, automaticallySetFirstEoa, defaultEoaProvider, simDuneApiKey,
19
20
  // deprecated since v0.0.87
20
- toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey, onConnect, onLogout, connectors, overrideDefaultConnectors = false, createClientReferenceId, defaultPermissions, disableBSMNTAuthentication = false, queryClient, authStrategy = "thirdweb", }) {
21
+ toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey, onConnect, onLogout, connectors, overrideDefaultConnectors = false, createClientReferenceId, defaultPermissions, disableBSMNTAuthentication = false, queryClient, authStrategy = "thirdweb", apiUrl, }) {
21
22
  // Initialize Google Analytics on mount
22
23
  useEffect(() => {
23
24
  loadGA4Script();
@@ -27,7 +28,7 @@ toaster: _toaster, clientType = "rest", rpcUrls, partnerId, stripePublishableKey
27
28
  setClientType(clientType);
28
29
  }, [clientType]);
29
30
  const wagmiConfig = useMemo(() => createWagmiConfig({ partnerId, rpcUrls, connectors, overrideDefaultConnectors }), [partnerId, rpcUrls, connectors, overrideDefaultConnectors]);
30
- return (_jsx(WalletProvider, { wagmiConfig: wagmiConfig, queryClient: queryClient, children: _jsx(TooltipProvider, { children: _jsx(ToastProvider, { children: _jsx(LocalSDKProvider, { onConnectCallback: onConnect, onLogoutCallback: onLogout, disableBSMNTAuthentication: disableBSMNTAuthentication, children: _jsxs(B3ConfigProvider, { accountOverride: accountOverride, environment: environment, automaticallySetFirstEoa: !!automaticallySetFirstEoa, theme: theme, clientType: clientType, partnerId: partnerId, stripePublishableKey: stripePublishableKey, createClientReferenceId: createClientReferenceId, defaultPermissions: defaultPermissions, authStrategy: authStrategy, children: [_jsx(ToastContextConnector, {}), _jsxs(RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, _jsx(StyleRoot, { id: "b3-root" })] }), authStrategy === "better-auth" ? (_jsx(BetterAuthProvider, { partnerId: partnerId })) : (_jsx(AuthenticationProvider, { partnerId: partnerId, automaticallySetFirstEoa: !!automaticallySetFirstEoa, defaultEoaProvider: defaultEoaProvider }))] }) }) }) }) }));
31
+ return (_jsx(WalletProvider, { wagmiConfig: wagmiConfig, queryClient: queryClient, children: _jsx(TooltipProvider, { children: _jsx(ToastProvider, { children: _jsx(LocalSDKProvider, { onConnectCallback: onConnect, onLogoutCallback: onLogout, disableBSMNTAuthentication: disableBSMNTAuthentication, children: _jsx(B3ConfigProvider, { accountOverride: accountOverride, environment: environment, automaticallySetFirstEoa: !!automaticallySetFirstEoa, theme: theme, clientType: clientType, partnerId: partnerId, stripePublishableKey: stripePublishableKey, createClientReferenceId: createClientReferenceId, defaultPermissions: defaultPermissions, authStrategy: authStrategy, apiUrl: apiUrl, children: _jsxs(BetterAuthClientProvider, { apiUrl: apiUrl, children: [_jsx(ToastContextConnector, {}), _jsxs(RelayKitProviderWrapper, { simDuneApiKey: simDuneApiKey, children: [children, _jsx(StyleRoot, { id: "b3-root" })] }), authStrategy === "better-auth" ? (_jsx(BetterAuthProvider, { partnerId: partnerId })) : (_jsx(AuthenticationProvider, { partnerId: partnerId, automaticallySetFirstEoa: !!automaticallySetFirstEoa, defaultEoaProvider: defaultEoaProvider }))] }) }) }) }) }) }));
31
32
  }
32
33
  /**
33
34
  * Component to connect the toast context to the global toast API
@@ -0,0 +1,17 @@
1
+ import { type B3BetterAuthClient } from "../../../better-auth-client";
2
+ /**
3
+ * Provides a Better Auth client instance to the subtree.
4
+ *
5
+ * When `apiUrl` is supplied, a custom client targeting that URL is created
6
+ * (e.g. `http://localhost:3031` for local development). Otherwise, the
7
+ * default singleton (which uses `B3_API_URL` / `NEXT_PUBLIC_B3_API`) is used.
8
+ */
9
+ export declare function BetterAuthClientProvider({ children, apiUrl, }: {
10
+ children: React.ReactNode;
11
+ apiUrl?: string;
12
+ }): import("react/jsx-runtime").JSX.Element;
13
+ /**
14
+ * Returns the Better Auth client from the nearest `BetterAuthClientProvider`.
15
+ * Falls back to the default singleton if no provider is present.
16
+ */
17
+ export declare function useBetterAuthClient(): B3BetterAuthClient;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { createContext, useContext, useMemo } from "react";
3
+ import { betterAuthClient, createB3BetterAuthClient, } from "../../../better-auth-client.js";
4
+ const BetterAuthClientContext = createContext(betterAuthClient);
5
+ /**
6
+ * Provides a Better Auth client instance to the subtree.
7
+ *
8
+ * When `apiUrl` is supplied, a custom client targeting that URL is created
9
+ * (e.g. `http://localhost:3031` for local development). Otherwise, the
10
+ * default singleton (which uses `B3_API_URL` / `NEXT_PUBLIC_B3_API`) is used.
11
+ */
12
+ export function BetterAuthClientProvider({ children, apiUrl, }) {
13
+ const client = useMemo(() => {
14
+ if (apiUrl) {
15
+ return createB3BetterAuthClient(apiUrl);
16
+ }
17
+ return betterAuthClient;
18
+ }, [apiUrl]);
19
+ return _jsx(BetterAuthClientContext.Provider, { value: client, children: children });
20
+ }
21
+ /**
22
+ * Returns the Better Auth client from the nearest `BetterAuthClientProvider`.
23
+ * Falls back to the default singleton if no provider is present.
24
+ */
25
+ export function useBetterAuthClient() {
26
+ return useContext(BetterAuthClientContext);
27
+ }
@@ -4,8 +4,8 @@ import { B3_AUTH_COOKIE_NAME } from "../../../../shared/constants/index.js";
4
4
  import { debugB3React } from "../../../../shared/utils/debug.js";
5
5
  import Cookies from "js-cookie";
6
6
  import { useEffect, useRef } from "react";
7
- import { betterAuthClient } from "../../../better-auth-client.js";
8
7
  import { useUserQuery } from "../../hooks/useUserQuery.js";
8
+ import { useBetterAuthClient } from "./BetterAuthClientProvider.js";
9
9
  const debug = debugB3React("BetterAuthProvider");
10
10
  /**
11
11
  * Parallel to AuthenticationProvider for Better Auth strategy.
@@ -20,6 +20,7 @@ const debug = debugB3React("BetterAuthProvider");
20
20
  * useAuth, SignIn component, etc.) automatically clears the Better Auth session.
21
21
  */
22
22
  const BetterAuthProvider = ({ partnerId }) => {
23
+ const betterAuthClient = useBetterAuthClient();
23
24
  const setIsAuthenticated = useAuthStore(state => state.setIsAuthenticated);
24
25
  const setIsAuthenticating = useAuthStore(state => state.setIsAuthenticating);
25
26
  const setIsConnected = useAuthStore(state => state.setIsConnected);
@@ -51,7 +52,7 @@ const BetterAuthProvider = ({ partnerId }) => {
51
52
  app.logout = originalLogout;
52
53
  hasPatched.current = false;
53
54
  };
54
- }, []);
55
+ }, [betterAuthClient]);
55
56
  // Session restore on mount
56
57
  useEffect(() => {
57
58
  if (hasAttemptedRestore.current)
@@ -109,7 +110,7 @@ const BetterAuthProvider = ({ partnerId }) => {
109
110
  setIsAuthenticating(false);
110
111
  };
111
112
  restoreSession();
112
- }, [setIsAuthenticated, setIsAuthenticating, setIsConnected, setUser, partnerId]);
113
+ }, [setIsAuthenticated, setIsAuthenticating, setIsConnected, setUser, partnerId, betterAuthClient]);
113
114
  return null;
114
115
  };
115
116
  export default BetterAuthProvider;
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { TabsListPrimitive, TabTriggerPrimitive, useModalStore } from "../../../../global-account/react/index.js";
2
+ import { TabsListPrimitive, TabTriggerPrimitive, useB3Config, useModalStore } from "../../../../global-account/react/index.js";
3
3
  const HomeIcon = () => {
4
4
  return (_jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M12.5227 1.33636C12.1804 1.24368 11.8196 1.24368 11.4773 1.33636C11.08 1.44395 10.7454 1.7066 10.4784 1.91623L10.4038 1.97465L3.54376 7.31012C3.16713 7.6024 2.83532 7.85991 2.58806 8.19421C2.37107 8.48759 2.20942 8.8181 2.11106 9.1695C1.99898 9.56992 1.99943 9.98993 1.99995 10.4667L2.00002 17.8385C2 18.3657 1.99998 18.8204 2.03059 19.195C2.06289 19.5904 2.1342 19.9836 2.327 20.362C2.61462 20.9264 3.07356 21.3854 3.63805 21.673C4.01643 21.8658 4.40964 21.9371 4.80499 21.9694C5.17956 22 5.63431 22 6.16145 22H17.8386C18.3657 22 18.8205 22 19.195 21.9694C19.5904 21.9371 19.9836 21.8658 20.362 21.673C20.9265 21.3854 21.3854 20.9264 21.673 20.362C21.8658 19.9836 21.9371 19.5904 21.9694 19.195C22.0001 18.8204 22 18.3657 22 17.8386L22.0001 10.4667C22.0006 9.98993 22.0011 9.56992 21.889 9.1695C21.7906 8.8181 21.629 8.48759 21.412 8.19421C21.1647 7.8599 20.8329 7.6024 20.4563 7.31011L13.5963 1.97465L13.5216 1.91623C13.2546 1.7066 12.9201 1.44395 12.5227 1.33636ZM8.00003 16C7.44775 16 7.00003 16.4477 7.00003 17C7.00003 17.5523 7.44775 18 8.00003 18H16C16.5523 18 17 17.5523 17 17C17 16.4477 16.5523 16 16 16H8.00003Z", fill: "currentColor" }) }));
5
5
  };
@@ -11,11 +11,13 @@ const SettingsIcon = () => {
11
11
  };
12
12
  const BottomNavigation = () => {
13
13
  const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
14
- return (_jsx("div", { className: "b3-modal-bottom-navigation sticky bottom-0 left-0 w-full rounded-b-xl border-t border-gray-200 bg-[#FAFAFA]", children: _jsxs(TabsListPrimitive, { className: "flex h-[68px] w-full items-center justify-center gap-4 border-none bg-transparent", children: [_jsxs(TabTriggerPrimitive, { value: "home", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", children: [_jsx(HomeIcon, {}), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Home" })] }), _jsxs(TabTriggerPrimitive, { value: "swap", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", onClick: () => {
14
+ const { authStrategy } = useB3Config();
15
+ const isBetterAuth = authStrategy === "better-auth";
16
+ return (_jsx("div", { className: "b3-modal-bottom-navigation sticky bottom-0 left-0 w-full rounded-b-xl border-t border-gray-200 bg-[#FAFAFA]", children: _jsxs(TabsListPrimitive, { className: "flex h-[68px] w-full items-center justify-center gap-4 border-none bg-transparent", children: [_jsxs(TabTriggerPrimitive, { value: "home", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", children: [_jsx(HomeIcon, {}), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Home" })] }), !isBetterAuth && (_jsxs(TabTriggerPrimitive, { value: "swap", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", onClick: () => {
15
17
  setB3ModalContentType({
16
18
  type: "anySpend",
17
19
  showBackButton: true,
18
20
  });
19
- }, children: [_jsx(SwapIcon, {}), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Swap" })] }), _jsxs(TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", children: [_jsx(SettingsIcon, {}), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Settings" })] })] }) }));
21
+ }, children: [_jsx(SwapIcon, {}), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Swap" })] })), _jsxs(TabTriggerPrimitive, { value: "settings", className: "data-[state=active]:border-b3-primary-blue group flex flex-initial flex-col items-center gap-1 border-r-0 border-t-0 px-6 pb-2 pt-2.5 text-[#a0a0ab] data-[state=active]:border-t-4 data-[state=active]:text-[#18181B] dark:data-[state=active]:text-white", children: [_jsx(SettingsIcon, {}), _jsx("span", { className: "text-b3-grey font-neue-montreal-semibold text-xs", children: "Settings" })] })] }) }));
20
22
  };
21
23
  export default BottomNavigation;
@@ -1,10 +1,11 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { CopyToClipboard, useAuthentication, useModalStore, } from "../../../../global-account/react/index.js";
2
+ import { CopyToClipboard, useAuthentication, useB3Config, useModalStore, } from "../../../../global-account/react/index.js";
3
3
  import * as AccordionPrimitive from "@radix-ui/react-accordion";
4
4
  import { AnimatePresence, motion } from "framer-motion";
5
5
  import { Loader2 } from "lucide-react";
6
6
  import { useState } from "react";
7
7
  import { useActiveWallet, useConnectedWallets, useSetActiveWallet, useWalletImage } from "thirdweb/react";
8
+ import { UserAvatar } from "../UserAvatar/UserAvatar.js";
8
9
  import { ChevronDownIcon } from "../icons/ChevronDownIcon.js";
9
10
  import LinkIcon from "../icons/LinkIcon.js";
10
11
  import SignOutIcon from "../icons/SignOutIcon.js";
@@ -39,7 +40,34 @@ function WalletItem({ wallet, isActive, onClick }) {
39
40
  : "Wallet";
40
41
  return (_jsxs("div", { className: `b3-modal-wallet-item ${isActive ? "b3-modal-wallet-item-active dark:bg-b3-line bg-[#F4F4F5]" : "hover:bg-b3-line/50"} box-border flex cursor-pointer items-center gap-2 rounded-xl px-3 py-2 transition-colors`, onClick: onClick, children: [_jsx("div", { className: "relative size-10 shrink-0 text-clip rounded-full", children: isGlobalAccount ? (_jsx("div", { className: "flex size-full items-center justify-center p-1", children: _jsx("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "size-full object-contain" }) })) : walletImage ? (_jsx("img", { src: walletImage, alt: walletName, className: "size-full object-contain p-1" })) : (_jsx("div", { className: "flex size-full items-center justify-center", children: _jsx(WalletIcon, {}) })) }), _jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-1", children: [_jsx("p", { className: "text-b3-grey font-neue-montreal-semibold truncate text-sm", children: walletName }), _jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: centerTruncate(address, 4) })] }), isActive && (_jsx("div", { className: "shrink-0", children: _jsx(CheckIcon, {}) }))] }));
41
42
  }
43
+ function BetterAuthHeader({ onLogout }) {
44
+ const contentType = useModalStore(state => state.contentType);
45
+ const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
46
+ const partnerId = contentType?.partnerId;
47
+ const { logout, user } = useAuthentication(partnerId);
48
+ const [logoutLoading, setLogoutLoading] = useState(false);
49
+ const displayName = user?.username || user?.email || "Account";
50
+ const onLogoutEnhanced = async () => {
51
+ setLogoutLoading(true);
52
+ try {
53
+ await logout();
54
+ onLogout?.();
55
+ }
56
+ finally {
57
+ setB3ModalOpen(false);
58
+ setLogoutLoading(false);
59
+ }
60
+ };
61
+ return (_jsxs("div", { className: "bg-b3-background border-b3-line flex items-center justify-between border-b px-5 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(UserAvatar, { avatarUrl: user?.avatar, name: displayName, size: 40, className: "shrink-0" }), _jsxs("div", { className: "flex flex-col gap-0.5", children: [user?.username && (_jsx("p", { className: "text-b3-grey font-neue-montreal-semibold text-left text-sm", children: user.username })), user?.email && (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("p", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: user.email }), _jsx(CopyToClipboard, { text: user.email })] }))] })] }), _jsxs("button", { className: "border-b3-line hover:bg-b3-line flex items-center justify-center gap-1.5 rounded-xl border border-solid px-3 py-2 transition-colors", onClick: onLogoutEnhanced, disabled: logoutLoading, children: [logoutLoading ? (_jsx(Loader2, { className: "animate-spin", size: 16 })) : (_jsx(SignOutIcon, { size: 16, className: "text-b3-grey" })), _jsx("p", { className: "text-b3-grey font-neue-montreal-semibold text-sm", children: "Sign out" })] })] }));
62
+ }
42
63
  export function Header({ onLogout }) {
64
+ const { authStrategy } = useB3Config();
65
+ if (authStrategy === "better-auth") {
66
+ return _jsx(BetterAuthHeader, { onLogout: onLogout });
67
+ }
68
+ return _jsx(WalletHeader, { onLogout: onLogout });
69
+ }
70
+ function WalletHeader({ onLogout }) {
43
71
  const activeWallet = useActiveWallet();
44
72
  const connectedWallets = useConnectedWallets();
45
73
  const setActiveWallet = useSetActiveWallet();
@@ -56,10 +84,14 @@ export function Header({ onLogout }) {
56
84
  const isActiveGlobalAccount = activeWallet?.id.includes("ecosystem");
57
85
  const onLogoutEnhanced = async () => {
58
86
  setLogoutLoading(true);
59
- await logout();
60
- onLogout?.();
61
- setB3ModalOpen(false);
62
- setLogoutLoading(false);
87
+ try {
88
+ await logout();
89
+ onLogout?.();
90
+ }
91
+ finally {
92
+ setB3ModalOpen(false);
93
+ setLogoutLoading(false);
94
+ }
63
95
  };
64
96
  const handleWalletSwitch = (wallet) => {
65
97
  setActiveWallet(wallet);
@@ -1,4 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useB3Config } from "../../../../global-account/react/index.js";
2
3
  import { Tabs, TabsContent, TabsList, TabTrigger } from "../ui/Tabs.js";
3
4
  import { Header } from "./Header.js";
4
5
  import HomeActions from "./HomeActions.js";
@@ -6,5 +7,7 @@ import NFTContent from "./NFTContent.js";
6
7
  import ProfileSection from "./ProfileSection.js";
7
8
  import TokenContent from "./TokenContent.js";
8
9
  export function HomeContent({ showDeposit = false, showSwap = true }) {
9
- return (_jsxs("div", { className: "flex flex-col", children: [_jsx(Header, {}), _jsxs("div", { className: "flex flex-col", children: [_jsx(ProfileSection, {}), _jsx(HomeActions, { showDeposit: showDeposit, showSwap: showSwap }), _jsx("div", { className: "b3-modal-balance-content space-y-2 p-5", children: _jsxs(Tabs, { defaultValue: "balance", children: [_jsxs(TabsList, { className: "b3-modal-balance-tabs-list", children: [_jsx(TabTrigger, { value: "balance", className: "font-neue-montreal-semibold p-0 pr-3", children: "Balance" }), _jsx(TabTrigger, { value: "nfts", className: "font-neue-montreal-semibold p-0 pr-3", children: "NFTs" })] }), _jsx(TabsContent, { value: "balance", className: "px-0 pb-4 pt-2", children: _jsx(TokenContent, {}) }), _jsx(TabsContent, { value: "nfts", className: "px-0 pb-4 pt-2", children: _jsx(NFTContent, {}) })] }) })] })] }));
10
+ const { authStrategy } = useB3Config();
11
+ const isBetterAuth = authStrategy === "better-auth";
12
+ return (_jsxs("div", { className: "flex flex-col", children: [_jsx(Header, {}), _jsxs("div", { className: "flex flex-col", children: [_jsx(ProfileSection, {}), !isBetterAuth && _jsx(HomeActions, { showDeposit: showDeposit, showSwap: showSwap }), !isBetterAuth && (_jsx("div", { className: "b3-modal-balance-content space-y-2 p-5", children: _jsxs(Tabs, { defaultValue: "balance", children: [_jsxs(TabsList, { className: "b3-modal-balance-tabs-list", children: [_jsx(TabTrigger, { value: "balance", className: "font-neue-montreal-semibold p-0 pr-3", children: "Balance" }), _jsx(TabTrigger, { value: "nfts", className: "font-neue-montreal-semibold p-0 pr-3", children: "NFTs" })] }), _jsx(TabsContent, { value: "balance", className: "px-0 pb-4 pt-2", children: _jsx(TokenContent, {}) }), _jsx(TabsContent, { value: "nfts", className: "px-0 pb-4 pt-2", children: _jsx(NFTContent, {}) })] }) }))] })] }));
10
13
  }
@@ -1,12 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { TabsContentPrimitive, TabsPrimitive, useModalStore, } from "../../../../global-account/react/index.js";
2
+ import { TabsContentPrimitive, TabsPrimitive, useB3Config, useModalStore, } from "../../../../global-account/react/index.js";
3
3
  import BottomNavigation from "./BottomNavigation.js";
4
4
  import { HomeContent } from "./HomeContent.js";
5
5
  import SettingsContent from "./SettingsContent.js";
6
6
  export function ManageAccount({ onLogout, onSwap: _onSwap, onDeposit: _onDeposit, chain, partnerId, showSwap, showDeposit, }) {
7
+ const { authStrategy } = useB3Config();
8
+ const isBetterAuth = authStrategy === "better-auth";
7
9
  const contentType = useModalStore(state => state.contentType);
8
10
  const { activeTab = "home", setActiveTab } = contentType;
9
11
  const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
12
+ // Better Auth: single-view layout — no Home/Swap tabs, just settings content
13
+ if (isBetterAuth) {
14
+ return (_jsx("div", { className: "b3-manage-account flex-1", children: _jsx(SettingsContent, { partnerId: partnerId, onLogout: onLogout, chain: chain }) }));
15
+ }
10
16
  return (_jsx("div", { className: "b3-manage-account flex-1", children: _jsxs(TabsPrimitive, { defaultValue: activeTab, onValueChange: value => {
11
17
  const tab = value;
12
18
  if (tab === "swap") {
@@ -1,6 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAccountWallet, useModalStore, useProfile, useSimBalance, useUser, } from "../../../../global-account/react/index.js";
2
+ import { useAccountWallet, useB3Config, useModalStore, useProfile, useSimBalance, useUser, } from "../../../../global-account/react/index.js";
3
3
  import { validateImageUrl } from "../../../../global-account/react/utils/profileDisplay.js";
4
+ import { AVATAR_COLORS } from "../../../../shared/constants/index.js";
4
5
  import { formatUsername } from "../../../../shared/utils/index.js";
5
6
  import { formatDisplayNumber } from "../../../../shared/utils/number.js";
6
7
  import Avatar from "boring-avatars";
@@ -9,8 +10,9 @@ import { useCallback, useEffect, useMemo, useState } from "react";
9
10
  import { useActiveAccount } from "thirdweb/react";
10
11
  import { useFirstEOA } from "../../hooks/useFirstEOA.js";
11
12
  import { IPFSMediaRenderer } from "../IPFSMediaRenderer/IPFSMediaRenderer.js";
12
- const AVATAR_COLORS = ["#3368ef", "#272727", "#6366f1", "#06b6d4", "#eeb0d9", "#ba3fbf", "#ff777b", "#dfbb53"];
13
13
  const ProfileSection = () => {
14
+ const { authStrategy } = useB3Config();
15
+ const isBetterAuth = authStrategy === "better-auth";
14
16
  const account = useActiveAccount();
15
17
  const { address: eoaAddress } = useFirstEOA();
16
18
  const { address: smartWalletAddress } = useAccountWallet();
@@ -45,7 +47,7 @@ const ProfileSection = () => {
45
47
  setImgError(false);
46
48
  }, [avatarSrc]);
47
49
  const currentUsername = user?.username || profile?.displayName || formatUsername(profile?.name || "");
48
- const avatarSeed = eoaAddress || account?.address || smartWalletAddress || currentUsername || "user";
49
- return (_jsx("div", { className: "flex items-center justify-between px-5 py-6", children: _jsxs("div", { className: "global-account-profile flex items-center gap-4", children: [_jsxs("div", { className: "global-account-profile-avatar relative", children: [_jsx("div", { className: "border-b3-line border-1 bg-b3-primary-wash size-14 overflow-hidden rounded-full border", children: avatarSrc && !imgError ? (_jsx(IPFSMediaRenderer, { src: avatarSrc, alt: "Profile Avatar", className: "h-full w-full object-cover", onError: handleImgError })) : (_jsx(Avatar, { name: avatarSeed, variant: "beam", size: 56, colors: AVATAR_COLORS })) }), _jsx("button", { onClick: handleEditAvatar, className: "border-b3-background hover:bg-b3-grey/80 absolute -bottom-1 -right-1 flex size-6 items-center justify-center rounded-full border-4 bg-[#a0a0ab] transition-colors", children: _jsx(Pencil, { size: 10, className: "text-b3-background" }) })] }), _jsxs("div", { className: "global-account-profile-info flex flex-col gap-1", children: [_jsxs("h2", { className: "text-b3-grey font-neue-montreal-semibold flex h-[38px] items-center gap-1 text-xl", children: [_jsx("div", { className: "text-b3-foreground-muted", children: " $" }), _jsx("div", { className: "text-[30px]", children: formatDisplayNumber(totalBalanceUsd, { fractionDigits: 2 }) })] }), _jsx("div", { className: "b3-modal-username font-neue-montreal-semibold text-base leading-none text-[#0B57C2]", children: currentUsername })] })] }) }));
50
+ const avatarSeed = eoaAddress || account?.address || smartWalletAddress || currentUsername || user?.email || "user";
51
+ return (_jsx("div", { className: "flex items-center justify-between px-5 py-6", children: _jsxs("div", { className: "global-account-profile flex items-center gap-4", children: [_jsxs("div", { className: "global-account-profile-avatar relative", children: [_jsx("div", { className: "border-b3-line border-1 bg-b3-primary-wash size-14 overflow-hidden rounded-full border", children: avatarSrc && !imgError ? (_jsx(IPFSMediaRenderer, { src: avatarSrc, alt: "Profile Avatar", className: "h-full w-full object-cover", onError: handleImgError })) : (_jsx(Avatar, { name: avatarSeed, variant: "beam", size: 56, colors: AVATAR_COLORS })) }), _jsx("button", { onClick: handleEditAvatar, className: "border-b3-background hover:bg-b3-grey/80 absolute -bottom-1 -right-1 flex size-6 items-center justify-center rounded-full border-4 bg-[#a0a0ab] transition-colors", children: _jsx(Pencil, { size: 10, className: "text-b3-background" }) })] }), _jsxs("div", { className: "global-account-profile-info flex flex-col gap-1", children: [!isBetterAuth && (_jsxs("h2", { className: "text-b3-grey font-neue-montreal-semibold flex h-[38px] items-center gap-1 text-xl", children: [_jsx("div", { className: "text-b3-foreground-muted", children: " $" }), _jsx("div", { className: "text-[30px]", children: formatDisplayNumber(totalBalanceUsd, { fractionDigits: 2 }) })] })), _jsx("div", { className: "b3-modal-username font-neue-montreal-semibold text-base leading-none text-[#0B57C2]", children: currentUsername }), isBetterAuth && user?.email && (_jsx("div", { className: "text-b3-foreground-muted font-neue-montreal-medium text-sm", children: user.email }))] })] }) }));
50
52
  };
51
53
  export default ProfileSection;
@@ -1,8 +1,8 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuthentication, useModalStore } from "../../../../global-account/react/index.js";
2
+ import { useAuthentication, useB3Config, useModalStore } from "../../../../global-account/react/index.js";
3
3
  import { client } from "../../../../shared/utils/thirdweb.js";
4
4
  import { getSessionDurationDays, SESSION_DURATION_LABELS } from "../../../../shared/utils/session-duration.js";
5
- import { Loader2 } from "lucide-react";
5
+ import { Bell, Clock, Link, Loader2 } from "lucide-react";
6
6
  import { useState } from "react";
7
7
  import { useProfiles } from "thirdweb/react";
8
8
  import SignOutIcon from "../icons/SignOutIcon.js";
@@ -10,6 +10,8 @@ import ModalHeader from "../ModalHeader/ModalHeader.js";
10
10
  import SettingsMenuItem from "./SettingsMenuItem.js";
11
11
  import SettingsProfileCard from "./SettingsProfileCard.js";
12
12
  const SettingsContent = ({ partnerId, onLogout, chain, }) => {
13
+ const { authStrategy } = useB3Config();
14
+ const isBetterAuth = authStrategy === "better-auth";
13
15
  const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
14
16
  const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
15
17
  const { logout, user } = useAuthentication(partnerId);
@@ -45,7 +47,7 @@ const SettingsContent = ({ partnerId, onLogout, chain, }) => {
45
47
  setB3ModalOpen(false);
46
48
  setLogoutLoading(false);
47
49
  };
48
- return (_jsxs("div", { className: "flex h-[470px] flex-col", children: [_jsx(ModalHeader, { showBackButton: false, showCloseButton: false, title: "Settings" }), _jsx("div", { className: "p-5", children: _jsx("div", { className: "b3-modal-settings-profile-card dark:border-b3-line dark:bg-b3-background flex items-center rounded-xl border border-[#e4e4e7] bg-[#f4f4f5] p-4", children: _jsx(SettingsProfileCard, {}) }) }), _jsxs("div", { className: "space-y-3 px-5", children: [_jsx(SettingsMenuItem, { icon: _jsx("svg", { width: "40", height: "40", viewBox: "0 0 40 40", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M0 12C0 5.37258 5.37258 0 12 0H28C34.6274 0 40 5.37258 40 12V28C40 34.6274 34.6274 40 28 40H12C5.37258 40 0 34.6274 0 28V12Z", fill: "#F4F4F5" }) }), title: "Linked Accounts", subtitle: `${profiles.length} connected account${profiles.length > 1 ? "s" : ""}`, onClick: () => handleNavigate("linkAccount") }), _jsx(SettingsMenuItem, { icon: _jsx("svg", { width: "40", height: "40", viewBox: "0 0 40 40", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M0 12C0 5.37258 5.37258 0 12 0H28C34.6274 0 40 5.37258 40 12V28C40 34.6274 34.6274 40 28 40H12C5.37258 40 0 34.6274 0 28V12Z", fill: "#F4F4F5" }) }), title: "Notifications", subtitle: "Manage your notifications", onClick: () => handleNavigate("notifications") }), _jsx(SettingsMenuItem, { icon: _jsx("svg", { width: "40", height: "40", viewBox: "0 0 40 40", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M0 12C0 5.37258 5.37258 0 12 0H28C34.6274 0 40 5.37258 40 12V28C40 34.6274 34.6274 40 28 40H12C5.37258 40 0 34.6274 0 28V12Z", fill: "#F4F4F5" }) }), title: "Stay signed in", subtitle: SESSION_DURATION_LABELS[sessionDays] ?? `${sessionDays} days`, onClick: () => handleNavigate("sessionDuration") })] }), _jsx("div", { className: "mt-auto px-5 pb-5", children: _jsxs("button", { type: "button", className: "b3-modal-sign-out-button border-b3-line hover:bg-b3-line bg-b3-background dark:bg-b3-background dark:border-b3-line dark:hover:bg-b3-line/80 flex w-full items-center justify-center gap-1.5 rounded-xl border border-solid p-3 transition-colors", onClick: onLogoutEnhanced, disabled: logoutLoading, style: {
50
+ return (_jsxs("div", { className: "flex h-[470px] flex-col", children: [!isBetterAuth && _jsx(ModalHeader, { showBackButton: false, showCloseButton: false, title: "Settings" }), _jsx("div", { className: "p-5", children: _jsx("div", { className: "b3-modal-settings-profile-card dark:border-b3-line dark:bg-b3-background flex items-center rounded-xl border border-[#e4e4e7] bg-[#f4f4f5] p-4", children: _jsx(SettingsProfileCard, {}) }) }), _jsxs("div", { className: "space-y-3 px-5", children: [!isBetterAuth && (_jsx(SettingsMenuItem, { icon: _jsx(Link, { size: 18, className: "text-[#51525c]" }), title: "Linked Accounts", subtitle: `${profiles.length} connected account${profiles.length > 1 ? "s" : ""}`, onClick: () => handleNavigate("linkAccount") })), _jsx(SettingsMenuItem, { icon: _jsx(Bell, { size: 18, className: "text-[#51525c]" }), title: "Notifications", subtitle: "Manage your notifications", onClick: () => handleNavigate("notifications") }), _jsx(SettingsMenuItem, { icon: _jsx(Clock, { size: 18, className: "text-[#51525c]" }), title: "Stay signed in", subtitle: SESSION_DURATION_LABELS[sessionDays] ?? `${sessionDays} days`, onClick: () => handleNavigate("sessionDuration") })] }), _jsx("div", { className: "mt-auto px-5 pb-5", children: _jsxs("button", { type: "button", className: "b3-modal-sign-out-button border-b3-line hover:bg-b3-line bg-b3-background dark:bg-b3-background dark:border-b3-line dark:hover:bg-b3-line/80 flex w-full items-center justify-center gap-1.5 rounded-xl border border-solid p-3 transition-colors", onClick: onLogoutEnhanced, disabled: logoutLoading, style: {
49
51
  boxShadow: "inset 0px 0px 0px 1px rgba(10,13,18,0.18), inset 0px -2px 0px 0px rgba(10,13,18,0.05)",
50
52
  }, children: [logoutLoading ? (_jsx(Loader2, { className: "text-b3-grey animate-spin", size: 20 })) : (_jsx(SignOutIcon, { size: 20, className: "text-b3-grey", color: "currentColor" })), _jsx("p", { className: "text-b3-grey dark:text-b3-foreground-muted font-neue-montreal-semibold text-base", children: "Sign out" })] }) })] }));
51
53
  };
@@ -16,7 +16,8 @@ const SettingsProfileCard = () => {
16
16
  address: eoaAddress || account?.address,
17
17
  fresh: true,
18
18
  });
19
- const { partnerId } = useB3Config();
19
+ const { partnerId, authStrategy } = useB3Config();
20
+ const isBetterAuth = authStrategy === "better-auth";
20
21
  const { user, setUser } = useAuthentication(partnerId);
21
22
  const setB3ModalOpen = useModalStore(state => state.setB3ModalOpen);
22
23
  const setB3ModalContentType = useModalStore(state => state.setB3ModalContentType);
@@ -66,19 +67,29 @@ const SettingsProfileCard = () => {
66
67
  }
67
68
  setIsSaving(true);
68
69
  try {
69
- const sanitizedUsername = ens_normalize(editedUsername.trim());
70
- const b3Username = `${sanitizedUsername}.b3.fun`;
71
- const usernameSignMessage = `Register "${b3Username}"`;
72
- const usernameSignature = await account?.signMessage({ message: usernameSignMessage });
73
- if (!usernameSignature) {
74
- throw new Error("Failed to sign username registration message");
70
+ let updatedUser;
71
+ if (isBetterAuth) {
72
+ // Better Auth: register username without wallet signing (DB-only, no ENS)
73
+ // Skip ens_normalize it rejects underscores/mixed-case that are valid non-ENS usernames
74
+ const sanitizedUsername = editedUsername.trim().toLowerCase();
75
+ // Type assertion needed: b3-mono now accepts message/hash as optional for Better Auth users
76
+ updatedUser = (await app
77
+ .service("users")
78
+ .registerUsername({ username: sanitizedUsername }, {}));
79
+ }
80
+ else {
81
+ // Thirdweb: register username with wallet signature + on-chain ENS
82
+ const sanitizedUsername = ens_normalize(editedUsername.trim());
83
+ const b3Username = `${sanitizedUsername}.b3.fun`;
84
+ const usernameSignMessage = `Register "${b3Username}"`;
85
+ const usernameSignature = await account?.signMessage({ message: usernameSignMessage });
86
+ if (!usernameSignature) {
87
+ throw new Error("Failed to sign username registration message");
88
+ }
89
+ updatedUser = (await app
90
+ .service("users")
91
+ .registerUsername({ username: sanitizedUsername, message: usernameSignMessage, hash: usernameSignature }, {}));
75
92
  }
76
- console.log("@@usernameSignature", usernameSignature);
77
- // Register username with ENS
78
- // Note: Type assertion needed until @b3dotfun/b3-api package is updated with RegisterUsername type
79
- const updatedUser = (await app
80
- .service("users")
81
- .registerUsername({ username: sanitizedUsername, message: usernameSignMessage, hash: usernameSignature }, {}));
82
93
  // Update user state - registerUsername returns an array with single user
83
94
  setUser(Array.isArray(updatedUser) ? updatedUser[0] : updatedUser);
84
95
  // Refresh profile to get updated data
@@ -107,6 +118,6 @@ const SettingsProfileCard = () => {
107
118
  /* Edit mode - inline input */
108
119
  _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { ref: inputRef, type: "text", value: editedUsername, onChange: e => setEditedUsername(e.target.value), onKeyDown: handleKeyDown, disabled: isSaving, className: "border-b3-line bg-b3-background text-b3-grey placeholder:text-b3-foreground-muted font-neue-montreal-medium focus:border-b3-primary-blue text-md w-full rounded-md border px-2 py-1 leading-none transition-colors focus:outline-none disabled:opacity-50", placeholder: "Enter username" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: handleSaveUsername, disabled: isSaving, className: "text-b3-primary-blue hover:text-b3-primary-blue/80 flex items-center justify-center rounded-md p-1 transition-colors disabled:opacity-50", "aria-label": "Save username", children: isSaving ? _jsx(Loader2, { size: 18, className: "animate-spin" }) : _jsx(Check, { size: 18, strokeWidth: 2.5 }) }), _jsx("button", { onClick: handleCancelEdit, disabled: isSaving, className: "text-b3-foreground-muted hover:text-b3-grey flex items-center justify-center rounded-md p-1 transition-colors disabled:opacity-50", "aria-label": "Cancel editing", children: _jsx(X, { size: 18, strokeWidth: 2.5 }) })] })] })) : (
109
120
  /* Display mode */
110
- _jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx("p", { className: "b3-modal-username font-neue-montreal-semibold text-lg leading-none text-[#0B57C2]", children: currentUsername }) }), _jsx("button", { onClick: handleEditUsername, className: "flex items-center justify-center gap-1 text-left transition-opacity hover:opacity-80", children: _jsx("p", { className: "font-inter text-sm font-semibold leading-5 text-[#51525C] dark:text-white", children: "Edit Username" }) })] })) })] }));
121
+ _jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center gap-1", children: _jsx("p", { className: "b3-modal-username font-neue-montreal-semibold text-lg leading-none text-[#0B57C2]", children: currentUsername || user?.email }) }), _jsx("button", { onClick: handleEditUsername, className: "flex items-center justify-center gap-1 text-left transition-opacity hover:opacity-80", children: _jsx("p", { className: "font-inter text-sm font-semibold leading-5 text-[#51525C] dark:text-white", children: "Edit Username" }) })] })) })] }));
111
122
  };
112
123
  export default SettingsProfileCard;
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Button, Input } from "../../../../global-account/react/index.js";
2
+ import { Button } from "../../../../global-account/react/index.js";
3
3
  import { debugB3React } from "../../../../shared/utils/debug.js";
4
4
  import { useState } from "react";
5
5
  import { useBetterAuth } from "../../hooks/useBetterAuth.js";
6
+ import { PasswordInput } from "./components/PasswordInput.js";
6
7
  const debug = debugB3React("BetterAuthResetPassword");
7
8
  /**
8
9
  * Standalone reset password form. Render this on your reset password page.
@@ -57,8 +58,8 @@ export function BetterAuthResetPassword({ token, onSuccess, onError, className }
57
58
  if (!token) {
58
59
  return (_jsx("div", { className: `w-full max-w-[400px] px-6 text-center ${className || ""}`, children: _jsx("p", { className: "text-sm text-red-500", children: "Invalid or missing reset token." }) }));
59
60
  }
60
- return (_jsxs("div", { className: `w-full max-w-[400px] px-6 ${className || ""}`, children: [_jsxs("div", { className: "mb-10 text-center", children: [_jsx("h1", { className: "text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: success ? "Password reset" : "Set new password" }), _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 ? (_jsx("div", { className: "space-y-4 text-center", children: _jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100", children: _jsx("svg", { className: "h-6 w-6 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }) })) : (_jsxs("div", { className: "space-y-5", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "New password" }), _jsx(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]" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Confirm password" }), _jsx(Input, { type: "password", placeholder: "Repeat your password", value: confirmPassword, onChange: e => setConfirmPassword(e.target.value), disabled: isLoading, onKeyDown: e => {
61
+ return (_jsxs("div", { className: `w-full max-w-[400px] px-6 ${className || ""}`, children: [_jsxs("div", { className: "mb-10 text-center", children: [_jsx("h1", { className: "text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100", children: success ? "Password reset" : "Set new password" }), _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 ? (_jsx("div", { className: "space-y-4 text-center", children: _jsx("div", { className: "mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100", children: _jsx("svg", { className: "h-6 w-6 text-green-600", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" }) }) }) })) : (_jsxs("div", { className: "space-y-5", children: [_jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "New password" }), _jsx(PasswordInput, { placeholder: "At least 8 characters", value: password, onChange: e => setPassword(e.target.value), disabled: isLoading, className: "h-11 px-4 pr-11 text-[15px]" })] }), _jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Confirm password" }), _jsx(PasswordInput, { placeholder: "Repeat your password", value: confirmPassword, onChange: e => setConfirmPassword(e.target.value), disabled: isLoading, onKeyDown: e => {
61
62
  if (e.key === "Enter")
62
63
  handleSubmit();
63
- }, className: "h-11 px-4 text-[15px]" })] }), error && _jsx("p", { className: "text-sm text-red-500", children: error }), _jsx(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" })] }))] }));
64
+ }, className: "h-11 px-4 pr-11 text-[15px]" })] }), error && _jsx("p", { className: "text-sm text-red-500", children: error }), _jsx(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" })] }))] }));
64
65
  }
@@ -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;
@@ -1,8 +1,9 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
- import { Button, Input, useAuthStore } from "../../../../global-account/react/index.js";
2
+ import { Button, Input, Loading, useAuthStore } from "../../../../global-account/react/index.js";
3
3
  import { debugB3React } from "../../../../shared/utils/debug.js";
4
4
  import { useState } from "react";
5
5
  import { EmailVerificationRequiredError, useBetterAuth, } from "../../hooks/useBetterAuth.js";
6
+ import { PasswordInput } from "./components/PasswordInput.js";
6
7
  import { strategyIcons, strategyLabels } from "./utils/signInUtils.js";
7
8
  const debug = debugB3React("BetterAuthSignIn");
8
9
  const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -27,9 +28,11 @@ const DEFAULT_SOCIAL_PROVIDERS = [
27
28
  * />
28
29
  * ```
29
30
  */
30
- 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, }) {
31
32
  const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = useBetterAuth();
32
33
  const isAuthenticated = useAuthStore(state => state.isAuthenticated);
34
+ const isAuthenticating = useAuthStore(state => state.isAuthenticating);
35
+ const hasStartedConnecting = useAuthStore(state => state.hasStartedConnecting);
33
36
  const [mode, setMode] = useState("sign-in");
34
37
  const [email, setEmail] = useState("");
35
38
  const [password, setPassword] = useState("");
@@ -42,7 +45,9 @@ export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to
42
45
  const resolvedTitle = title ||
43
46
  (mode === "forgot-password" ? "Reset password" : mode === "sign-in" ? "Welcome back" : "Create an account");
44
47
  const resolvedSubtitle = mode === "forgot-password"
45
- ? "Enter your email and we'll send you a reset link"
48
+ ? resetEmailSent
49
+ ? "We've sent a password reset link to your email"
50
+ : "Enter your email and we'll send you a reset link"
46
51
  : subtitle || "Enter your credentials to access your account";
47
52
  const handleForgotPassword = async () => {
48
53
  const normalizedEmail = email.trim().toLowerCase();
@@ -67,6 +72,11 @@ export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to
67
72
  const providers = socialProviders
68
73
  .map(id => DEFAULT_SOCIAL_PROVIDERS.find(p => p.id === id))
69
74
  .filter((p) => !!p);
75
+ // Show loading during session restore (before any user interaction) to prevent
76
+ // the login form from flashing briefly after OAuth redirect.
77
+ if (isAuthenticating && !hasStartedConnecting) {
78
+ return (_jsx("div", { className: `flex w-full max-w-[400px] items-center justify-center px-6 py-20 ${className || ""}`, children: _jsx(Loading, { variant: "primary", size: "lg" }) }));
79
+ }
70
80
  if (isAuthenticated) {
71
81
  return null;
72
82
  }
@@ -88,7 +98,7 @@ export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to
88
98
  setIsLoading(true);
89
99
  setError(null);
90
100
  if (mode === "sign-up") {
91
- await signUpWithEmail(normalizedEmail, password, name.trim());
101
+ await signUpWithEmail(normalizedEmail, password, name.trim(), verifyEmailRedirectTo);
92
102
  }
93
103
  else {
94
104
  await signInWithEmail(normalizedEmail, password);
@@ -145,10 +155,10 @@ export function BetterAuthSignIn({ title, subtitle = "Enter your credentials to
145
155
  }, className: "font-medium text-blue-600 hover:text-blue-500 dark:text-blue-400", children: "Back to sign in" }) })] })), showEmail && mode !== "forgot-password" && (_jsxs("div", { className: "space-y-5", children: [mode === "sign-up" && (_jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Name" }), _jsx(Input, { type: "text", placeholder: "Your name", value: name, onChange: e => setName(e.target.value), disabled: isLoading, className: "h-11 px-4 text-[15px]" })] })), _jsxs("div", { children: [_jsx("label", { className: "mb-2 block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Email" }), _jsx(Input, { type: "email", placeholder: "name@company.com", value: email, onChange: e => setEmail(e.target.value), disabled: isLoading, className: "h-11 px-4 text-[15px]" })] }), _jsxs("div", { children: [_jsxs("div", { className: "mb-2 flex items-center justify-between", children: [_jsx("label", { className: "block text-xs font-medium uppercase tracking-wide text-gray-700 dark:text-gray-300", children: "Password" }), mode === "sign-in" && (_jsx("button", { type: "button", onClick: () => {
146
156
  setMode("forgot-password");
147
157
  setError(null);
148
- }, className: "text-xs font-medium text-blue-600 hover:text-blue-500 dark:text-blue-400", children: "Forgot password?" }))] }), _jsx(Input, { type: "password", placeholder: "Password", value: password, onChange: e => setPassword(e.target.value), disabled: isLoading, onKeyDown: e => {
158
+ }, className: "text-xs font-medium text-blue-600 hover:text-blue-500 dark:text-blue-400", children: "Forgot password?" }))] }), _jsx(PasswordInput, { value: password, onChange: e => setPassword(e.target.value), disabled: isLoading, onKeyDown: e => {
149
159
  if (e.key === "Enter")
150
160
  handleEmailSubmit();
151
- }, className: "h-11 px-4 text-[15px]" })] }), error && _jsx("p", { className: "text-sm text-red-500", children: error }), _jsx(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" && (_jsxs(_Fragment, { children: [showEmail && (_jsxs("div", { className: "my-8 flex items-center gap-4", children: [_jsx("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" }), _jsx("span", { className: "text-xs text-gray-400", children: "Or continue with" }), _jsx("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" })] })), _jsx("div", { className: "space-y-4", children: providers.map(provider => {
161
+ }, className: "h-11 px-4 pr-11 text-[15px]" }, mode)] }), error && _jsx("p", { className: "text-sm text-red-500", children: error }), _jsx(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" && (_jsxs(_Fragment, { children: [showEmail && (_jsxs("div", { className: "my-8 flex items-center gap-4", children: [_jsx("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" }), _jsx("span", { className: "text-xs text-gray-400", children: "Or continue with" }), _jsx("div", { className: "h-px flex-1 bg-gray-200 dark:bg-gray-700" })] })), _jsx("div", { className: "space-y-4", children: providers.map(provider => {
152
162
  const icon = strategyIcons[provider.id];
153
163
  const label = strategyLabels[provider.id] || provider.label;
154
164
  const isProviderLoading = loadingProvider === provider.id;