From a61b0fc1d7c22bf233700f7d56c44a5e642ab21a Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Tue, 17 Dec 2024 13:13:45 -0600 Subject: [PATCH 01/10] fix: updating styles for otp input field when focussed --- account-kit/react/src/components/otp-input/otp-input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account-kit/react/src/components/otp-input/otp-input.tsx b/account-kit/react/src/components/otp-input/otp-input.tsx index b1297af972..11377bec28 100644 --- a/account-kit/react/src/components/otp-input/otp-input.tsx +++ b/account-kit/react/src/components/otp-input/otp-input.tsx @@ -140,7 +140,7 @@ export const OTPInput: React.FC = ({
{initialOTPValue.map((_, i) => ( (refs.current[i] = el)} From c819c8b82890b1e8ba8e226072777e8d7042024f Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Wed, 18 Dec 2024 09:34:37 -0600 Subject: [PATCH 02/10] fix: keeping otp input in view while the code is validated --- .../react/src/components/auth/card/index.tsx | 1 - .../src/components/auth/card/loading/otp.tsx | 100 ++++++++---------- .../react/src/components/auth/card/steps.tsx | 4 +- .../react/src/components/auth/context.ts | 6 -- .../src/components/auth/sections/Footer.tsx | 1 - .../src/components/otp-input/otp-input.tsx | 4 +- 6 files changed, 49 insertions(+), 67 deletions(-) diff --git a/account-kit/react/src/components/auth/card/index.tsx b/account-kit/react/src/components/auth/card/index.tsx index 260259ad86..2fbc949874 100644 --- a/account-kit/react/src/components/auth/card/index.tsx +++ b/account-kit/react/src/components/auth/card/index.tsx @@ -90,7 +90,6 @@ export const AuthCardContent = ({ case "passkey_verify": case "passkey_create": case "oauth_completing": - case "otp_completing": disconnect(config); // Terminate any inflight authentication didGoBack.current = true; setAuthStep({ type: "initial" }); diff --git a/account-kit/react/src/components/auth/card/loading/otp.tsx b/account-kit/react/src/components/auth/card/loading/otp.tsx index 542da7c2db..969aa9af71 100644 --- a/account-kit/react/src/components/auth/card/loading/otp.tsx +++ b/account-kit/react/src/components/auth/card/loading/otp.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { EmailIllustration } from "../../../../icons/illustrations/email.js"; import { ls } from "../../../../strings.js"; import { @@ -14,14 +14,15 @@ import { useSignerStatus } from "../../../../hooks/useSignerStatus.js"; export const LoadingOtp = () => { const { isConnected } = useSignerStatus(); - const { authStep, setAuthStep } = useAuthContext("otp_verify"); + const { authStep } = useAuthContext("otp_verify"); const [otpCode, setOtpCode] = useState(initialOTPValue); - const [errorText, setErrorText] = useState( - getUserErrorMessage(authStep.error) - ); - const resetOTP = () => { + const [errorText, setErrorText] = useState(authStep.error?.message || ""); + const [isDisabled, setIsDisabled] = useState(false); + const { setAuthStep } = useAuthContext(); + const resetOTP = (errorText = "") => { setOtpCode(initialOTPValue); - setErrorText(""); + setErrorText(errorText); + setIsDisabled(false); }; const { authenticate } = useAuthenticate({ onError: (error: any) => { @@ -36,26 +37,11 @@ export const LoadingOtp = () => { }, }); - useEffect(() => { - if (isOTPCodeType(otpCode)) { - setAuthStep({ - type: "otp_completing", - email: authStep.email, - otp: otpCode.join(""), - }); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [otpCode]); - const setValue = (otpCode: OTPCodeType) => { setOtpCode(otpCode); if (isOTPCodeType(otpCode)) { + setIsDisabled(true); const otp = otpCode.join(""); - setAuthStep({ - type: "otp_completing", - email: authStep.email, - otp, - }); authenticate({ type: "otp", otpCode: otp }); } }; @@ -80,6 +66,7 @@ export const LoadingOtp = () => { {authStep.email}

{ ); }; -export const CompletingOtp = () => { - return ( -
-
- -
-

- {ls.completingOtp.title} -

-

- {ls.completingOtp.body} -

-
- ); -}; +// export const CompletingOtp = () => { +// const { isConnected } = useSignerStatus(); +// const { setAuthStep, authStep } = useAuthContext("otp_completing"); +// const { authenticate } = useAuthenticate({ +// onError: (error: any) => { +// console.error(error); +// const { email } = authStep; +// setAuthStep({ type: "otp_verify", email, error }); +// }, +// onSuccess: () => { +// if (isConnected && authStep.createPasskeyAfter) { +// setAuthStep({ type: "passkey_create" }); +// } else if (isConnected) { +// setAuthStep({ type: "complete" }); +// } +// }, +// }); -function getUserErrorMessage(error: Error | undefined): string { - if (!error) { - return ""; - } - // Errors from Alchemy have a JSON message. - try { - const message = JSON.parse(error.message).error; - if (message === "invalid OTP code") { - return ls.error.otp.invalid; - } - return message; - } catch (e) { - // Ignore - } - return error.message; -} +// useEffect(() => { +// authenticate({ type: "otp", otpCode: authStep.otp }); +// // eslint-disable-next-line react-hooks/exhaustive-deps +// }, []); + +// return ( +//
+//
+// +//
+//

+// {ls.completingOtp.title} +//

+//

+// {ls.completingOtp.body} +//

+//
+// ); +// }; diff --git a/account-kit/react/src/components/auth/card/steps.tsx b/account-kit/react/src/components/auth/card/steps.tsx index a6a9eae177..ff74b36a6f 100644 --- a/account-kit/react/src/components/auth/card/steps.tsx +++ b/account-kit/react/src/components/auth/card/steps.tsx @@ -6,7 +6,7 @@ import { CompletingOAuth } from "./loading/oauth.js"; import { LoadingPasskeyAuth } from "./loading/passkey.js"; import { MainAuthContent } from "./main.js"; import { PasskeyAdded } from "./passkey-added.js"; -import { CompletingOtp, LoadingOtp } from "./loading/otp.js"; +import { LoadingOtp } from "./loading/otp.js"; export const Step = () => { const { authStep } = useAuthContext(); @@ -21,8 +21,6 @@ export const Step = () => { return ; case "oauth_completing": return ; - case "otp_completing": - return ; case "passkey_create": return ; case "passkey_create_success": diff --git a/account-kit/react/src/components/auth/context.ts b/account-kit/react/src/components/auth/context.ts index 61827a9712..61e27847f1 100644 --- a/account-kit/react/src/components/auth/context.ts +++ b/account-kit/react/src/components/auth/context.ts @@ -16,12 +16,6 @@ export type AuthStep = config: Extract; error?: Error; } - | { - type: "otp_completing"; - email: string; - otp: string; - error?: Error; - } | { type: "initial"; error?: Error } | { type: "complete" } | { type: "eoa_connect"; connector: Connector; error?: Error } diff --git a/account-kit/react/src/components/auth/sections/Footer.tsx b/account-kit/react/src/components/auth/sections/Footer.tsx index 40ae4781b3..302a30b428 100644 --- a/account-kit/react/src/components/auth/sections/Footer.tsx +++ b/account-kit/react/src/components/auth/sections/Footer.tsx @@ -23,7 +23,6 @@ const RenderFooterText = ({ authStep }: FooterProps) => { case "oauth_completing": return ; case "email_completing": - case "otp_completing": case "passkey_create_success": case "eoa_connect": case "pick_eoa": diff --git a/account-kit/react/src/components/otp-input/otp-input.tsx b/account-kit/react/src/components/otp-input/otp-input.tsx index 11377bec28..fe56075cd2 100644 --- a/account-kit/react/src/components/otp-input/otp-input.tsx +++ b/account-kit/react/src/components/otp-input/otp-input.tsx @@ -7,8 +7,8 @@ const OTP_LENGTH = 6; type OTPInputProps = { errorText?: string; value: OTPCodeType; - setValue: (otp: OTPCodeType) => void; - setErrorText: (error: string) => void; + setValue: (otpCode: OTPCodeType) => void; + setErrorText: React.Dispatch>; disabled?: boolean; handleReset: () => void; className?: string; From 57d2b6c542baca545275490cba58990ea12c1753 Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Wed, 18 Dec 2024 10:31:25 -0600 Subject: [PATCH 03/10] fix: removing un-used component --- .../src/components/auth/card/loading/otp.tsx | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/account-kit/react/src/components/auth/card/loading/otp.tsx b/account-kit/react/src/components/auth/card/loading/otp.tsx index 969aa9af71..c33505f689 100644 --- a/account-kit/react/src/components/auth/card/loading/otp.tsx +++ b/account-kit/react/src/components/auth/card/loading/otp.tsx @@ -76,41 +76,3 @@ export const LoadingOtp = () => {
); }; - -// export const CompletingOtp = () => { -// const { isConnected } = useSignerStatus(); -// const { setAuthStep, authStep } = useAuthContext("otp_completing"); -// const { authenticate } = useAuthenticate({ -// onError: (error: any) => { -// console.error(error); -// const { email } = authStep; -// setAuthStep({ type: "otp_verify", email, error }); -// }, -// onSuccess: () => { -// if (isConnected && authStep.createPasskeyAfter) { -// setAuthStep({ type: "passkey_create" }); -// } else if (isConnected) { -// setAuthStep({ type: "complete" }); -// } -// }, -// }); - -// useEffect(() => { -// authenticate({ type: "otp", otpCode: authStep.otp }); -// // eslint-disable-next-line react-hooks/exhaustive-deps -// }, []); - -// return ( -//
-//
-// -//
-//

-// {ls.completingOtp.title} -//

-//

-// {ls.completingOtp.body} -//

-//
-// ); -// }; From 4e9460866013389537f24a1c7eb801ecebe45740 Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Thu, 19 Dec 2024 13:17:19 -0600 Subject: [PATCH 04/10] fix: make input disable when code is verified --- account-kit/react/src/components/otp-input/otp-input.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/account-kit/react/src/components/otp-input/otp-input.tsx b/account-kit/react/src/components/otp-input/otp-input.tsx index fe56075cd2..c8e49bb6ae 100644 --- a/account-kit/react/src/components/otp-input/otp-input.tsx +++ b/account-kit/react/src/components/otp-input/otp-input.tsx @@ -158,7 +158,7 @@ export const OTPInput: React.FC = ({ onInput={focusNextElement} onKeyDown={handleKeydown} key={i} - disabled={disabled} + disabled={disabled || isVerified} value={value[i]} aria-invalid={!!errorText} /> From b00b3d4ee0cc1d7db40f18247fce9ee881fc5edf Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Thu, 19 Dec 2024 13:50:48 -0600 Subject: [PATCH 05/10] fix: fixing unit tests with added color --- account-kit/react/src/tailwind/utils.test.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/account-kit/react/src/tailwind/utils.test.ts b/account-kit/react/src/tailwind/utils.test.ts index faa0f38296..322cfcb8cc 100644 --- a/account-kit/react/src/tailwind/utils.test.ts +++ b/account-kit/react/src/tailwind/utils.test.ts @@ -91,6 +91,10 @@ describe("tailwind utils test", () => { "dark": "#E2E8F0", "light": "#475569", }, + "fg-success": { + + "dark": "#86EFAC", + + "light": "#16A34A", + + }, "fg-tertiary": { "dark": "#94A3B8", "light": "#94A3B8", From 099952d823b214dcc17e2dc46714abe61066ab30 Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Thu, 19 Dec 2024 13:58:42 -0600 Subject: [PATCH 06/10] fix: fixing unit tests with added color --- account-kit/react/src/tailwind/utils.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/account-kit/react/src/tailwind/utils.test.ts b/account-kit/react/src/tailwind/utils.test.ts index 322cfcb8cc..321b0eac1c 100644 --- a/account-kit/react/src/tailwind/utils.test.ts +++ b/account-kit/react/src/tailwind/utils.test.ts @@ -92,9 +92,9 @@ describe("tailwind utils test", () => { "light": "#475569", }, "fg-success": { - + "dark": "#86EFAC", - + "light": "#16A34A", - + }, + "dark": "#86EFAC", + "light": "#16A34A", + }, "fg-tertiary": { "dark": "#94A3B8", "light": "#94A3B8", From c4cc6a33f6d6e5fc309b6e039074615c19d3c69a Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Fri, 20 Dec 2024 12:03:22 -0600 Subject: [PATCH 07/10] fix: updating styles and flow of otp auth --- .../auth/card/footer/email-not-reveived.tsx | 29 ++++++++++-- .../src/components/auth/card/loading/otp.tsx | 46 +++++++++++++++---- .../react/src/components/auth/context.ts | 13 +++++- .../src/components/otp-input/otp-input.tsx | 16 +++++-- account-kit/react/src/strings.ts | 2 + 5 files changed, 88 insertions(+), 18 deletions(-) diff --git a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx index 18d62fa577..2bcae57487 100644 --- a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx +++ b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx @@ -1,7 +1,11 @@ -import { useEffect, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import { useAuthenticate } from "../../../../hooks/useAuthenticate.js"; import { ls } from "../../../../strings.js"; -import { useAuthContext, type AuthStep } from "../../context.js"; +import { + AuthStepStatus, + useAuthContext, + type AuthStep, +} from "../../context.js"; import { Button } from "../../../button.js"; type EmailNotReceivedDisclaimerProps = { @@ -18,6 +22,14 @@ export const EmailNotReceivedDisclaimer = ({ }, }); + const isOTPVerifying = useMemo(() => { + return ( + authStep.type === "otp_verify" && + (authStep.status === AuthStepStatus.verifying || + authStep.status === AuthStepStatus.success) + ); + }, [authStep]); + useEffect(() => { if (emailResent) { // set the text back to "Resend" after 2 seconds @@ -29,13 +41,20 @@ export const EmailNotReceivedDisclaimer = ({ return (
- + {ls.loadingEmail.emailNotReceived}

- {ls.loadingOtp.title} + {titleText}

{ls.loadingOtp.body} @@ -66,13 +76,31 @@ export const LoadingOtp = () => { {authStep.email}

); }; + +function getUserErrorMessage(error: Error | undefined): string { + if (!error) { + return ""; + } + // Errors from Alchemy have a JSON message. + try { + const message = JSON.parse(error.message).error; + if (message === "invalid OTP code") { + return ls.error.otp.invalid; + } + return message; + } catch (e) { + // Ignore + } + return error.message; +} diff --git a/account-kit/react/src/components/auth/context.ts b/account-kit/react/src/components/auth/context.ts index 61e27847f1..e3b14107ee 100644 --- a/account-kit/react/src/components/auth/context.ts +++ b/account-kit/react/src/components/auth/context.ts @@ -4,9 +4,20 @@ import type { Connector } from "@wagmi/core"; import { createContext, useContext } from "react"; import type { AuthType } from "./types"; +export enum AuthStepStatus { + success = "success", + error = "error", + verifying = "verifying", +} + export type AuthStep = | { type: "email_verify"; email: string } - | { type: "otp_verify"; email: string; error?: Error } + | { + type: "otp_verify"; + email: string; + error?: Error; + status?: AuthStepStatus | null; + } | { type: "passkey_verify"; error?: Error } | { type: "passkey_create"; error?: Error } | { type: "passkey_create_success" } diff --git a/account-kit/react/src/components/otp-input/otp-input.tsx b/account-kit/react/src/components/otp-input/otp-input.tsx index c8e49bb6ae..d1e14b4d5d 100644 --- a/account-kit/react/src/components/otp-input/otp-input.tsx +++ b/account-kit/react/src/components/otp-input/otp-input.tsx @@ -12,6 +12,7 @@ type OTPInputProps = { disabled?: boolean; handleReset: () => void; className?: string; + isVerified?: boolean; }; export const isOTPCodeType = (arg: string[]): arg is OTPCodeType => { @@ -30,6 +31,7 @@ export const OTPInput: React.FC = ({ setErrorText, handleReset, className, + isVerified, }) => { const [autoComplete, setAutoComplete] = useState(""); const [activeElement, setActiveElement] = useState(0); @@ -140,9 +142,17 @@ export const OTPInput: React.FC = ({
{initialOTPValue.map((_, i) => ( (refs.current[i] = el)} tabIndex={i + 1} type="text" diff --git a/account-kit/react/src/strings.ts b/account-kit/react/src/strings.ts index a5680833bf..b37469d59d 100644 --- a/account-kit/react/src/strings.ts +++ b/account-kit/react/src/strings.ts @@ -35,6 +35,8 @@ const STRINGS = { body: "We sent a verification code to", notReceived: "Didn't receive code?", resend: "Resend", + verifying: "Verifying...", + verified: "Verified!", }, completingEmail: { body: "Completing login. Please wait a few seconds for this to screen to update.", From a99057b6edc5c0d3e89763bd35b8337c778fdb67 Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Wed, 18 Dec 2024 21:52:06 -0600 Subject: [PATCH 08/10] fix: using enum instead of strings for auth step types --- .../src/components/auth/card/add-passkey.tsx | 12 ++--- .../react/src/components/auth/card/eoa.tsx | 28 ++++++----- .../auth/card/footer/email-not-reveived.tsx | 10 ++-- .../react/src/components/auth/card/index.tsx | 50 +++++++++---------- .../components/auth/card/loading/email.tsx | 8 +-- .../components/auth/card/loading/oauth.tsx | 14 ++++-- .../auth/card/loading/otp.stories.tsx | 6 +-- .../src/components/auth/card/loading/otp.tsx | 6 +-- .../components/auth/card/loading/passkey.tsx | 10 ++-- .../components/auth/card/passkey-added.tsx | 4 +- .../components/auth/card/passkey.stories.tsx | 4 +- .../react/src/components/auth/card/steps.tsx | 26 +++++----- .../react/src/components/auth/context.ts | 39 ++++++++++----- .../components/auth/hooks/useConnectEOA.ts | 12 ++--- .../components/auth/hooks/useOAuthVerify.ts | 8 +-- .../components/auth/hooks/usePasskeyVerify.ts | 8 +-- .../react/src/components/auth/modal.tsx | 7 +-- .../components/auth/sections/EmailAuth.tsx | 15 +++--- .../src/components/auth/sections/Footer.tsx | 27 +++++----- .../auth/sections/InjectedProvidersAuth.tsx | 4 +- account-kit/react/src/context.tsx | 14 ++++-- 21 files changed, 175 insertions(+), 137 deletions(-) diff --git a/account-kit/react/src/components/auth/card/add-passkey.tsx b/account-kit/react/src/components/auth/card/add-passkey.tsx index 6de8a97b7a..3bfd7bc781 100644 --- a/account-kit/react/src/components/auth/card/add-passkey.tsx +++ b/account-kit/react/src/components/auth/card/add-passkey.tsx @@ -7,7 +7,7 @@ import { import { ReactLogger } from "../../../metrics.js"; import { ls } from "../../../strings.js"; import { Button } from "../../button.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import { ConnectionError } from "./error/connection-error.js"; import { ConnectionFailed as PasskeyConnectionFailed } from "../../../icons/connectionFailed.js"; @@ -25,18 +25,18 @@ const BENEFITS = [ ]; export const AddPasskey = () => { - const { setAuthStep, authStep } = useAuthContext("passkey_create"); + const { setAuthStep, authStep } = useAuthContext(AuthStepType.passkey_create); const { addPasskey, isAddingPasskey } = useAddPasskey({ onSuccess: () => { ReactLogger.trackEvent({ name: "add_passkey_on_signup_success", }); - setAuthStep({ type: "passkey_create_success" }); + setAuthStep({ type: AuthStepType.passkey_create_success }); }, onError: () => { setAuthStep({ - type: "passkey_create", + type: AuthStepType.passkey_create, error: new Error("Failed to add passkey"), }); }, @@ -50,7 +50,7 @@ export const AddPasskey = () => { icon={} shouldDisconnect={false} handleTryAgain={addPasskey} - handleSkip={() => setAuthStep({ type: "complete" })} + handleSkip={() => setAuthStep({ type: AuthStepType.complete })} /> ); } @@ -91,7 +91,7 @@ export const AddPasskey = () => { ReactLogger.trackEvent({ name: "add_passkey_on_signup_skip", }); - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }} disabled={isAddingPasskey} > diff --git a/account-kit/react/src/components/auth/card/eoa.tsx b/account-kit/react/src/components/auth/card/eoa.tsx index 565d8fe8fd..babc7a3f8f 100644 --- a/account-kit/react/src/components/auth/card/eoa.tsx +++ b/account-kit/react/src/components/auth/card/eoa.tsx @@ -4,7 +4,7 @@ import { Spinner } from "../../../icons/spinner.js"; import { WalletConnectIcon } from "../../../icons/walletConnectIcon.js"; import { ls } from "../../../strings.js"; import { Button } from "../../button.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import { useConnectEOA } from "../hooks/useConnectEOA.js"; import { useWalletConnectAuthConfig } from "../hooks/useWalletConnectAuthConfig.js"; import { CardContent } from "./content.js"; @@ -14,7 +14,7 @@ import { WalletIcon } from "./error/icons/wallet-icon.js"; export const WALLET_CONNECT = "walletConnect"; export const EoaConnectCard = () => { - const { setAuthStep, authStep } = useAuthContext("eoa_connect"); + const { setAuthStep, authStep } = useAuthContext(AuthStepType.eoa_connect); const { connect } = useConnectEOA(); const { chain } = useChain(); @@ -31,7 +31,7 @@ export const EoaConnectCard = () => { tryAgainCTA={errorMessage.tryAgainCTA} handleTryAgain={() => { setAuthStep({ - type: "eoa_connect", + type: AuthStepType.eoa_connect, connector: authStep.connector, }); @@ -41,7 +41,9 @@ export const EoaConnectCard = () => { chainId: chain.id, }); }} - handleUseAnotherMethod={() => setAuthStep({ type: "pick_eoa" })} + handleUseAnotherMethod={() => + setAuthStep({ type: AuthStepType.pick_eoa }) + } /> ); } @@ -69,7 +71,7 @@ export const EoaConnectCard = () => { secondaryButton={{ title: "Cancel", onClick: async () => { - setAuthStep({ type: "initial" }); + setAuthStep({ type: AuthStepType.initial }); }, }} /> @@ -77,7 +79,7 @@ export const EoaConnectCard = () => { }; export const WalletConnectCard = () => { - const { setAuthStep, authStep } = useAuthContext("wallet_connect"); + const { setAuthStep, authStep } = useAuthContext(AuthStepType.wallet_connect); const { walletConnectParams } = useWalletConnectAuthConfig(); const { chain } = useChain(); @@ -89,7 +91,7 @@ export const WalletConnectCard = () => { if (!walletConnectConnector) { setAuthStep({ - type: "wallet_connect", + type: AuthStepType.wallet_connect, error: new Error("WalletConnect params not found"), }); @@ -106,14 +108,16 @@ export const WalletConnectCard = () => { tryAgainCTA={errorMessage.tryAgainCTA} icon={} handleTryAgain={() => { - setAuthStep({ type: "wallet_connect" }); + setAuthStep({ type: AuthStepType.wallet_connect }); // Re-try wallet connect's connection... connect({ connector: walletConnectConnector, chainId: chain.id, }); }} - handleUseAnotherMethod={() => setAuthStep({ type: "pick_eoa" })} + handleUseAnotherMethod={() => + setAuthStep({ type: AuthStepType.pick_eoa }) + } /> ); } @@ -141,7 +145,7 @@ export const WalletConnectCard = () => { title: "Cancel", onClick: async () => { // Ensure to stop all inflight requests - setAuthStep({ type: "initial" }); + setAuthStep({ type: AuthStepType.initial }); }, }} /> @@ -151,7 +155,7 @@ export const WalletConnectCard = () => { export const EoaPickCard = () => { const { chain } = useChain(); const { connectors, connect } = useConnectEOA(); - const { setAuthStep } = useAuthContext("pick_eoa"); + const { setAuthStep } = useAuthContext(AuthStepType.pick_eoa); const { walletConnectParams } = useWalletConnectAuthConfig(); @@ -203,7 +207,7 @@ export const EoaPickCard = () => { // If walletConnectConnector is not found, set the error and return if (!walletConnectConnector) { return setAuthStep({ - type: "wallet_connect", + type: AuthStepType.wallet_connect, error: new Error("WalletConnect params not found"), }); } diff --git a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx index 2bcae57487..8acb012dbf 100644 --- a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx +++ b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx @@ -3,13 +3,17 @@ import { useAuthenticate } from "../../../../hooks/useAuthenticate.js"; import { ls } from "../../../../strings.js"; import { AuthStepStatus, + AuthStepType, useAuthContext, type AuthStep, } from "../../context.js"; import { Button } from "../../../button.js"; type EmailNotReceivedDisclaimerProps = { - authStep: Extract; + authStep: Extract< + AuthStep, + { type: AuthStepType.email_verify | AuthStepType.otp_verify } + >; }; export const EmailNotReceivedDisclaimer = ({ authStep, @@ -18,13 +22,13 @@ export const EmailNotReceivedDisclaimer = ({ const [emailResent, setEmailResent] = useState(false); const { authenticate } = useAuthenticate({ onSuccess: () => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, }); const isOTPVerifying = useMemo(() => { return ( - authStep.type === "otp_verify" && + authStep.type === AuthStepType.otp_verify && (authStep.status === AuthStepStatus.verifying || authStep.status === AuthStepStatus.success) ); diff --git a/account-kit/react/src/components/auth/card/index.tsx b/account-kit/react/src/components/auth/card/index.tsx index 2fbc949874..a2b2230995 100644 --- a/account-kit/react/src/components/auth/card/index.tsx +++ b/account-kit/react/src/components/auth/card/index.tsx @@ -14,7 +14,7 @@ import { useAuthModal } from "../../../hooks/useAuthModal.js"; import { useElementHeight } from "../../../hooks/useElementHeight.js"; import { useSignerStatus } from "../../../hooks/useSignerStatus.js"; import { Navigation } from "../../navigation.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import { Footer } from "../sections/Footer.js"; import { Step } from "./steps.js"; export type AuthCardProps = { @@ -72,34 +72,34 @@ export const AuthCardContent = ({ const canGoBack = useMemo(() => { return [ - "email_verify", - "otp_verify", - "passkey_verify", - "passkey_create", - "pick_eoa", - "wallet_connect", - "eoa_connect", - "oauth_completing", + AuthStepType.email_verify, + AuthStepType.otp_verify, + AuthStepType.passkey_verify, + AuthStepType.passkey_create, + AuthStepType.pick_eoa, + AuthStepType.wallet_connect, + AuthStepType.eoa_connect, + AuthStepType.oauth_completing, ].includes(authStep.type); }, [authStep]); const onBack = useCallback(() => { switch (authStep.type) { - case "email_verify": - case "otp_verify": - case "passkey_verify": - case "passkey_create": - case "oauth_completing": + case AuthStepType.email_verify: + case AuthStepType.otp_verify: + case AuthStepType.passkey_verify: + case AuthStepType.passkey_create: + case AuthStepType.oauth_completing: disconnect(config); // Terminate any inflight authentication didGoBack.current = true; - setAuthStep({ type: "initial" }); + setAuthStep({ type: AuthStepType.initial }); break; - case "wallet_connect": - case "eoa_connect": - setAuthStep({ type: "pick_eoa" }); + case AuthStepType.wallet_connect: + case AuthStepType.eoa_connect: + setAuthStep({ type: AuthStepType.pick_eoa }); break; - case "pick_eoa": - setAuthStep({ type: "initial" }); + case AuthStepType.pick_eoa: + setAuthStep({ type: AuthStepType.initial }); break; default: console.warn("Unhandled back action for auth step", authStep); @@ -112,20 +112,20 @@ export const AuthCardContent = ({ disconnect(config); } - if (authStep.type === "passkey_create") { - setAuthStep({ type: "complete" }); + if (authStep.type === AuthStepType.passkey_create) { + setAuthStep({ type: AuthStepType.complete }); } else { - setAuthStep({ type: "initial" }); + setAuthStep({ type: AuthStepType.initial }); } closeAuthModal(); }, [isConnected, authStep.type, closeAuthModal, config, setAuthStep]); useEffect(() => { - if (authStep.type === "complete") { + if (authStep.type === AuthStepType.complete) { didGoBack.current = false; closeAuthModal(); onAuthSuccess?.(); - } else if (authStep.type !== "initial") { + } else if (authStep.type !== AuthStepType.initial) { didGoBack.current = false; } }, [ diff --git a/account-kit/react/src/components/auth/card/loading/email.tsx b/account-kit/react/src/components/auth/card/loading/email.tsx index f0226f3ff2..559422304a 100644 --- a/account-kit/react/src/components/auth/card/loading/email.tsx +++ b/account-kit/react/src/components/auth/card/loading/email.tsx @@ -3,11 +3,11 @@ import { useSignerStatus } from "../../../../hooks/useSignerStatus.js"; import { EmailIllustration } from "../../../../icons/illustrations/email.js"; import { Spinner } from "../../../../icons/spinner.js"; import { ls } from "../../../../strings.js"; -import { useAuthContext } from "../../context.js"; +import { AuthStepType, useAuthContext } from "../../context.js"; // eslint-disable-next-line jsdoc/require-jsdoc export const LoadingEmail = () => { - const { authStep } = useAuthContext("email_verify"); + const { authStep } = useAuthContext(AuthStepType.email_verify); // yup, re-sent and resent. I'm not fixing it const [emailResent, setEmailResent] = useState(false); @@ -39,11 +39,11 @@ export const LoadingEmail = () => { // eslint-disable-next-line jsdoc/require-jsdoc export const CompletingEmailAuth = () => { const { isConnected } = useSignerStatus(); - const { setAuthStep } = useAuthContext("email_completing"); + const { setAuthStep } = useAuthContext(AuthStepType.email_completing); useEffect(() => { if (isConnected) { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); } }, [isConnected, setAuthStep]); diff --git a/account-kit/react/src/components/auth/card/loading/oauth.tsx b/account-kit/react/src/components/auth/card/loading/oauth.tsx index 689901d7e5..0b5b5e3e1e 100644 --- a/account-kit/react/src/components/auth/card/loading/oauth.tsx +++ b/account-kit/react/src/components/auth/card/loading/oauth.tsx @@ -6,22 +6,24 @@ import { OAuthConnectionFailed, } from "../../../../icons/oauth.js"; import { capitalize } from "../../../../utils.js"; -import { useAuthContext } from "../../context.js"; +import { AuthStepType, useAuthContext } from "../../context.js"; import { useOAuthVerify } from "../../hooks/useOAuthVerify.js"; import { ConnectionError } from "../error/connection-error.js"; import { ls } from "../../../../strings.js"; export const CompletingOAuth = () => { const { isConnected } = useSignerStatus(); - const { setAuthStep, authStep } = useAuthContext("oauth_completing"); + const { setAuthStep, authStep } = useAuthContext( + AuthStepType.oauth_completing + ); const { authenticate } = useOAuthVerify({ config: authStep.config }); const oauthWasCancelled = authStep.error instanceof OauthCancelledError; useEffect(() => { if (isConnected) { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); } else if (oauthWasCancelled) { - setAuthStep({ type: "initial" }); + setAuthStep({ type: AuthStepType.initial }); } }, [isConnected, oauthWasCancelled, setAuthStep]); @@ -33,7 +35,9 @@ export const CompletingOAuth = () => { )}`} bodyText={ls.error.connection.oauthBody} handleTryAgain={authenticate} - handleUseAnotherMethod={() => setAuthStep({ type: "initial" })} + handleUseAnotherMethod={() => + setAuthStep({ type: AuthStepType.initial }) + } icon={ } diff --git a/account-kit/react/src/components/auth/card/loading/otp.stories.tsx b/account-kit/react/src/components/auth/card/loading/otp.stories.tsx index 5265359e41..d8e1074fdb 100644 --- a/account-kit/react/src/components/auth/card/loading/otp.stories.tsx +++ b/account-kit/react/src/components/auth/card/loading/otp.stories.tsx @@ -1,6 +1,6 @@ /* eslint-disable react-hooks/rules-of-hooks */ import { useEffect } from "react"; -import { useAuthContext } from "../../context.js"; +import { AuthStepType, useAuthContext } from "../../context.js"; import { LoadingOtp } from "./otp.js"; import type { Meta, StoryObj } from "@storybook/react"; @@ -12,9 +12,9 @@ const meta: Meta = { render: () => { const { authStep, setAuthStep } = useAuthContext(); useEffect(() => { - setAuthStep({ type: "otp_verify", email: "test@alchemy.com" }); + setAuthStep({ type: AuthStepType.otp_verify, email: "test@alchemy.com" }); }, [setAuthStep]); - if (authStep.type === "otp_verify") { + if (authStep.type === AuthStepType.otp_verify) { return ; } diff --git a/account-kit/react/src/components/auth/card/loading/otp.tsx b/account-kit/react/src/components/auth/card/loading/otp.tsx index 6ac9aa4b71..eb7f30dcfe 100644 --- a/account-kit/react/src/components/auth/card/loading/otp.tsx +++ b/account-kit/react/src/components/auth/card/loading/otp.tsx @@ -8,13 +8,13 @@ import { isOTPCodeType, } from "../../../otp-input/otp-input.js"; import { Spinner } from "../../../../icons/spinner.js"; -import { AuthStepStatus, useAuthContext } from "../../context.js"; +import { AuthStepStatus, AuthStepType, useAuthContext } from "../../context.js"; import { useAuthenticate } from "../../../../hooks/useAuthenticate.js"; import { useSignerStatus } from "../../../../hooks/useSignerStatus.js"; export const LoadingOtp = () => { const { isConnected } = useSignerStatus(); - const { authStep } = useAuthContext("otp_verify"); + const { authStep } = useAuthContext(AuthStepType.otp_verify); const [otpCode, setOtpCode] = useState(initialOTPValue); const [errorText, setErrorText] = useState(authStep.error?.message || ""); const [titleText, setTitleText] = useState(ls.loadingOtp.title); @@ -39,7 +39,7 @@ export const LoadingOtp = () => { setAuthStep({ ...authStep, status: AuthStepStatus.success }); setTitleText(ls.loadingOtp.verified); setTimeout(() => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, 3000); } }, diff --git a/account-kit/react/src/components/auth/card/loading/passkey.tsx b/account-kit/react/src/components/auth/card/loading/passkey.tsx index c1f46842f0..4453fff286 100644 --- a/account-kit/react/src/components/auth/card/loading/passkey.tsx +++ b/account-kit/react/src/components/auth/card/loading/passkey.tsx @@ -1,12 +1,12 @@ import { ConnectionFailed } from "../../../../icons/connectionFailed.js"; import { LoadingPasskey } from "../../../../icons/passkey.js"; import { ls } from "../../../../strings.js"; -import { useAuthContext } from "../../context.js"; +import { AuthStepType, useAuthContext } from "../../context.js"; import { usePasskeyVerify } from "../../hooks/usePasskeyVerify.js"; import { ConnectionError } from "../error/connection-error.js"; export const LoadingPasskeyAuth = () => { - const { setAuthStep, authStep } = useAuthContext("passkey_verify"); + const { setAuthStep, authStep } = useAuthContext(AuthStepType.passkey_verify); const { authenticate } = usePasskeyVerify(); if (authStep.error) { @@ -16,7 +16,9 @@ export const LoadingPasskeyAuth = () => { bodyText={ls.error.connection.passkeyBody} icon={} handleTryAgain={authenticate} - handleUseAnotherMethod={() => setAuthStep({ type: "initial" })} + handleUseAnotherMethod={() => + setAuthStep({ type: AuthStepType.initial }) + } /> ); } @@ -45,7 +47,7 @@ export const LoadingPasskeyAuth = () => {
diff --git a/account-kit/react/src/components/auth/card/passkey-added.tsx b/account-kit/react/src/components/auth/card/passkey-added.tsx index 58207b8523..91d8ae017f 100644 --- a/account-kit/react/src/components/auth/card/passkey-added.tsx +++ b/account-kit/react/src/components/auth/card/passkey-added.tsx @@ -1,12 +1,12 @@ import { AddedPasskeyIllustration } from "../../../icons/illustrations/added-passkey.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; // eslint-disable-next-line jsdoc/require-jsdoc export function PasskeyAdded() { const { setAuthStep } = useAuthContext(); setTimeout(() => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, 5000); return ( diff --git a/account-kit/react/src/components/auth/card/passkey.stories.tsx b/account-kit/react/src/components/auth/card/passkey.stories.tsx index f001eb5e1d..b903ef093a 100644 --- a/account-kit/react/src/components/auth/card/passkey.stories.tsx +++ b/account-kit/react/src/components/auth/card/passkey.stories.tsx @@ -2,7 +2,7 @@ import type { Meta, StoryObj } from "@storybook/react"; import { http, HttpResponse } from "msw"; import { useEffect } from "react"; import { useUiConfig } from "../../../hooks/useUiConfig.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import type { AuthType } from "../types.js"; import { AuthCard } from "./index.jsx"; @@ -44,7 +44,7 @@ const PasskeyStory = (props: any) => { const { setAuthStep } = useAuthContext(); useEffect(() => { - setAuthStep({ type: "passkey_create" }); + setAuthStep({ type: AuthStepType.passkey_create }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); diff --git a/account-kit/react/src/components/auth/card/steps.tsx b/account-kit/react/src/components/auth/card/steps.tsx index ff74b36a6f..7ba056d5c1 100644 --- a/account-kit/react/src/components/auth/card/steps.tsx +++ b/account-kit/react/src/components/auth/card/steps.tsx @@ -1,4 +1,4 @@ -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import { AddPasskey } from "./add-passkey.js"; import { EoaConnectCard, EoaPickCard, WalletConnectCard } from "./eoa.js"; import { CompletingEmailAuth, LoadingEmail } from "./loading/email.js"; @@ -11,28 +11,28 @@ import { LoadingOtp } from "./loading/otp.js"; export const Step = () => { const { authStep } = useAuthContext(); switch (authStep.type) { - case "email_verify": + case AuthStepType.email_verify: return ; - case "otp_verify": + case AuthStepType.otp_verify: return ; - case "passkey_verify": + case AuthStepType.passkey_verify: return ; - case "email_completing": + case AuthStepType.email_completing: return ; - case "oauth_completing": + case AuthStepType.oauth_completing: return ; - case "passkey_create": + case AuthStepType.passkey_create: return ; - case "passkey_create_success": + case AuthStepType.passkey_create_success: return ; - case "eoa_connect": + case AuthStepType.eoa_connect: return ; - case "pick_eoa": + case AuthStepType.pick_eoa: return ; - case "wallet_connect": + case AuthStepType.wallet_connect: return ; - case "complete": - case "initial": + case AuthStepType.complete: + case AuthStepType.initial: default: return ; } diff --git a/account-kit/react/src/components/auth/context.ts b/account-kit/react/src/components/auth/context.ts index e3b14107ee..7f03443109 100644 --- a/account-kit/react/src/components/auth/context.ts +++ b/account-kit/react/src/components/auth/context.ts @@ -4,6 +4,21 @@ import type { Connector } from "@wagmi/core"; import { createContext, useContext } from "react"; import type { AuthType } from "./types"; +export enum AuthStepType { + email_verify = "email_verify", + otp_verify = "otp_verify", + passkey_verify = "passkey_verify", + passkey_create = "passkey_create", + passkey_create_success = "passkey_create_success", + email_completing = "email_completing", + oauth_completing = "oauth_completing", + initial = "initial", + complete = "complete", + eoa_connect = "eoa_connect", + wallet_connect = "wallet_connect", + pick_eoa = "pick_eoa", +} + export enum AuthStepStatus { success = "success", error = "error", @@ -11,27 +26,27 @@ export enum AuthStepStatus { } export type AuthStep = - | { type: "email_verify"; email: string } + | { type: AuthStepType.email_verify; email: string } | { - type: "otp_verify"; + type: AuthStepType.otp_verify; email: string; error?: Error; status?: AuthStepStatus | null; } - | { type: "passkey_verify"; error?: Error } - | { type: "passkey_create"; error?: Error } - | { type: "passkey_create_success" } - | { type: "email_completing" } + | { type: AuthStepType.passkey_verify; error?: Error } + | { type: AuthStepType.passkey_create; error?: Error } + | { type: AuthStepType.passkey_create_success } + | { type: AuthStepType.email_completing } | { - type: "oauth_completing"; + type: AuthStepType.oauth_completing; config: Extract; error?: Error; } - | { type: "initial"; error?: Error } - | { type: "complete" } - | { type: "eoa_connect"; connector: Connector; error?: Error } - | { type: "wallet_connect"; error?: Error } - | { type: "pick_eoa" }; + | { type: AuthStepType.initial; error?: Error } + | { type: AuthStepType.complete } + | { type: AuthStepType.eoa_connect; connector: Connector; error?: Error } + | { type: AuthStepType.wallet_connect; error?: Error } + | { type: AuthStepType.pick_eoa }; type AuthContextType< TType extends AuthStep["type"] | undefined = AuthStep["type"] | undefined diff --git a/account-kit/react/src/components/auth/hooks/useConnectEOA.ts b/account-kit/react/src/components/auth/hooks/useConnectEOA.ts index 48e8d958c6..e98646543a 100644 --- a/account-kit/react/src/components/auth/hooks/useConnectEOA.ts +++ b/account-kit/react/src/components/auth/hooks/useConnectEOA.ts @@ -1,27 +1,27 @@ "use client"; import { useConnect } from "../../../hooks/useConnect.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; export const useConnectEOA = () => { const { setAuthStep } = useAuthContext(); const { connectors, connect } = useConnect({ onMutate: ({ connector }) => { if (typeof connector === "function") { - setAuthStep({ type: "wallet_connect" }); + setAuthStep({ type: AuthStepType.wallet_connect }); } else { - setAuthStep({ type: "eoa_connect", connector }); + setAuthStep({ type: AuthStepType.eoa_connect, connector }); } }, onError: (error, { connector }) => { if (typeof connector === "function") { - setAuthStep({ type: "wallet_connect", error }); + setAuthStep({ type: AuthStepType.wallet_connect, error }); } else { - setAuthStep({ type: "eoa_connect", connector, error }); + setAuthStep({ type: AuthStepType.eoa_connect, connector, error }); } }, onSuccess: () => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, }); diff --git a/account-kit/react/src/components/auth/hooks/useOAuthVerify.ts b/account-kit/react/src/components/auth/hooks/useOAuthVerify.ts index 3957c14862..c8e59b5fc2 100644 --- a/account-kit/react/src/components/auth/hooks/useOAuthVerify.ts +++ b/account-kit/react/src/components/auth/hooks/useOAuthVerify.ts @@ -1,7 +1,7 @@ "use client"; import { useCallback } from "react"; import { useAuthenticate } from "../../../hooks/useAuthenticate.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import type { AuthType } from "../types.js"; export type UseOAuthVerifyReturnType = { @@ -20,19 +20,19 @@ export const useOAuthVerify = ({ onMutate: () => { setAuthStep({ config, - type: "oauth_completing", + type: AuthStepType.oauth_completing, }); }, onError: (err) => { console.error(err); setAuthStep({ - type: "oauth_completing", + type: AuthStepType.oauth_completing, config, error: err, }); }, onSuccess: () => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, }); diff --git a/account-kit/react/src/components/auth/hooks/usePasskeyVerify.ts b/account-kit/react/src/components/auth/hooks/usePasskeyVerify.ts index ab626254fa..fd295f60a5 100644 --- a/account-kit/react/src/components/auth/hooks/usePasskeyVerify.ts +++ b/account-kit/react/src/components/auth/hooks/usePasskeyVerify.ts @@ -1,6 +1,6 @@ import { useCallback } from "react"; import { useAuthenticate } from "../../../hooks/useAuthenticate.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; export type UsePasskeyVerifyReturnType = { authenticate: () => void; @@ -18,13 +18,13 @@ export const usePasskeyVerify = (): UsePasskeyVerifyReturnType => { const { setAuthStep } = useAuthContext(); const { authenticate: authenticate_, isPending } = useAuthenticate({ onMutate: () => { - setAuthStep({ type: "passkey_verify" }); + setAuthStep({ type: AuthStepType.passkey_verify }); }, onError: (err) => { - setAuthStep({ type: "passkey_verify", error: err }); + setAuthStep({ type: AuthStepType.passkey_verify, error: err }); }, onSuccess: () => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, }); diff --git a/account-kit/react/src/components/auth/modal.tsx b/account-kit/react/src/components/auth/modal.tsx index d60e41d091..bb7047090f 100644 --- a/account-kit/react/src/components/auth/modal.tsx +++ b/account-kit/react/src/components/auth/modal.tsx @@ -5,7 +5,7 @@ import { useUiConfig } from "../../hooks/useUiConfig.js"; import { useSignerStatus } from "../../index.js"; import { Dialog } from "../dialog/dialog.js"; import { AuthCardContent } from "./card/index.js"; -import { useAuthContext } from "./context.js"; +import { AuthStepType, useAuthContext } from "./context.js"; export const AuthModal = () => { const { isConnected } = useSignerStatus(); @@ -23,14 +23,15 @@ export const AuthModal = () => { if (addPasskeyOnSignup) { openAuthModal(); setAuthStep({ - type: "passkey_create", + type: AuthStepType.passkey_create, }); } }, [addPasskeyOnSignup, openAuthModal, setAuthStep]); useNewUserSignup( handleSignup, isConnected && - (authStep.type === "complete" || authStep.type === "initial") && + (authStep.type === AuthStepType.complete || + authStep.type === AuthStepType.initial) && !isOpen ); diff --git a/account-kit/react/src/components/auth/sections/EmailAuth.tsx b/account-kit/react/src/components/auth/sections/EmailAuth.tsx index 8b335bb084..15d35d2d83 100644 --- a/account-kit/react/src/components/auth/sections/EmailAuth.tsx +++ b/account-kit/react/src/components/auth/sections/EmailAuth.tsx @@ -10,7 +10,7 @@ import { ls } from "../../../strings.js"; import { Button } from "../../button.js"; import { IS_SIGNUP_QP } from "../../constants.js"; import { Input } from "../../input.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; import type { AuthType } from "../types.js"; type EmailAuthProps = Extract; @@ -30,18 +30,21 @@ export const EmailAuth = memo( onMutate: async (params) => { if (params.type === "email" && "email" in params) { if (params.emailMode === "magicLink") { - setAuthStep({ type: "email_verify", email: params.email }); + setAuthStep({ + type: AuthStepType.email_verify, + email: params.email, + }); } else { - setAuthStep({ type: "otp_verify", email: params.email }); + setAuthStep({ type: AuthStepType.otp_verify, email: params.email }); } } }, onSuccess: () => { - setAuthStep({ type: "complete" }); + setAuthStep({ type: AuthStepType.complete }); }, onError: (error) => { console.error(error); - setAuthStep({ type: "initial", error }); + setAuthStep({ type: AuthStepType.initial, error }); }, }); @@ -67,7 +70,7 @@ export const EmailAuth = memo( } catch (e) { const error = e instanceof Error ? e : new Error("An Unknown error"); - setAuthStep({ type: "initial", error }); + setAuthStep({ type: AuthStepType.initial, error }); } }, validatorAdapter: zodValidator(), diff --git a/account-kit/react/src/components/auth/sections/Footer.tsx b/account-kit/react/src/components/auth/sections/Footer.tsx index 302a30b428..703fb14df2 100644 --- a/account-kit/react/src/components/auth/sections/Footer.tsx +++ b/account-kit/react/src/components/auth/sections/Footer.tsx @@ -3,7 +3,7 @@ import { HelpText } from "../card/footer/help-text.js"; import { OAuthContactSupport } from "../card/footer/oauth-contact-support.js"; import { ProtectedBy } from "../card/footer/protected-by.js"; import { RegistrationDisclaimer } from "../card/footer/registration-disclaimer.js"; -import type { AuthStep } from "../context.js"; +import { AuthStepType, type AuthStep } from "../context.js"; type FooterProps = { authStep: AuthStep; @@ -11,22 +11,23 @@ type FooterProps = { const RenderFooterText = ({ authStep }: FooterProps) => { switch (authStep.type) { - case "initial": + case AuthStepType.initial: return ; - case "email_verify": - case "otp_verify": + case AuthStepType.email_verify: + case AuthStepType.otp_verify: return ; - case "passkey_create": - case "wallet_connect": - case "passkey_verify": + case AuthStepType.passkey_create: + case AuthStepType.wallet_connect: + case AuthStepType.passkey_verify: return ; - case "oauth_completing": + case AuthStepType.oauth_completing: return ; - case "email_completing": - case "passkey_create_success": - case "eoa_connect": - case "pick_eoa": - case "complete": + case AuthStepType.email_completing: + case AuthStepType.passkey_create_success: + case AuthStepType.eoa_connect: + case AuthStepType.pick_eoa: + case AuthStepType.complete: + default: return null; } }; diff --git a/account-kit/react/src/components/auth/sections/InjectedProvidersAuth.tsx b/account-kit/react/src/components/auth/sections/InjectedProvidersAuth.tsx index f5ae8870d2..03ff91f26c 100644 --- a/account-kit/react/src/components/auth/sections/InjectedProvidersAuth.tsx +++ b/account-kit/react/src/components/auth/sections/InjectedProvidersAuth.tsx @@ -1,6 +1,6 @@ import { WalletIcon } from "../../../icons/wallet.js"; import { Button } from "../../button.js"; -import { useAuthContext } from "../context.js"; +import { AuthStepType, useAuthContext } from "../context.js"; export const ExternalWalletsAuth = () => { const { setAuthStep } = useAuthContext(); @@ -9,7 +9,7 @@ export const ExternalWalletsAuth = () => { diff --git a/account-kit/react/src/context.tsx b/account-kit/react/src/context.tsx index 63315b6871..a7a88f7914 100644 --- a/account-kit/react/src/context.tsx +++ b/account-kit/react/src/context.tsx @@ -14,7 +14,11 @@ import { useMemo, useState, } from "react"; -import { AuthModalContext, type AuthStep } from "./components/auth/context.js"; +import { + AuthModalContext, + AuthStepType, + type AuthStep, +} from "./components/auth/context.js"; import { AuthModal } from "./components/auth/modal.js"; import { IS_SIGNUP_QP } from "./components/constants.js"; import type { AlchemyAccountsConfigWithUI } from "./createConfig.js"; @@ -115,7 +119,7 @@ export const AlchemyAccountProvider = ( * Reset the auth step to the initial state. This also clears the email auth query params from the URL. */ const resetAuthStep = useCallback(() => { - setAuthStep({ type: "initial" }); + setAuthStep({ type: AuthStepType.initial }); clearSignupParam(); }, []); @@ -133,17 +137,17 @@ export const AlchemyAccountProvider = ( const [authStep, setAuthStep] = useState(() => { if (status === AlchemySignerStatus.AUTHENTICATING_EMAIL) { return { - type: "email_completing", + type: AuthStepType.email_completing, }; } return { - type: "initial", + type: AuthStepType.initial, }; }); useEffect(() => { - if (authStep.type === "complete") { + if (authStep.type === AuthStepType.complete) { clearSignupParam(); } }, [authStep]); From 3c1b585be0f13ff7220dfee90be4bd738b63bddf Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Fri, 20 Dec 2024 12:29:42 -0600 Subject: [PATCH 09/10] fix: adding color to theme --- account-kit/react/src/tailwind/theme.ts | 1 + account-kit/react/src/tailwind/types.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/account-kit/react/src/tailwind/theme.ts b/account-kit/react/src/tailwind/theme.ts index d329d20961..7c77e66ec9 100644 --- a/account-kit/react/src/tailwind/theme.ts +++ b/account-kit/react/src/tailwind/theme.ts @@ -26,6 +26,7 @@ export function createDefaultTheme(): AccountKitTheme { "fg-disabled": createColorSet("#CBD5E1", "#475569"), "fg-accent-brand": createColorSet("#E82594", "#FF66CC"), "fg-critical": createColorSet("#B91C1C", "#F87171"), + "fg-success": createColorSet("#16A34A", "#86EFAC"), // surface colors "bg-surface-default": createColorSet("#fff", "#020617"), diff --git a/account-kit/react/src/tailwind/types.ts b/account-kit/react/src/tailwind/types.ts index 0f65307bf1..03b2572d8e 100644 --- a/account-kit/react/src/tailwind/types.ts +++ b/account-kit/react/src/tailwind/types.ts @@ -22,6 +22,7 @@ export interface AccountKitTheme { "fg-disabled": ColorVariantRecord; "fg-accent-brand": ColorVariantRecord; "fg-critical": ColorVariantRecord; + "fg-success": ColorVariantRecord; // surface colors "bg-surface-default": ColorVariantRecord; From 0782fa5e5017ef023c8b943eec22a4cc331754af Mon Sep 17 00:00:00 2001 From: Caleb Briancesco Date: Mon, 13 Jan 2025 10:37:45 -0600 Subject: [PATCH 10/10] fix: adding pr feedback --- .../auth/card/footer/email-not-reveived.tsx | 5 +++-- .../react/src/components/auth/card/loading/otp.tsx | 11 +++++------ account-kit/react/src/components/auth/context.ts | 3 ++- .../react/src/components/otp-input/otp-input.tsx | 11 ++++++----- 4 files changed, 16 insertions(+), 14 deletions(-) diff --git a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx index 2bcae57487..841cfc07c5 100644 --- a/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx +++ b/account-kit/react/src/components/auth/card/footer/email-not-reveived.tsx @@ -51,9 +51,10 @@ export const EmailNotReceivedDisclaimer = ({