Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add email, sms, and metamask extension #148

Merged
merged 12 commits into from
Dec 20, 2024
Merged
Binary file modified bun.lockb
Binary file not shown.
4 changes: 1 addition & 3 deletions components/3js/animatedAsterisk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,9 @@ export default function AnimatedAsterisk({ onLoad }: { onLoad?: () => void }) {
style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}
camera={{ position: [0, 0, 10] }}
>
<ambientLight intensity={0.2} />

<Suspense fallback={null}>
{meshes}
<Environment files="/rosendal_park_sunset_puresky_4k.hdr" background={false} />
<Environment files="/rosendal_park_sunset_puresky_1k.hdr" background={false} />
</Suspense>
</Canvas>
);
Expand Down
4 changes: 1 addition & 3 deletions components/3js/animatedMesh.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,11 +174,9 @@ export default function AnimatedShape({
style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}
camera={{ position: [0, 0, 10] }}
>
<ambientLight intensity={0.2} />

<Suspense fallback={null}>
{meshes}
<Environment files="/rosendal_park_sunset_puresky_4k.hdr" background={false} />
<Environment files="/rosendal_park_sunset_puresky_1k.hdr" background={false} />
<OrbitControls enablePan={false} enableZoom={false} />
</Suspense>
</Canvas>
Expand Down
3 changes: 1 addition & 2 deletions components/3js/pennRoseTriangleScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -148,15 +148,14 @@ function PenroseTriangleScene({ onLoad }: { onLoad: () => void }) {
<CameraSetup />

{/* Lighting */}
<ambientLight intensity={0.5} />

{/* Suspense for async loading */}
<Suspense fallback={null}>
{/* Animated Penrose Triangle */}
<AnimatedPenroseTriangle />

{/* Environment */}
<Environment files="/rosendal_park_sunset_puresky_4k.hdr" background={false} />
<Environment files="/rosendal_park_sunset_puresky_1k.hdr" background={false} />
</Suspense>

{/* Adjust the plane to be closer to the Penrose Triangle */}
Expand Down
2 changes: 0 additions & 2 deletions components/bank/forms/sendForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ export default function SendForm({
amount: [{ denom: values.selectedToken.coreDenom, amount: amountInBaseUnits }],
});

console.log('Estimating fee for address:', address);
const fee = await estimateFee(address, [msg]);

await tx([msg], {
Expand All @@ -150,7 +149,6 @@ export default function SendForm({
});
} catch (error) {
console.error('Error during sending:', error);
// You might want to show this error to the user through a toast or alert
} finally {
setIsSending(false);
}
Expand Down
2 changes: 0 additions & 2 deletions components/groups/modals/memberManagementModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,6 @@ export function MemberManagementModal({
weight: member.markedForDeletion ? '0' : member.weight || '1',
}));

console.log('Member updates:', memberUpdates);

const msg = updateGroupMembers({
admin: groupAdmin,
groupId: BigInt(groupId),
Expand Down
85 changes: 76 additions & 9 deletions components/react/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,20 @@
import { WalletStatus } from 'cosmos-kit';
import React, { useCallback, Fragment, useState, useMemo, useEffect } from 'react';
import { Dialog, Transition, Portal } from '@headlessui/react';
import { Connected, Connecting, Error, NotExist, QRCode, WalletList, Contacts } from './views';
import {
Connected,
Connecting,
Error,
NotExist,
QRCode,
WalletList,
Contacts,
EmailInput,
SMSInput,
} from './views';
import { useRouter } from 'next/router';
import { ToastProvider } from '@/contexts/toastContext';
import { Web3AuthClient, Web3AuthWallet } from '@cosmos-kit/web3auth';
import { useDeviceDetect } from '@/hooks';
export enum ModalView {
WalletList,
Expand All @@ -15,6 +26,8 @@
Error,
NotExist,
Contacts,
EmailInput,
SMSInput,
}

export const TailwindModal: React.FC<
Expand Down Expand Up @@ -79,17 +92,29 @@

const onWalletClicked = useCallback(
(name: string) => {
const wallet = walletRepo?.getWallet(name);
if (wallet?.walletInfo.prettyName === 'Email') {
setCurrentView(ModalView.EmailInput);
return;
}
if (wallet?.walletInfo.prettyName === 'SMS') {
setCurrentView(ModalView.SMSInput);
return;
}
Comment on lines +95 to +103
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Improve error handling for wallet selection

The wallet selection logic needs better error handling for cases where the wallet is undefined.

Apply this diff to add proper error handling:

-      if (wallet?.walletInfo.prettyName === 'Email') {
+      if (!wallet) {
+        console.error('Wallet not found');
+        return;
+      }
+      if (wallet.walletInfo.prettyName === 'Email') {

Committable suggestion skipped: line range outside the PR's diff.


Check warning on line 104 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L95-L104

Added lines #L95 - L104 were not covered by tests
walletRepo?.connect(name);

// 1ms timeout prevents _render from determining the view to show first
setTimeout(() => {
const wallet = walletRepo?.getWallet(name);

if (wallet?.isWalletNotExist) {
if (
wallet?.walletInfo.name === 'cosmos-extension-metamask' &&
wallet.message?.includes("Cannot read properties of undefined (reading 'request')")
) {

Check warning on line 111 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L108-L111

Added lines #L108 - L111 were not covered by tests
setCurrentView(ModalView.NotExist);
setSelectedWallet(wallet);
}
if (wallet?.walletInfo.mode === 'wallet-connect') {
} else if (wallet?.isWalletNotExist) {
setCurrentView(ModalView.NotExist);
setSelectedWallet(wallet);
} else if (wallet?.walletInfo.mode === 'wallet-connect') {

Check warning on line 117 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L114-L117

Added lines #L114 - L117 were not covered by tests
setCurrentView(isMobile ? ModalView.Connecting : ModalView.QRCode);
setQRWallet(wallet);
}
Expand All @@ -112,6 +137,48 @@
wallets={walletRepo?.wallets || []}
/>
);
case ModalView.EmailInput:
return (
<EmailInput
onClose={onCloseModal}
onReturn={() => setCurrentView(ModalView.WalletList)}
onSubmit={async email => {
try {
const emailWallet = walletRepo?.wallets.find(
w => w.walletInfo.prettyName === 'Email'
) as Web3AuthWallet | undefined;

if (emailWallet?.client instanceof Web3AuthClient) {
emailWallet.client.setLoginHint(email);
await walletRepo?.connect(emailWallet.walletInfo.name);
} else {
console.error('Email wallet or client not found');
}
} catch (error) {
console.error('Email login error:', error);

Check warning on line 158 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L140-L158

Added lines #L140 - L158 were not covered by tests
// Handle the error appropriately in your UI
}
}}
/>

Check warning on line 162 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L162

Added line #L162 was not covered by tests
);

case ModalView.SMSInput:
return (
<SMSInput
onClose={onCloseModal}
onReturn={() => setCurrentView(ModalView.WalletList)}
onSubmit={phone => {
const smsWallet = walletRepo?.wallets.find(w => w.walletInfo.prettyName === 'SMS') as
| Web3AuthWallet
| undefined;

if (smsWallet?.client instanceof Web3AuthClient) {
smsWallet.client.setLoginHint(phone);
walletRepo?.connect(smsWallet.walletInfo.name);
}

Check warning on line 178 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L165-L178

Added lines #L165 - L178 were not covered by tests
}}
/>

Check warning on line 180 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L180

Added line #L180 was not covered by tests
);
Comment on lines +165 to +181
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Add error handling and improve type safety in SMS login

The current implementation lacks error handling and proper async/await usage:

-            onSubmit={phone => {
+            onSubmit={async phone => {
+              try {
                 const smsWallet = walletRepo?.wallets.find(
                   w => w.walletInfo.prettyName === 'SMS'
-                ) as Web3AuthWallet | undefined;
+                );
+                
+                if (!smsWallet) {
+                  throw new Error('SMS wallet not found');
+                }
 
-              if (smsWallet?.client instanceof Web3AuthClient) {
+                if (smsWallet.client instanceof Web3AuthClient) {
                   smsWallet.client.setLoginHint(phone);
-                  walletRepo?.connect(smsWallet.walletInfo.name);
+                  await walletRepo?.connect(smsWallet.walletInfo.name);
+                } else {
+                  throw new Error('SMS wallet configuration not found');
+                }
+              } catch (error) {
+                if (error instanceof Error) {
+                  throw new Error(`SMS login failed: ${error.message}`);
+                }
+                throw new Error('An unexpected error occurred');
+              }
             }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
case ModalView.SMSInput:
return (
<SMSInput
onClose={onCloseModal}
onReturn={() => setCurrentView(ModalView.WalletList)}
onSubmit={phone => {
const smsWallet = walletRepo?.wallets.find(w => w.walletInfo.prettyName === 'SMS') as
| Web3AuthWallet
| undefined;
if (smsWallet?.client instanceof Web3AuthClient) {
smsWallet.client.setLoginHint(phone);
walletRepo?.connect(smsWallet.walletInfo.name);
}
}}
/>
);
case ModalView.SMSInput:
return (
<SMSInput
onClose={onCloseModal}
onReturn={() => setCurrentView(ModalView.WalletList)}
onSubmit={async phone => {
try {
const smsWallet = walletRepo?.wallets.find(
w => w.walletInfo.prettyName === 'SMS'
);
if (!smsWallet) {
throw new Error('SMS wallet not found');
}
if (smsWallet.client instanceof Web3AuthClient) {
smsWallet.client.setLoginHint(phone);
await walletRepo?.connect(smsWallet.walletInfo.name);
} else {
throw new Error('SMS wallet configuration not found');
}
} catch (error) {
if (error instanceof Error) {
throw new Error(`SMS login failed: ${error.message}`);
}
throw new Error('An unexpected error occurred');
}
}}
/>
);

case ModalView.Connected:
return (
<Connected
Expand All @@ -126,11 +193,11 @@
);
case ModalView.Connecting:
let subtitle: string;
if (currentWalletData!.mode === 'wallet-connect') {
if (currentWalletData!?.mode === 'wallet-connect') {

Check warning on line 196 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L196

Added line #L196 was not covered by tests
subtitle = `Approve ${currentWalletData!.prettyName} connection request on your mobile.`;
} else {
subtitle = `Open the ${
currentWalletData!.prettyName
currentWalletData!?.prettyName

Check warning on line 200 in components/react/modal.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/modal.tsx#L200

Added line #L200 was not covered by tests
Comment on lines +196 to +200
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Replace unsafe non-null assertions

The current code uses multiple non-null assertions (!), which could lead to runtime errors if currentWalletData is undefined.

Apply this safer approach using optional chaining with fallbacks:

-if (currentWalletData!?.mode === 'wallet-connect') {
-  subtitle = `Approve ${currentWalletData!.prettyName} connection request on your mobile.`;
-} else {
-  subtitle = `Open the ${currentWalletData!?.prettyName} browser extension to connect your wallet.`;
-}
+if (currentWalletData?.mode === 'wallet-connect') {
+  subtitle = `Approve ${currentWalletData.prettyName || 'wallet'} connection request on your mobile.`;
+} else {
+  subtitle = `Open the ${currentWalletData?.prettyName || 'wallet'} browser extension to connect your wallet.`;
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (currentWalletData!?.mode === 'wallet-connect') {
subtitle = `Approve ${currentWalletData!.prettyName} connection request on your mobile.`;
} else {
subtitle = `Open the ${
currentWalletData!.prettyName
currentWalletData!?.prettyName
if (currentWalletData?.mode === 'wallet-connect') {
subtitle = `Approve ${currentWalletData.prettyName || 'wallet'} connection request on your mobile.`;
} else {
subtitle = `Open the ${currentWalletData?.prettyName || 'wallet'} browser extension to connect your wallet.`;
}
🧰 Tools
🪛 Biome (1.9.4)

[error] 134-134: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)


[error] 138-138: Forbidden extra non-null assertion.

Safe fix: Remove extra non-null assertion.

(lint/suspicious/noExtraNonNullAssertion)

🪛 GitHub Check: codecov/patch

[warning] 134-134: components/react/modal.tsx#L134
Added line #L134 was not covered by tests


[warning] 138-138: components/react/modal.tsx#L138
Added line #L138 was not covered by tests

} browser extension to connect your wallet.`;
}

Expand Down
11 changes: 6 additions & 5 deletions components/react/views/Connected.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import Image from 'next/image';
import { MdContacts } from 'react-icons/md';
import { Contacts } from './Contacts';
import { useTheme } from '@/contexts';

export const Connected = ({
onClose,
Expand All @@ -31,7 +30,7 @@
const { balance } = useBalance(address ?? '');
const [copied, setCopied] = useState(false);
const [showContacts, setShowContacts] = useState(false);
const { theme } = useTheme();
const isDarkMode = document.documentElement.classList.contains('dark');

Check warning on line 33 in components/react/views/Connected.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connected.tsx#L33

Added line #L33 was not covered by tests

const copyAddress = () => {
if (address) {
Expand All @@ -50,7 +49,7 @@
<div className="flex justify-between items-center -mt-4 mb-6">
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 52 in components/react/views/Connected.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connected.tsx#L52

Added line #L52 was not covered by tests
onClick={onReturn}
>
<ChevronLeftIcon className="w-5 h-5" aria-hidden="true" />
Expand All @@ -59,7 +58,9 @@
<Image
height={0}
width={0}
src={getRealLogo(logo, theme === 'dark')}
src={
name === 'Cosmos MetaMask Extension' ? '/metamask.svg' : getRealLogo(logo, isDarkMode)
}

Check warning on line 63 in components/react/views/Connected.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connected.tsx#L61-L63

Added lines #L61 - L63 were not covered by tests
alt={name}
className="w-8 h-8 rounded-full mr-2"
/>
Expand All @@ -69,7 +70,7 @@
</div>
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 73 in components/react/views/Connected.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connected.tsx#L73

Added line #L73 was not covered by tests
onClick={onClose}
>
<XMarkIcon className="w-5 h-5" aria-hidden="true" />
Expand Down
10 changes: 7 additions & 3 deletions components/react/views/Connecting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<div className="flex justify-between items-center mb-2">
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 30 in components/react/views/Connecting.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connecting.tsx#L30

Added line #L30 was not covered by tests
onClick={onReturn}
>
<ChevronLeftIcon className="w-5 h-5" aria-hidden="true" />
Expand All @@ -37,15 +37,19 @@
</Dialog.Title>
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 40 in components/react/views/Connecting.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connecting.tsx#L40

Added line #L40 was not covered by tests
onClick={onClose}
>
<XMarkIcon className="w-5 h-5" aria-hidden="true" />
</button>
</div>
<div className="flex flex-col w-full h-full mt-4 sm:px-8 sm:py-6">
<img
src={getRealLogo(logo, theme === 'dark')}
src={
name === 'Cosmos MetaMask Extension'
? '/metamask.svg'
: getRealLogo(logo, theme === 'dark')
}

Check warning on line 52 in components/react/views/Connecting.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Connecting.tsx#L48-L52

Added lines #L48 - L52 were not covered by tests
alt={name}
className="flex-shrink-0 w-20 h-20 mx-auto aspect-1"
/>
Expand Down
12 changes: 6 additions & 6 deletions components/react/views/Contacts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
{onReturn ? (
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 129 in components/react/views/Contacts.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Contacts.tsx#L129

Added line #L129 was not covered by tests
onClick={onReturn}
>
<ChevronLeftIcon className="w-5 h-5" aria-hidden="true" />
Expand All @@ -139,7 +139,7 @@
</Dialog.Title>
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 142 in components/react/views/Contacts.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Contacts.tsx#L142

Added line #L142 was not covered by tests
onClick={onClose}
>
<XMarkIcon className="w-5 h-5" aria-hidden="true" />
Expand Down Expand Up @@ -192,7 +192,7 @@
{onReturn ? (
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 195 in components/react/views/Contacts.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Contacts.tsx#L195

Added line #L195 was not covered by tests
onClick={onReturn}
>
<ChevronLeftIcon className="w-5 h-5" aria-hidden="true" />
Expand All @@ -208,7 +208,7 @@
</div>
<button
type="button"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700"
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033]"

Check warning on line 211 in components/react/views/Contacts.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Contacts.tsx#L211

Added line #L211 was not covered by tests
onClick={onClose}
>
<XMarkIcon className="w-5 h-5" aria-hidden="true" />
Expand Down Expand Up @@ -347,13 +347,13 @@
<div className="flex items-center">
<button
onClick={() => setEditingIndex(index)}
className="ml-2 p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 text-blue-500"
className="ml-2 p-2 rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033] transition-colors duration-200 text-blue-500"

Check warning on line 350 in components/react/views/Contacts.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Contacts.tsx#L350

Added line #L350 was not covered by tests
>
<PencilIcon className="w-5 h-5" aria-hidden="true" />
</button>
<button
onClick={() => handleRemoveContact(index)}
className="ml-2 p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors duration-200 text-red-500"
className="ml-2 p-2 rounded-full hover:bg-gray-200 dark:hover:bg-[#00000033] transition-colors duration-200 text-red-500"

Check warning on line 356 in components/react/views/Contacts.tsx

View check run for this annotation

Codecov / codecov/patch

components/react/views/Contacts.tsx#L356

Added line #L356 was not covered by tests
>
<XMarkIcon className="w-5 h-5" aria-hidden="true" />
</button>
Expand Down
Loading
Loading