diff --git a/packages/thirdweb/src/react/web/wallets/shared/OTPLoginUI.tsx b/packages/thirdweb/src/react/web/wallets/shared/OTPLoginUI.tsx index 7aeffc41bb8..46bb91ff7fa 100644 --- a/packages/thirdweb/src/react/web/wallets/shared/OTPLoginUI.tsx +++ b/packages/thirdweb/src/react/web/wallets/shared/OTPLoginUI.tsx @@ -29,7 +29,10 @@ type VerificationStatus = | "valid" | "idle" | "payment_required"; -type AccountStatus = "sending" | "sent" | "error"; +type AccountStatus = + | { type: "sending" } + | { type: "sent" } + | { type: "error"; message: string | undefined }; type ScreenToShow = "base" | "enter-password-or-recovery-code"; /** @@ -52,7 +55,9 @@ export function OTPLoginUI(props: { const [otpInput, setOtpInput] = useState(""); const [verifyStatus, setVerifyStatus] = useState("idle"); const [error, setError] = useState(); - const [accountStatus, setAccountStatus] = useState("sending"); + const [accountStatus, setAccountStatus] = useState({ + type: "sending", + }); const [countdown, setCountdown] = useState(0); const ecosystem = isEcosystemWallet(wallet) ? { @@ -66,7 +71,7 @@ export function OTPLoginUI(props: { const sendEmailOrSms = useCallback(async () => { setOtpInput(""); setVerifyStatus("idle"); - setAccountStatus("sending"); + setAccountStatus({ type: "sending" }); try { if ("email" in userInfo) { @@ -76,7 +81,7 @@ export function OTPLoginUI(props: { email: userInfo.email, strategy: "email", }); - setAccountStatus("sent"); + setAccountStatus({ type: "sent" }); setCountdown(60); // Start 60-second countdown } else if ("phone" in userInfo) { await preAuthenticate({ @@ -85,7 +90,7 @@ export function OTPLoginUI(props: { phoneNumber: userInfo.phone, strategy: "phone", }); - setAccountStatus("sent"); + setAccountStatus({ type: "sent" }); setCountdown(60); // Start 60-second countdown } else { throw new Error("Invalid userInfo"); @@ -93,7 +98,10 @@ export function OTPLoginUI(props: { } catch (e) { console.error(e); setVerifyStatus("idle"); - setAccountStatus("error"); + setAccountStatus({ + type: "error", + message: e instanceof Error ? e.message : undefined, + }); } }, [props.client, userInfo, ecosystem]); @@ -317,19 +325,24 @@ export function OTPLoginUI(props: { {!isWideModal && } - - {accountStatus === "error" && ( + + {accountStatus.type === "error" && ( - {locale.emailLoginScreen.failedToSendCode} + {accountStatus.message || + locale.emailLoginScreen.failedToSendCode} )} - {accountStatus === "sending" && ( + {accountStatus.type === "sending" && ( )} - {accountStatus !== "sending" && ( + {accountStatus.type !== "sending" && ( => { }); if (!response.ok) { - throw new Error("Failed to send verification code"); + const raw = await response.text(); + let message: string | undefined; + try { + const parsed = JSON.parse(raw); + if (parsed && typeof parsed.message === "string") { + message = parsed.message; + } + } catch { + // ignore parse errors + } + throw new Error(message || "Failed to send verification code"); } return await response.json();