import { KeyIcon } from "@heroicons/react/24/outline"; import { HEY_APP, IS_MAINNET } from "@hey/data/constants"; import { ERRORS } from "@hey/data/errors"; import { type ChallengeRequest, ManagedAccountsVisibility, useAccountsAvailableQuery, useAuthenticateMutation, useChallengeMutation } from "@hey/indexer"; import { AnimatePresence, motion } from "motion/react"; import type { Dispatch, SetStateAction } from "react"; import { useCallback, useState } from "react"; import { toast } from "sonner"; import { useAccount, useDisconnect, useSignMessage } from "wagmi"; import SingleAccount from "@/components/Shared/Account/SingleAccount"; import Loader from "@/components/Shared/Loader"; import { Button, Card, ErrorMessage } from "@/components/Shared/UI"; import errorToast from "@/helpers/errorToast"; import reloadAllTabs from "@/helpers/reloadAllTabs"; import { signIn } from "@/store/persisted/useAuthStore"; import { EXPANSION_EASE } from "@/variants"; import SignupCard from "./SignupCard"; import WalletSelector from "./WalletSelector"; interface LoginProps { setHasAccounts: Dispatch>; } const Login = ({ setHasAccounts }: LoginProps) => { const [isSubmitting, setIsSubmitting] = useState(false); const [loggingInAccountId, setLoggingInAccountId] = useState( null ); const [isExpanded, setIsExpanded] = useState(true); const onError = useCallback((error?: any) => { setIsSubmitting(false); setLoggingInAccountId(null); errorToast(error); }, []); const { disconnect } = useDisconnect(); const { address, connector: activeConnector } = useAccount(); const { signMessageAsync } = useSignMessage({ mutation: { onError } }); const [loadChallenge, { error: errorChallenge }] = useChallengeMutation({ onError }); const [authenticate, { error: errorAuthenticate }] = useAuthenticateMutation({ onError }); const { data, loading } = useAccountsAvailableQuery({ onCompleted: (data) => { setHasAccounts(data?.accountsAvailable.items.length > 0); setIsExpanded(true); }, skip: !address, variables: { accountsAvailableRequest: { hiddenFilter: ManagedAccountsVisibility.NoneHidden, managedBy: address }, lastLoggedInAccountRequest: { address } } }); const allAccounts = data?.accountsAvailable.items || []; const lastLogin = data?.lastLoggedInAccount; const remainingAccounts = lastLogin ? allAccounts .filter(({ account }) => account.address !== lastLogin.address) .map(({ account }) => account) : allAccounts.map(({ account }) => account); const accounts = lastLogin ? [lastLogin, ...remainingAccounts] : remainingAccounts; const handleSign = async (account: string) => { const isManager = allAccounts.some( ({ account: a, __typename }) => __typename === "AccountManaged" && a.address === account ); const meta = { account, app: IS_MAINNET ? HEY_APP : undefined }; const request: ChallengeRequest = isManager ? { accountManager: { manager: address, ...meta } } : { accountOwner: { owner: address, ...meta } }; try { setLoggingInAccountId(account || null); setIsSubmitting(true); // Get challenge const challenge = await loadChallenge({ variables: { request } }); if (!challenge?.data?.challenge?.text) { return toast.error(ERRORS.SomethingWentWrong); } // Get signature const signature = await signMessageAsync({ message: challenge?.data?.challenge?.text }); // Auth account const auth = await authenticate({ variables: { request: { id: challenge.data.challenge.id, signature } } }); if (auth.data?.authenticate.__typename === "AuthenticationTokens") { const accessToken = auth.data?.authenticate.accessToken; const refreshToken = auth.data?.authenticate.refreshToken; signIn({ accessToken, refreshToken }); reloadAllTabs(); return; } return onError({ message: ERRORS.SomethingWentWrong }); } catch { onError(); } }; return activeConnector?.id ? (
{errorChallenge || errorAuthenticate ? ( ) : null} {loading ? ( ) : accounts.length > 0 ? ( {isExpanded && ( {accounts.map((account, index) => ( ))} )} ) : ( )}
) : ( ); }; export default Login;