From e4aae4972cf3a1613252b437154cd32bd731d4f8 Mon Sep 17 00:00:00 2001
From: Robinnnnn <rokim8@gmail.com>
Date: Thu, 18 Apr 2024 15:03:42 -0400
Subject: [PATCH] improve privy wallet creation

---
 .../multichain/MultichainWalletSelector.tsx   |  5 +-
 apps/web/src/contexts/AppProvider.tsx         |  6 ++
 apps/web/src/hooks/useUniversalAuthModal.tsx  | 74 ++++++++++---------
 3 files changed, 48 insertions(+), 37 deletions(-)

diff --git a/apps/web/src/components/WalletSelector/multichain/MultichainWalletSelector.tsx b/apps/web/src/components/WalletSelector/multichain/MultichainWalletSelector.tsx
index da032a91c..b2a9c1a0d 100644
--- a/apps/web/src/components/WalletSelector/multichain/MultichainWalletSelector.tsx
+++ b/apps/web/src/components/WalletSelector/multichain/MultichainWalletSelector.tsx
@@ -47,7 +47,6 @@ export default function MultichainWalletSelector({
     graphql`
       fragment MultichainWalletSelectorFragment on Query {
         ...EthereumAddWalletFragment
-        ...GnosisSafeAddWalletFragment
         ...TezosAddWalletFragment
       }
     `,
@@ -138,13 +137,11 @@ export default function MultichainWalletSelector({
   if (selectedAuthMethod === supportedAuthMethods.delegateCash) {
     return (
       <WalletSelectorWrapper>
-        <DelegateCashMessage reset={reset} />
+        <DelegateCashMessage />
       </WalletSelectorWrapper>
     );
   }
 
-  console.log({ selectedAuthMethod });
-
   return (
     <WalletSelectorWrapper gap={24}>
       <VStack gap={16}>
diff --git a/apps/web/src/contexts/AppProvider.tsx b/apps/web/src/contexts/AppProvider.tsx
index de453b0d9..7e3bfcf95 100644
--- a/apps/web/src/contexts/AppProvider.tsx
+++ b/apps/web/src/contexts/AppProvider.tsx
@@ -39,6 +39,12 @@ const isProd = isProduction();
 
 const privyConfig: PrivyClientConfig = {
   loginMethods: ['email'],
+  embeddedWallets: {
+    // automatically generate embedded wallets for new users signing up with privy emails.
+    // this will not apply to users signing up with farcaster or wallet extensions, since
+    // those methods already come with a wallet.
+    createOnLogin: 'users-without-wallets',
+  },
 };
 
 export default function AppProvider({
diff --git a/apps/web/src/hooks/useUniversalAuthModal.tsx b/apps/web/src/hooks/useUniversalAuthModal.tsx
index 12774e13d..b42e7ddc7 100644
--- a/apps/web/src/hooks/useUniversalAuthModal.tsx
+++ b/apps/web/src/hooks/useUniversalAuthModal.tsx
@@ -1,4 +1,4 @@
-import { useCreateWallet, useLogin, useLogout, useToken } from '@privy-io/react-auth';
+import { useLogin, useLogout, useToken } from '@privy-io/react-auth';
 import { useCallback, useEffect, useMemo, useState } from 'react';
 import { graphql, useFragment, useLazyLoadQuery } from 'react-relay';
 import { useReportError } from 'shared/contexts/ErrorReportingContext';
@@ -8,6 +8,7 @@ import styled from 'styled-components';
 
 import breakpoints from '~/components/core/breakpoints';
 import IconContainer from '~/components/core/IconContainer';
+import Loader from '~/components/core/Loader/Loader';
 import { HStack, VStack } from '~/components/core/Spacer/Stack';
 import { BaseM, TitleS } from '~/components/core/Text/Text';
 import transitions from '~/components/core/transitions';
@@ -122,32 +123,38 @@ function UniversalAuthModal({ queryRef }: UniversalAuthModalProps) {
           </WalletSelectorWrapper>
         )}
 
-        {
-          // if the user selects the `Email` auth method, we want to keep
-          // the current view open, and open the privy modal on top
-          !selectedAuthMethod || isPrivySelectedAuthMethod ? (
-            <WalletSelectorWrapper gap={12}>
-              <Row
-                label="Wallet"
-                disabled={false}
-                onClick={() => setSelectedAuthMethod('Wallet')}
-                icon={<WalletIcon />}
-              />
-              <Row
-                label="Farcaster"
-                disabled={false}
-                onClick={() => setSelectedAuthMethod('Farcaster')}
-                icon={<FarcasterOutlineIcon />}
-              />
-              <Row
-                label="Email"
-                disabled={false}
-                onClick={() => setSelectedAuthMethod('Email')}
-                icon={<EmailIcon />}
-              />
-            </WalletSelectorWrapper>
-          ) : null
-        }
+        {selectedAuthMethod === 'Email' && (
+          // the Privy modal will be displayed over this loader
+          <WalletSelectorWrapper>
+            <LoaderContainer align="center" justify="center" gap={12}>
+              <BaseM>Creating your account</BaseM>
+              <Loader size="small" />
+            </LoaderContainer>
+          </WalletSelectorWrapper>
+        )}
+
+        {selectedAuthMethod ? null : (
+          <WalletSelectorWrapper gap={12}>
+            <Row
+              label="Wallet"
+              disabled={false}
+              onClick={() => setSelectedAuthMethod('Wallet')}
+              icon={<WalletIcon />}
+            />
+            <Row
+              label="Farcaster"
+              disabled={false}
+              onClick={() => setSelectedAuthMethod('Farcaster')}
+              icon={<FarcasterOutlineIcon />}
+            />
+            <Row
+              label="Email"
+              disabled={false}
+              onClick={() => setSelectedAuthMethod('Email')}
+              icon={<EmailIcon />}
+            />
+          </WalletSelectorWrapper>
+        )}
       </Container>
     </VStack>
   );
@@ -180,6 +187,10 @@ const WalletContainer = styled(VStack)`
   }
 `;
 
+const LoaderContainer = styled(VStack)`
+  min-height: 200px;
+`;
+
 type RowProps = {
   label: string;
   disabled: boolean;
@@ -244,8 +255,6 @@ function usePrivyGalleryLogin({ selectedAuthMethod, onExitPrivyModal }: usePrivy
 
   const { getAccessToken } = useToken();
 
-  const { createWallet: generatePrivyEmbeddedWallet } = useCreateWallet();
-
   const { logout } = useLogout();
 
   const [loginOrRedirectToOnboarding] = useLoginOrRedirectToOnboarding();
@@ -272,16 +281,15 @@ function usePrivyGalleryLogin({ selectedAuthMethod, onExitPrivyModal }: usePrivy
           userExists: true,
         });
       } catch (error) {
-        console.log('the error onComplete', error);
         if (error instanceof LoginError) {
+          // proceed to onboarding as it means the privy user was not found.
+          // at this point the user should have an embedded wallet created
+          // automatically via `users-without-wallets` config in PrivyProvider
           if (!user.email?.address) {
             reportError('Privy email not found after user login');
             return;
           }
 
-          await generatePrivyEmbeddedWallet();
-
-          // proceed to onboarding as it means the privy user was not found
           await loginOrRedirectToOnboarding({
             authMechanism,
             email: user.email.address,