@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.
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -0
- package/dist/cjs/anyspend/react/components/AnySpend.js +12 -4
- package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +5 -1
- package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +2 -2
- package/dist/cjs/anyspend/react/components/AnySpendCustom.d.ts +2 -0
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +7 -3
- package/dist/cjs/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/AnySpendDeposit.js +3 -3
- package/dist/cjs/anyspend/react/components/AnySpendNFT.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/AnySpendNFT.js +2 -2
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpside.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/AnySpendStakeUpside.js +2 -2
- package/dist/cjs/anyspend/react/components/checkout/AnySpendCheckout.js +6 -5
- package/dist/cjs/anyspend/react/components/checkout/CartItemRow.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/checkout/CartSummary.d.ts +6 -4
- package/dist/cjs/anyspend/react/components/checkout/CartSummary.js +13 -11
- package/dist/cjs/anyspend/react/components/checkout/CheckoutCartPanel.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/checkout/CheckoutCartPanel.js +5 -4
- package/dist/cjs/anyspend/react/components/checkout/CheckoutFormPanel.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/checkout/CheckoutFormPanel.js +2 -2
- package/dist/cjs/anyspend/react/components/checkout/DiscountCodeInput.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/checkout/DiscountCodeInput.js +3 -6
- package/dist/cjs/anyspend/react/components/checkout/PriceSkeleton.d.ts +5 -0
- package/dist/cjs/anyspend/react/components/checkout/PriceSkeleton.js +9 -0
- package/dist/cjs/anyspend/react/components/checkout/ShippingSelector.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/checkout/ShippingSelector.js +3 -2
- package/dist/cjs/global-account/react/components/AvatarEditor/AvatarEditor.js +3 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +5 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3ConfigProvider.js +2 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +17 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +3 -2
- package/dist/cjs/global-account/react/components/B3Provider/BetterAuthClientProvider.d.ts +17 -0
- package/dist/cjs/global-account/react/components/B3Provider/BetterAuthClientProvider.js +31 -0
- package/dist/cjs/global-account/react/components/B3Provider/BetterAuthProvider.js +6 -5
- package/dist/cjs/global-account/react/components/ManageAccount/BottomNavigation.js +4 -2
- package/dist/cjs/global-account/react/components/ManageAccount/Header.js +36 -4
- package/dist/cjs/global-account/react/components/ManageAccount/HomeContent.js +4 -1
- package/dist/cjs/global-account/react/components/ManageAccount/ManageAccount.js +6 -0
- package/dist/cjs/global-account/react/components/ManageAccount/ProfileSection.js +5 -3
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsContent.js +3 -1
- package/dist/cjs/global-account/react/components/ManageAccount/SettingsProfileCard.js +25 -14
- package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthResetPassword.js +3 -2
- package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +15 -5
- package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.js +85 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/SignIn.js +14 -4
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -2
- package/dist/cjs/global-account/react/components/SignInWithB3/components/PasswordInput.d.ts +10 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/components/PasswordInput.js +10 -0
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
- package/dist/cjs/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +8 -5
- package/dist/cjs/global-account/react/components/UserAvatar/UserAvatar.d.ts +18 -0
- package/dist/cjs/global-account/react/components/UserAvatar/UserAvatar.js +27 -0
- package/dist/cjs/global-account/react/components/index.d.ts +3 -0
- package/dist/cjs/global-account/react/components/index.js +10 -3
- package/dist/cjs/global-account/react/hooks/useBetterAuth.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useBetterAuth.js +19 -17
- package/dist/cjs/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/cjs/shared/constants/index.d.ts +1 -0
- package/dist/cjs/shared/constants/index.js +2 -1
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -0
- package/dist/esm/anyspend/react/components/AnySpend.js +12 -4
- package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +5 -1
- package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +2 -2
- package/dist/esm/anyspend/react/components/AnySpendCustom.d.ts +2 -0
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +7 -3
- package/dist/esm/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
- package/dist/esm/anyspend/react/components/AnySpendDeposit.js +3 -3
- package/dist/esm/anyspend/react/components/AnySpendNFT.d.ts +3 -1
- package/dist/esm/anyspend/react/components/AnySpendNFT.js +2 -2
- package/dist/esm/anyspend/react/components/AnySpendStakeUpside.d.ts +3 -1
- package/dist/esm/anyspend/react/components/AnySpendStakeUpside.js +2 -2
- package/dist/esm/anyspend/react/components/checkout/AnySpendCheckout.js +6 -5
- package/dist/esm/anyspend/react/components/checkout/CartItemRow.d.ts +2 -1
- package/dist/esm/anyspend/react/components/checkout/CartSummary.d.ts +6 -4
- package/dist/esm/anyspend/react/components/checkout/CartSummary.js +13 -11
- package/dist/esm/anyspend/react/components/checkout/CheckoutCartPanel.d.ts +3 -1
- package/dist/esm/anyspend/react/components/checkout/CheckoutCartPanel.js +5 -4
- package/dist/esm/anyspend/react/components/checkout/CheckoutFormPanel.d.ts +3 -1
- package/dist/esm/anyspend/react/components/checkout/CheckoutFormPanel.js +2 -2
- package/dist/esm/anyspend/react/components/checkout/DiscountCodeInput.d.ts +3 -1
- package/dist/esm/anyspend/react/components/checkout/DiscountCodeInput.js +3 -6
- package/dist/esm/anyspend/react/components/checkout/PriceSkeleton.d.ts +5 -0
- package/dist/esm/anyspend/react/components/checkout/PriceSkeleton.js +6 -0
- package/dist/esm/anyspend/react/components/checkout/ShippingSelector.d.ts +3 -1
- package/dist/esm/anyspend/react/components/checkout/ShippingSelector.js +3 -2
- package/dist/esm/global-account/react/components/AvatarEditor/AvatarEditor.js +3 -1
- package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +5 -1
- package/dist/esm/global-account/react/components/B3Provider/B3ConfigProvider.js +2 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +17 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +3 -2
- package/dist/esm/global-account/react/components/B3Provider/BetterAuthClientProvider.d.ts +17 -0
- package/dist/esm/global-account/react/components/B3Provider/BetterAuthClientProvider.js +27 -0
- package/dist/esm/global-account/react/components/B3Provider/BetterAuthProvider.js +4 -3
- package/dist/esm/global-account/react/components/ManageAccount/BottomNavigation.js +5 -3
- package/dist/esm/global-account/react/components/ManageAccount/Header.js +37 -5
- package/dist/esm/global-account/react/components/ManageAccount/HomeContent.js +4 -1
- package/dist/esm/global-account/react/components/ManageAccount/ManageAccount.js +7 -1
- package/dist/esm/global-account/react/components/ManageAccount/ProfileSection.js +6 -4
- package/dist/esm/global-account/react/components/ManageAccount/SettingsContent.js +5 -3
- package/dist/esm/global-account/react/components/ManageAccount/SettingsProfileCard.js +25 -14
- package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthResetPassword.js +4 -3
- package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
- package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthSignIn.js +16 -6
- package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
- package/dist/esm/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.js +82 -0
- package/dist/esm/global-account/react/components/SignInWithB3/SignIn.js +15 -5
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
- package/dist/esm/global-account/react/components/SignInWithB3/SignInWithB3Flow.js +2 -2
- package/dist/esm/global-account/react/components/SignInWithB3/components/PasswordInput.d.ts +10 -0
- package/dist/esm/global-account/react/components/SignInWithB3/components/PasswordInput.js +7 -0
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
- package/dist/esm/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.js +8 -5
- package/dist/esm/global-account/react/components/UserAvatar/UserAvatar.d.ts +18 -0
- package/dist/esm/global-account/react/components/UserAvatar/UserAvatar.js +21 -0
- package/dist/esm/global-account/react/components/index.d.ts +3 -0
- package/dist/esm/global-account/react/components/index.js +4 -0
- package/dist/esm/global-account/react/hooks/useBetterAuth.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useBetterAuth.js +12 -10
- package/dist/esm/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/esm/shared/constants/index.d.ts +1 -0
- package/dist/esm/shared/constants/index.js +1 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -0
- package/dist/types/anyspend/react/components/AnySpendCollectorClubPurchase.d.ts +5 -1
- package/dist/types/anyspend/react/components/AnySpendCustom.d.ts +2 -0
- package/dist/types/anyspend/react/components/AnySpendDeposit.d.ts +3 -1
- package/dist/types/anyspend/react/components/AnySpendNFT.d.ts +3 -1
- package/dist/types/anyspend/react/components/AnySpendStakeUpside.d.ts +3 -1
- package/dist/types/anyspend/react/components/checkout/CartItemRow.d.ts +2 -1
- package/dist/types/anyspend/react/components/checkout/CartSummary.d.ts +6 -4
- package/dist/types/anyspend/react/components/checkout/CheckoutCartPanel.d.ts +3 -1
- package/dist/types/anyspend/react/components/checkout/CheckoutFormPanel.d.ts +3 -1
- package/dist/types/anyspend/react/components/checkout/DiscountCodeInput.d.ts +3 -1
- package/dist/types/anyspend/react/components/checkout/PriceSkeleton.d.ts +5 -0
- package/dist/types/anyspend/react/components/checkout/ShippingSelector.d.ts +3 -1
- package/dist/types/global-account/react/components/B3Provider/B3ConfigProvider.d.ts +5 -1
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +17 -1
- package/dist/types/global-account/react/components/B3Provider/BetterAuthClientProvider.d.ts +17 -0
- package/dist/types/global-account/react/components/SignInWithB3/BetterAuthSignIn.d.ts +6 -1
- package/dist/types/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.d.ts +37 -0
- package/dist/types/global-account/react/components/SignInWithB3/SignInWithB3Flow.d.ts +1 -1
- package/dist/types/global-account/react/components/SignInWithB3/components/PasswordInput.d.ts +10 -0
- package/dist/types/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.d.ts +3 -1
- package/dist/types/global-account/react/components/UserAvatar/UserAvatar.d.ts +18 -0
- package/dist/types/global-account/react/components/index.d.ts +3 -0
- package/dist/types/global-account/react/hooks/useBetterAuth.d.ts +1 -1
- package/dist/types/global-account/react/stores/useModalStore.d.ts +4 -0
- package/dist/types/shared/constants/index.d.ts +1 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +24 -12
- package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +6 -0
- package/src/anyspend/react/components/AnySpendCustom.tsx +12 -2
- package/src/anyspend/react/components/AnySpendDeposit.tsx +38 -31
- package/src/anyspend/react/components/AnySpendNFT.tsx +4 -0
- package/src/anyspend/react/components/AnySpendStakeUpside.tsx +4 -0
- package/src/anyspend/react/components/checkout/AnySpendCheckout.tsx +10 -4
- package/src/anyspend/react/components/checkout/CartItemRow.tsx +2 -1
- package/src/anyspend/react/components/checkout/CartSummary.tsx +24 -20
- package/src/anyspend/react/components/checkout/CheckoutCartPanel.tsx +12 -3
- package/src/anyspend/react/components/checkout/CheckoutFormPanel.tsx +5 -0
- package/src/anyspend/react/components/checkout/DiscountCodeInput.tsx +15 -5
- package/src/anyspend/react/components/checkout/PriceSkeleton.tsx +19 -0
- package/src/anyspend/react/components/checkout/ShippingSelector.tsx +5 -1
- package/src/global-account/react/components/AvatarEditor/AvatarEditor.tsx +3 -1
- package/src/global-account/react/components/B3Provider/B3ConfigProvider.tsx +6 -0
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +36 -15
- package/src/global-account/react/components/B3Provider/BetterAuthClientProvider.tsx +40 -0
- package/src/global-account/react/components/B3Provider/BetterAuthProvider.tsx +4 -3
- package/src/global-account/react/components/ManageAccount/BottomNavigation.tsx +18 -14
- package/src/global-account/react/components/ManageAccount/Header.tsx +71 -4
- package/src/global-account/react/components/ManageAccount/HomeContent.tsx +25 -19
- package/src/global-account/react/components/ManageAccount/ManageAccount.tsx +13 -0
- package/src/global-account/react/components/ManageAccount/ProfileSection.tsx +14 -7
- package/src/global-account/react/components/ManageAccount/SettingsContent.tsx +15 -32
- package/src/global-account/react/components/ManageAccount/SettingsProfileCard.tsx +29 -20
- package/src/global-account/react/components/SignInWithB3/BetterAuthResetPassword.tsx +6 -7
- package/src/global-account/react/components/SignInWithB3/BetterAuthSignIn.tsx +27 -7
- package/src/global-account/react/components/SignInWithB3/BetterAuthVerifyEmail.tsx +155 -0
- package/src/global-account/react/components/SignInWithB3/SignIn.tsx +42 -13
- package/src/global-account/react/components/SignInWithB3/SignInWithB3Flow.tsx +8 -1
- package/src/global-account/react/components/SignInWithB3/components/PasswordInput.tsx +62 -0
- package/src/global-account/react/components/SignInWithB3/steps/LoginStepBetterAuth.tsx +13 -6
- package/src/global-account/react/components/UserAvatar/UserAvatar.tsx +45 -0
- package/src/global-account/react/components/index.ts +9 -0
- package/src/global-account/react/hooks/useBetterAuth.ts +12 -10
- package/src/global-account/react/stores/useModalStore.ts +4 -0
- package/src/shared/constants/index.ts +2 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { Button } from "@b3dotfun/sdk/global-account/react";
|
|
2
|
+
import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
|
|
3
|
+
|
|
4
|
+
const debug = debugB3React("BetterAuthVerifyEmail");
|
|
5
|
+
|
|
6
|
+
export type BetterAuthVerifyEmailState = "success" | "expired" | "invalid" | "already-verified" | "error";
|
|
7
|
+
|
|
8
|
+
export interface BetterAuthVerifyEmailProps {
|
|
9
|
+
/**
|
|
10
|
+
* Error code from the callback URL's `?error=` query param. Pass `null` /
|
|
11
|
+
* `undefined` when the user landed here cleanly (successful verification).
|
|
12
|
+
* Better Auth appends this param when server-side verification fails.
|
|
13
|
+
*/
|
|
14
|
+
errorCode?: string | null;
|
|
15
|
+
/** Called when the user clicks the "Go to sign in" button. */
|
|
16
|
+
onGoToSignIn?: () => void;
|
|
17
|
+
/** Fallback href used when `onGoToSignIn` is not provided. Defaults to "/login". */
|
|
18
|
+
signInHref?: string;
|
|
19
|
+
/** Optional override for the success headline. */
|
|
20
|
+
successTitle?: string;
|
|
21
|
+
/** Optional override for the success body text. */
|
|
22
|
+
successMessage?: string;
|
|
23
|
+
/** Optional class name for the root container. */
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function classifyError(code: string | null | undefined): BetterAuthVerifyEmailState {
|
|
28
|
+
if (!code) return "success";
|
|
29
|
+
const normalized = code.toLowerCase();
|
|
30
|
+
|
|
31
|
+
// Exact matches for Better Auth's documented verification error codes.
|
|
32
|
+
if (normalized === "expired_token") return "expired";
|
|
33
|
+
if (normalized === "invalid_token") return "invalid";
|
|
34
|
+
if (normalized === "already_verified" || normalized === "email_already_verified") return "already-verified";
|
|
35
|
+
|
|
36
|
+
// Loose fallbacks for close variants. Order matters — check "already" before
|
|
37
|
+
// "verified" so `email_already_verified` maps to already-verified, not invalid.
|
|
38
|
+
if (normalized.includes("expired")) return "expired";
|
|
39
|
+
if (normalized.includes("already")) return "already-verified";
|
|
40
|
+
if (normalized.includes("invalid")) return "invalid";
|
|
41
|
+
return "error";
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const COPY: Record<BetterAuthVerifyEmailState, { title: string; message: string }> = {
|
|
45
|
+
success: {
|
|
46
|
+
title: "Email verified",
|
|
47
|
+
message: "Your email is confirmed. You can now sign in to your account.",
|
|
48
|
+
},
|
|
49
|
+
expired: {
|
|
50
|
+
title: "Link expired",
|
|
51
|
+
message: "This verification link has expired. Request a new one from the sign-in page.",
|
|
52
|
+
},
|
|
53
|
+
invalid: {
|
|
54
|
+
title: "Invalid link",
|
|
55
|
+
message: "This verification link is invalid or has already been used. Try signing in or request a new link.",
|
|
56
|
+
},
|
|
57
|
+
"already-verified": {
|
|
58
|
+
title: "Already verified",
|
|
59
|
+
message: "Your email was already confirmed. You can sign in now.",
|
|
60
|
+
},
|
|
61
|
+
error: {
|
|
62
|
+
title: "Verification failed",
|
|
63
|
+
message: "We couldn't verify your email. Request a new link from the sign-in page.",
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Standalone email-verification confirmation page. Render on the route you
|
|
69
|
+
* set as `callbackURL` when calling `betterAuthClient.sendVerificationEmail`
|
|
70
|
+
* (or the `verifyCallbackURL` arg on `useBetterAuth().signUpWithEmail`).
|
|
71
|
+
*
|
|
72
|
+
* Better Auth verifies the token server-side before redirecting here. This
|
|
73
|
+
* component only displays the outcome based on the `?error=` query param.
|
|
74
|
+
*
|
|
75
|
+
* Usage:
|
|
76
|
+
* ```tsx
|
|
77
|
+
* const error = new URLSearchParams(window.location.search).get("error");
|
|
78
|
+
* <BetterAuthVerifyEmail
|
|
79
|
+
* errorCode={error}
|
|
80
|
+
* onGoToSignIn={() => router.push("/login")}
|
|
81
|
+
* />
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export function BetterAuthVerifyEmail({
|
|
85
|
+
errorCode,
|
|
86
|
+
onGoToSignIn,
|
|
87
|
+
signInHref = "/login",
|
|
88
|
+
successTitle,
|
|
89
|
+
successMessage,
|
|
90
|
+
className,
|
|
91
|
+
}: BetterAuthVerifyEmailProps) {
|
|
92
|
+
const state = classifyError(errorCode);
|
|
93
|
+
const isSuccess = state === "success" || state === "already-verified";
|
|
94
|
+
const copy = COPY[state];
|
|
95
|
+
const title = isSuccess && successTitle ? successTitle : copy.title;
|
|
96
|
+
const message = isSuccess && successMessage ? successMessage : copy.message;
|
|
97
|
+
|
|
98
|
+
debug("Rendering verify-email state", { state, errorCode });
|
|
99
|
+
|
|
100
|
+
const handleClick = () => {
|
|
101
|
+
if (onGoToSignIn) {
|
|
102
|
+
onGoToSignIn();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (typeof window !== "undefined") {
|
|
106
|
+
window.location.href = signInHref;
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
return (
|
|
111
|
+
<div className={`w-full max-w-[400px] px-6 ${className || ""}`}>
|
|
112
|
+
<div className="space-y-6 text-center">
|
|
113
|
+
<div
|
|
114
|
+
className={`mx-auto flex h-12 w-12 items-center justify-center rounded-full ${
|
|
115
|
+
isSuccess ? "bg-green-100" : "bg-red-100"
|
|
116
|
+
}`}
|
|
117
|
+
>
|
|
118
|
+
{isSuccess ? (
|
|
119
|
+
<svg
|
|
120
|
+
className="h-6 w-6 text-green-600"
|
|
121
|
+
fill="none"
|
|
122
|
+
viewBox="0 0 24 24"
|
|
123
|
+
stroke="currentColor"
|
|
124
|
+
aria-hidden="true"
|
|
125
|
+
>
|
|
126
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
127
|
+
</svg>
|
|
128
|
+
) : (
|
|
129
|
+
<svg
|
|
130
|
+
className="h-6 w-6 text-red-600"
|
|
131
|
+
fill="none"
|
|
132
|
+
viewBox="0 0 24 24"
|
|
133
|
+
stroke="currentColor"
|
|
134
|
+
aria-hidden="true"
|
|
135
|
+
>
|
|
136
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
|
|
137
|
+
</svg>
|
|
138
|
+
)}
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<div>
|
|
142
|
+
<h1 className="text-[28px] font-semibold tracking-tight text-gray-900 dark:text-gray-100">{title}</h1>
|
|
143
|
+
<p className="mt-3 text-[15px] text-gray-500 dark:text-gray-400">{message}</p>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<Button
|
|
147
|
+
onClick={handleClick}
|
|
148
|
+
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"
|
|
149
|
+
>
|
|
150
|
+
{isSuccess ? "Go to sign in" : "Back to sign in"}
|
|
151
|
+
</Button>
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
SignInWithB3ModalProps,
|
|
5
5
|
StyleRoot,
|
|
6
6
|
useAccountWallet,
|
|
7
|
+
useAuthStore,
|
|
7
8
|
useAuthentication,
|
|
8
9
|
useB3Config,
|
|
9
10
|
useIsMobile,
|
|
@@ -14,6 +15,8 @@ import { cn, truncateAddress } from "@b3dotfun/sdk/shared/utils";
|
|
|
14
15
|
import { Menu, MenuButton, MenuItems, Transition } from "@headlessui/react";
|
|
15
16
|
import { ReactNode, useEffect } from "react";
|
|
16
17
|
import { useConnectedWallets, useSetActiveWallet, useWalletImage } from "thirdweb/react";
|
|
18
|
+
import { useUser } from "../../hooks/useUser";
|
|
19
|
+
import { UserAvatar } from "../UserAvatar/UserAvatar";
|
|
17
20
|
import { ManageAccountButton } from "../custom/ManageAccountButton";
|
|
18
21
|
|
|
19
22
|
type SignInProps = {
|
|
@@ -30,7 +33,9 @@ type SignInWithB3Props = Omit<SignInWithB3ModalProps, "type" | "showBackButton">
|
|
|
30
33
|
|
|
31
34
|
export function SignIn(props: SignInWithB3Props) {
|
|
32
35
|
const { className } = props;
|
|
33
|
-
const { automaticallySetFirstEoa, partnerId } = useB3Config();
|
|
36
|
+
const { automaticallySetFirstEoa, partnerId, authStrategy } = useB3Config();
|
|
37
|
+
const isBetterAuth = authStrategy === "better-auth";
|
|
38
|
+
|
|
34
39
|
const {
|
|
35
40
|
address: globalAddress,
|
|
36
41
|
ensName,
|
|
@@ -53,6 +58,11 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
53
58
|
|
|
54
59
|
const setActiveWallet = useSetActiveWallet();
|
|
55
60
|
|
|
61
|
+
// Better Auth state
|
|
62
|
+
const isAuthenticated = useAuthStore(state => state.isAuthenticated);
|
|
63
|
+
const { user } = useUser();
|
|
64
|
+
const userDisplayName = user?.username || user?.email || "Account";
|
|
65
|
+
|
|
56
66
|
const handleSetActiveAccount = (selectedWalletId: string | undefined) => {
|
|
57
67
|
if (
|
|
58
68
|
!selectedWalletId ||
|
|
@@ -72,21 +82,29 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
72
82
|
}
|
|
73
83
|
}, [connectedEOAWallet, isActiveEOAWallet, setActiveWallet, automaticallySetFirstEoa]);
|
|
74
84
|
|
|
85
|
+
const isLoggedIn = isBetterAuth ? isAuthenticated : !!globalAddress;
|
|
86
|
+
|
|
75
87
|
// Desktop version - original dropdown menu
|
|
76
88
|
return (
|
|
77
89
|
<StyleRoot>
|
|
78
90
|
<Menu className={`relative flex items-center ${className || ""}`} as="div">
|
|
79
|
-
{
|
|
91
|
+
{isLoggedIn ? (
|
|
80
92
|
<>
|
|
81
93
|
<MenuButton className="bg-b3-react-background group flex h-10 items-center gap-1 rounded-xl px-3 focus:outline-none">
|
|
82
|
-
{
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
{isBetterAuth ? (
|
|
95
|
+
<UserAvatar avatarUrl={user?.avatar} name={userDisplayName} size={24} />
|
|
96
|
+
) : (
|
|
97
|
+
!!walletImage && (
|
|
98
|
+
<IPFSMediaRenderer
|
|
99
|
+
src={walletImage}
|
|
100
|
+
alt="Wallet Image"
|
|
101
|
+
className="bg-b3-react-primary h-6 w-6 rounded-full object-cover opacity-100"
|
|
102
|
+
/>
|
|
103
|
+
)
|
|
88
104
|
)}
|
|
89
|
-
<div className="text-as-primary">
|
|
105
|
+
<div className="text-as-primary">
|
|
106
|
+
{isBetterAuth ? userDisplayName : ensName ? ensName : truncateAddress(globalAddress ?? "")}
|
|
107
|
+
</div>
|
|
90
108
|
</MenuButton>
|
|
91
109
|
<Transition
|
|
92
110
|
enter="duration-200 ease-out"
|
|
@@ -103,7 +121,16 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
103
121
|
anchor={isMobile ? "top end" : undefined}
|
|
104
122
|
>
|
|
105
123
|
<div className="bg-b3-react-background">
|
|
106
|
-
{
|
|
124
|
+
{isBetterAuth ? (
|
|
125
|
+
/* Better Auth: show user info instead of wallet switching */
|
|
126
|
+
<div className="flex items-center gap-3 rounded-xl p-3">
|
|
127
|
+
<UserAvatar avatarUrl={user?.avatar} name={userDisplayName} size={48} />
|
|
128
|
+
<div className="flex flex-col gap-0.5">
|
|
129
|
+
{user?.username && <div className="text-b3-react-primary font-semibold">{user.username}</div>}
|
|
130
|
+
{user?.email && <div className="text-b3-react-secondary text-sm">{user.email}</div>}
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
) : connectedEOAWallet ? (
|
|
107
134
|
<div
|
|
108
135
|
className={cn(
|
|
109
136
|
"border-b3-react-subtle bg-b3-react-background flex cursor-pointer items-center justify-between rounded-xl p-3",
|
|
@@ -118,7 +145,7 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
118
145
|
/>
|
|
119
146
|
<div className="ml-4 grow">
|
|
120
147
|
{ensName && <div>{ensName}</div>}
|
|
121
|
-
<div>{truncateAddress(globalAddress)}</div>
|
|
148
|
+
<div>{truncateAddress(globalAddress ?? "")}</div>
|
|
122
149
|
{/* <div>{walletInfo?.name}</div> */}
|
|
123
150
|
</div>
|
|
124
151
|
</div>
|
|
@@ -143,7 +170,7 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
143
170
|
/>
|
|
144
171
|
<div className="grow pl-4">
|
|
145
172
|
{ensName && <div>{ensName}</div>}
|
|
146
|
-
<div>{truncateAddress(globalAddress)}</div>
|
|
173
|
+
<div>{truncateAddress(globalAddress ?? "")}</div>
|
|
147
174
|
<div>Smart wallet</div>
|
|
148
175
|
</div>
|
|
149
176
|
</div>
|
|
@@ -159,7 +186,9 @@ export function SignIn(props: SignInWithB3Props) {
|
|
|
159
186
|
<button className="mb-2 w-full space-y-1" onClick={onDisconnect}>
|
|
160
187
|
<div className="hover:bg-b3-react-background group flex h-12 items-center rounded-xl px-4 transition-colors">
|
|
161
188
|
<Icon className="fill-b3-react-primary mr-4 shrink-0 transition-colors" name="logout" />
|
|
162
|
-
<div className="text-b3-react-primary mr-auto transition-colors">
|
|
189
|
+
<div className="text-b3-react-primary mr-auto transition-colors">
|
|
190
|
+
{isBetterAuth ? "Sign out" : "Disconnect"}
|
|
191
|
+
</div>
|
|
163
192
|
</div>
|
|
164
193
|
</button>
|
|
165
194
|
</div>
|
|
@@ -34,6 +34,7 @@ export function SignInWithB3Flow({
|
|
|
34
34
|
closeAfterLogin = false,
|
|
35
35
|
source = "signInWithB3Button",
|
|
36
36
|
signersEnabled = false,
|
|
37
|
+
verifyEmailRedirectTo,
|
|
37
38
|
}: SignInWithB3ModalProps) {
|
|
38
39
|
const { automaticallySetFirstEoa, authStrategy } = useB3Config();
|
|
39
40
|
// skipAutoConnect: this component intentionally logs out on mount to show a fresh login screen.
|
|
@@ -292,7 +293,13 @@ export function SignInWithB3Flow({
|
|
|
292
293
|
// Better Auth manages its own loading/verification states internally.
|
|
293
294
|
// Don't gate on isAuthenticating — it would unmount the component
|
|
294
295
|
// and lose verification state when setIsAuthenticating(false) fires.
|
|
295
|
-
content =
|
|
296
|
+
content = (
|
|
297
|
+
<LoginStepBetterAuth
|
|
298
|
+
onSuccess={() => handleLoginSuccess({} as Account)}
|
|
299
|
+
onError={onError}
|
|
300
|
+
verifyEmailRedirectTo={verifyEmailRedirectTo}
|
|
301
|
+
/>
|
|
302
|
+
);
|
|
296
303
|
} else if (!readyToShowLogin || isAuthenticating || isFetchingSigners) {
|
|
297
304
|
content = (
|
|
298
305
|
<LoginStepContainer partnerId={partnerId}>
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Input } from "@b3dotfun/sdk/global-account/react";
|
|
2
|
+
import { useState } from "react";
|
|
3
|
+
|
|
4
|
+
interface PasswordInputProps {
|
|
5
|
+
value: string;
|
|
6
|
+
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
onKeyDown?: (e: React.KeyboardEvent<HTMLInputElement>) => void;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function PasswordInput({
|
|
14
|
+
value,
|
|
15
|
+
onChange,
|
|
16
|
+
disabled,
|
|
17
|
+
placeholder = "Password",
|
|
18
|
+
onKeyDown,
|
|
19
|
+
className,
|
|
20
|
+
}: PasswordInputProps) {
|
|
21
|
+
const [showPassword, setShowPassword] = useState(false);
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<div className="relative">
|
|
25
|
+
<Input
|
|
26
|
+
type={showPassword ? "text" : "password"}
|
|
27
|
+
placeholder={placeholder}
|
|
28
|
+
value={value}
|
|
29
|
+
onChange={onChange}
|
|
30
|
+
disabled={disabled}
|
|
31
|
+
onKeyDown={onKeyDown}
|
|
32
|
+
className={className}
|
|
33
|
+
/>
|
|
34
|
+
<button
|
|
35
|
+
type="button"
|
|
36
|
+
onClick={() => setShowPassword(!showPassword)}
|
|
37
|
+
aria-label={showPassword ? "Hide password" : "Show password"}
|
|
38
|
+
className="absolute right-3 top-1/2 -translate-y-1/2 text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300"
|
|
39
|
+
tabIndex={-1}
|
|
40
|
+
>
|
|
41
|
+
{showPassword ? (
|
|
42
|
+
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
43
|
+
<path
|
|
44
|
+
strokeLinecap="round"
|
|
45
|
+
strokeLinejoin="round"
|
|
46
|
+
d="M3.98 8.223A10.477 10.477 0 001.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.45 10.45 0 0112 4.5c4.756 0 8.773 3.162 10.065 7.498a10.523 10.523 0 01-4.293 5.774M6.228 6.228L3 3m3.228 3.228l3.65 3.65m7.894 7.894L21 21m-3.228-3.228l-3.65-3.65m0 0a3 3 0 10-4.243-4.243m4.242 4.242L9.88 9.88"
|
|
47
|
+
/>
|
|
48
|
+
</svg>
|
|
49
|
+
) : (
|
|
50
|
+
<svg className="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
|
|
51
|
+
<path
|
|
52
|
+
strokeLinecap="round"
|
|
53
|
+
strokeLinejoin="round"
|
|
54
|
+
d="M2.036 12.322a1.012 1.012 0 010-.639C3.423 7.51 7.36 4.5 12 4.5c4.638 0 8.573 3.007 9.963 7.178.07.207.07.431 0 .639C20.577 16.49 16.64 19.5 12 19.5c-4.638 0-8.573-3.007-9.963-7.178z"
|
|
55
|
+
/>
|
|
56
|
+
<path strokeLinecap="round" strokeLinejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
|
57
|
+
</svg>
|
|
58
|
+
)}
|
|
59
|
+
</button>
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
useBetterAuth,
|
|
8
8
|
} from "../../../hooks/useBetterAuth";
|
|
9
9
|
import { AuthButton } from "../components/AuthButton";
|
|
10
|
+
import { PasswordInput } from "../components/PasswordInput";
|
|
10
11
|
|
|
11
12
|
const debug = debugB3React("LoginStepBetterAuth");
|
|
12
13
|
const EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
@@ -22,9 +23,11 @@ const SOCIAL_PROVIDERS: { id: BetterAuthSocialProvider; label: string }[] = [
|
|
|
22
23
|
interface LoginStepBetterAuthProps {
|
|
23
24
|
onSuccess?: () => void;
|
|
24
25
|
onError?: (error: Error) => Promise<void>;
|
|
26
|
+
/** URL Better Auth redirects to after server-side email verification. */
|
|
27
|
+
verifyEmailRedirectTo?: string;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
export function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthProps) {
|
|
30
|
+
export function LoginStepBetterAuth({ onSuccess, onError, verifyEmailRedirectTo }: LoginStepBetterAuthProps) {
|
|
28
31
|
const { partnerId } = useB3Config();
|
|
29
32
|
const { signInWithEmail, signUpWithEmail, signInWithSocial, requestPasswordReset } = useBetterAuth();
|
|
30
33
|
|
|
@@ -62,7 +65,7 @@ export function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthP
|
|
|
62
65
|
|
|
63
66
|
if (mode === "sign-up") {
|
|
64
67
|
debug("Signing up", { email: normalizedEmail, name: name.trim() });
|
|
65
|
-
await signUpWithEmail(normalizedEmail, password, name.trim());
|
|
68
|
+
await signUpWithEmail(normalizedEmail, password, name.trim(), verifyEmailRedirectTo);
|
|
66
69
|
} else {
|
|
67
70
|
debug("Signing in", { email: normalizedEmail });
|
|
68
71
|
await signInWithEmail(normalizedEmail, password);
|
|
@@ -160,7 +163,11 @@ export function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthP
|
|
|
160
163
|
{mode === "forgot-password" ? (
|
|
161
164
|
<div className="mb-6 w-full space-y-3 px-3">
|
|
162
165
|
<p className="text-center text-sm font-medium text-gray-900 dark:text-gray-100">Reset password</p>
|
|
163
|
-
<p className="text-center text-xs text-gray-500">
|
|
166
|
+
<p className="text-center text-xs text-gray-500">
|
|
167
|
+
{resetEmailSent
|
|
168
|
+
? "We've sent a password reset link to your email"
|
|
169
|
+
: "Enter your email and we'll send you a reset link"}
|
|
170
|
+
</p>
|
|
164
171
|
|
|
165
172
|
{resetEmailSent ? (
|
|
166
173
|
<div className="space-y-3 py-4 text-center">
|
|
@@ -223,15 +230,15 @@ export function LoginStepBetterAuth({ onSuccess, onError }: LoginStepBetterAuthP
|
|
|
223
230
|
disabled={isLoading}
|
|
224
231
|
/>
|
|
225
232
|
|
|
226
|
-
<
|
|
227
|
-
|
|
228
|
-
placeholder="Password"
|
|
233
|
+
<PasswordInput
|
|
234
|
+
key={mode}
|
|
229
235
|
value={password}
|
|
230
236
|
onChange={event => setPassword(event.target.value)}
|
|
231
237
|
disabled={isLoading}
|
|
232
238
|
onKeyDown={event => {
|
|
233
239
|
if (event.key === "Enter") handleEmailSubmit();
|
|
234
240
|
}}
|
|
241
|
+
className="pr-11"
|
|
235
242
|
/>
|
|
236
243
|
|
|
237
244
|
{error && <p className="text-sm text-red-500">{error}</p>}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { validateImageUrl } from "@b3dotfun/sdk/global-account/react/utils/profileDisplay";
|
|
2
|
+
import { AVATAR_COLORS } from "@b3dotfun/sdk/shared/constants";
|
|
3
|
+
import Avatar from "boring-avatars";
|
|
4
|
+
import { useCallback, useEffect, useState } from "react";
|
|
5
|
+
import { IPFSMediaRenderer } from "../IPFSMediaRenderer/IPFSMediaRenderer";
|
|
6
|
+
|
|
7
|
+
interface UserAvatarProps {
|
|
8
|
+
/** Direct avatar URL (IPFS or HTTP). Resolved and validated internally. */
|
|
9
|
+
avatarUrl?: string | null;
|
|
10
|
+
/** Seed for the generated fallback avatar + alt text. Use email, username, or address. */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Avatar size in pixels (square). */
|
|
13
|
+
size?: number;
|
|
14
|
+
/** Additional className for the outer container. */
|
|
15
|
+
className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Renders a user avatar with IPFS support and boring-avatars fallback.
|
|
20
|
+
*
|
|
21
|
+
* - If `avatarUrl` is provided and valid, renders via IPFSMediaRenderer.
|
|
22
|
+
* - On load failure or missing URL, falls back to a deterministic boring-avatars beam.
|
|
23
|
+
*/
|
|
24
|
+
export function UserAvatar({ avatarUrl, name = "user", size = 40, className }: UserAvatarProps) {
|
|
25
|
+
const resolvedSrc = validateImageUrl(avatarUrl);
|
|
26
|
+
const [imgError, setImgError] = useState(false);
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
setImgError(false);
|
|
30
|
+
}, [avatarUrl]);
|
|
31
|
+
|
|
32
|
+
const handleImgError = useCallback(() => setImgError(true), []);
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<div className={className} style={{ width: size, height: size, minWidth: size, minHeight: size }}>
|
|
36
|
+
{resolvedSrc && !imgError ? (
|
|
37
|
+
<div onErrorCapture={handleImgError} className="h-full w-full overflow-hidden rounded-full">
|
|
38
|
+
<IPFSMediaRenderer src={resolvedSrc} alt={name} className="h-full w-full object-cover" />
|
|
39
|
+
</div>
|
|
40
|
+
) : (
|
|
41
|
+
<Avatar name={name} variant="beam" size={size} colors={AVATAR_COLORS} />
|
|
42
|
+
)}
|
|
43
|
+
</div>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
@@ -7,11 +7,17 @@ export { RelayKitProviderWrapper } from "./B3Provider/RelayKitProviderWrapper";
|
|
|
7
7
|
export { useB3 } from "./B3Provider/useB3";
|
|
8
8
|
export { useB3Account } from "./B3Provider/useB3Account";
|
|
9
9
|
export { useB3Config } from "./B3Provider/useB3Config";
|
|
10
|
+
export { useBetterAuthClient } from "./B3Provider/BetterAuthClientProvider";
|
|
10
11
|
export { StyleRoot } from "./StyleRoot";
|
|
11
12
|
|
|
12
13
|
// SignInWithB3 Components
|
|
13
14
|
export { BetterAuthResetPassword, type BetterAuthResetPasswordProps } from "./SignInWithB3/BetterAuthResetPassword";
|
|
14
15
|
export { BetterAuthSignIn, type BetterAuthSignInProps } from "./SignInWithB3/BetterAuthSignIn";
|
|
16
|
+
export {
|
|
17
|
+
BetterAuthVerifyEmail,
|
|
18
|
+
type BetterAuthVerifyEmailProps,
|
|
19
|
+
type BetterAuthVerifyEmailState,
|
|
20
|
+
} from "./SignInWithB3/BetterAuthVerifyEmail";
|
|
15
21
|
export { AuthButton } from "./SignInWithB3/components/AuthButton";
|
|
16
22
|
export { PermissionItem } from "./SignInWithB3/components/PermissionItem";
|
|
17
23
|
export { WalletRow } from "./SignInWithB3/components/WalletRow";
|
|
@@ -24,6 +30,9 @@ export { getConnectOptionsFromStrategy, isWalletType, type AllowedStrategy } fro
|
|
|
24
30
|
// ManageAccount Components
|
|
25
31
|
export { ManageAccount } from "./ManageAccount/ManageAccount";
|
|
26
32
|
|
|
33
|
+
// UserAvatar
|
|
34
|
+
export { UserAvatar } from "./UserAvatar/UserAvatar";
|
|
35
|
+
|
|
27
36
|
// Deposit Components
|
|
28
37
|
export { Deposit } from "./Deposit/Deposit";
|
|
29
38
|
|
|
@@ -2,7 +2,7 @@ import app from "@b3dotfun/sdk/global-account/app";
|
|
|
2
2
|
import { useAuthStore, useB3Config } from "@b3dotfun/sdk/global-account/react";
|
|
3
3
|
import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
|
|
4
4
|
import { useCallback } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { useBetterAuthClient } from "../components/B3Provider/BetterAuthClientProvider";
|
|
6
6
|
import { useUserQuery } from "./useUserQuery";
|
|
7
7
|
|
|
8
8
|
const debug = debugB3React("useBetterAuth");
|
|
@@ -27,6 +27,7 @@ export class EmailVerificationRequiredError extends Error {
|
|
|
27
27
|
*/
|
|
28
28
|
export function useBetterAuth() {
|
|
29
29
|
const { partnerId } = useB3Config();
|
|
30
|
+
const betterAuthClient = useBetterAuthClient();
|
|
30
31
|
const { setUser } = useUserQuery();
|
|
31
32
|
const setIsAuthenticated = useAuthStore(state => state.setIsAuthenticated);
|
|
32
33
|
const setIsAuthenticating = useAuthStore(state => state.setIsAuthenticating);
|
|
@@ -83,11 +84,11 @@ export function useBetterAuth() {
|
|
|
83
84
|
throw error;
|
|
84
85
|
}
|
|
85
86
|
},
|
|
86
|
-
[exchangeForFeathersJWT, setIsAuthenticating, setHasStartedConnecting],
|
|
87
|
+
[exchangeForFeathersJWT, setIsAuthenticating, setHasStartedConnecting, betterAuthClient],
|
|
87
88
|
);
|
|
88
89
|
|
|
89
90
|
const signUpWithEmail = useCallback(
|
|
90
|
-
async (email: string, password: string, name: string) => {
|
|
91
|
+
async (email: string, password: string, name: string, verifyCallbackURL?: string) => {
|
|
91
92
|
debug("Signing up with email", { email, name });
|
|
92
93
|
setHasStartedConnecting(true);
|
|
93
94
|
setIsAuthenticating(true);
|
|
@@ -101,11 +102,12 @@ export function useBetterAuth() {
|
|
|
101
102
|
|
|
102
103
|
const token = result.data?.token;
|
|
103
104
|
if (!token) {
|
|
104
|
-
// requireEmailVerification is enabled — send verification email
|
|
105
|
-
//
|
|
105
|
+
// requireEmailVerification is enabled — send verification email with
|
|
106
|
+
// a callbackURL Better Auth redirects to after server-side verify.
|
|
107
|
+
// Pass verifyCallbackURL to land on a dedicated confirmation page.
|
|
106
108
|
await betterAuthClient.sendVerificationEmail({
|
|
107
109
|
email,
|
|
108
|
-
callbackURL: `${window.location.origin}?authStrategy=better-auth`,
|
|
110
|
+
callbackURL: verifyCallbackURL || `${window.location.origin}?authStrategy=better-auth`,
|
|
109
111
|
});
|
|
110
112
|
throw new EmailVerificationRequiredError();
|
|
111
113
|
}
|
|
@@ -117,7 +119,7 @@ export function useBetterAuth() {
|
|
|
117
119
|
throw error;
|
|
118
120
|
}
|
|
119
121
|
},
|
|
120
|
-
[exchangeForFeathersJWT, setIsAuthenticating, setHasStartedConnecting],
|
|
122
|
+
[exchangeForFeathersJWT, setIsAuthenticating, setHasStartedConnecting, betterAuthClient],
|
|
121
123
|
);
|
|
122
124
|
|
|
123
125
|
const signInWithSocial = useCallback(
|
|
@@ -144,7 +146,7 @@ export function useBetterAuth() {
|
|
|
144
146
|
throw error;
|
|
145
147
|
}
|
|
146
148
|
},
|
|
147
|
-
[setIsAuthenticating, setHasStartedConnecting],
|
|
149
|
+
[setIsAuthenticating, setHasStartedConnecting, betterAuthClient],
|
|
148
150
|
);
|
|
149
151
|
|
|
150
152
|
const requestPasswordReset = useCallback(async (email: string, redirectTo?: string) => {
|
|
@@ -161,7 +163,7 @@ export function useBetterAuth() {
|
|
|
161
163
|
|
|
162
164
|
debug("Password reset email sent");
|
|
163
165
|
return result;
|
|
164
|
-
}, []);
|
|
166
|
+
}, [betterAuthClient]);
|
|
165
167
|
|
|
166
168
|
const resetPassword = useCallback(async (newPassword: string, token: string) => {
|
|
167
169
|
debug("Resetting password");
|
|
@@ -177,7 +179,7 @@ export function useBetterAuth() {
|
|
|
177
179
|
|
|
178
180
|
debug("Password reset successful");
|
|
179
181
|
return result;
|
|
180
|
-
}, []);
|
|
182
|
+
}, [betterAuthClient]);
|
|
181
183
|
|
|
182
184
|
return {
|
|
183
185
|
signInWithEmail,
|
|
@@ -44,6 +44,8 @@ export interface SignInWithB3ModalProps extends BaseModalProps {
|
|
|
44
44
|
source?: "signInWithB3Button" | "requestPermissions";
|
|
45
45
|
/** Whether to show the signers enabled modal */
|
|
46
46
|
signersEnabled?: boolean;
|
|
47
|
+
/** URL Better Auth redirects to after server-side email verification. */
|
|
48
|
+
verifyEmailRedirectTo?: string;
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/**
|
|
@@ -635,6 +637,8 @@ export interface AnySpendDepositModalProps extends BaseModalProps {
|
|
|
635
637
|
actionLabel?: string;
|
|
636
638
|
/** Whether to show chain selection step. Defaults to true if sourceTokenChainId is not provided */
|
|
637
639
|
showChainSelection?: boolean;
|
|
640
|
+
/** Whether to show the "Fund with Fiat" option in the deposit options list. Defaults to true */
|
|
641
|
+
showFiatOption?: boolean;
|
|
638
642
|
/** Minimum pool size for filtering tokens (default: 1,000,000) */
|
|
639
643
|
minPoolSize?: number;
|
|
640
644
|
/** Custom title for chain selection step */
|
|
@@ -32,3 +32,5 @@ export const B3_AUTH_COOKIE_NAME = "b3-auth";
|
|
|
32
32
|
export const ENS_GATEWAY_URL = "https://ens-gateway.b3.fun/";
|
|
33
33
|
|
|
34
34
|
export const PUBLIC_BASE_RPC_URL = "https://base-rpc.publicnode.com";
|
|
35
|
+
|
|
36
|
+
export const AVATAR_COLORS = ["#3368ef", "#272727", "#6366f1", "#06b6d4", "#eeb0d9", "#ba3fbf", "#ff777b", "#dfbb53"];
|