-
Notifications
You must be signed in to change notification settings - Fork 5
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
Changes from 3 commits
f059f3b
6994d01
0ef933f
062c391
b47e977
42ec23f
59a3759
b80f9e4
cf55389
a10b8ed
eff477e
f07730e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,9 +3,20 @@ import type { ChainWalletBase, WalletModalProps } from 'cosmos-kit'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export enum ModalView { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
WalletList, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -15,6 +26,8 @@ export enum ModalView { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Error, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
NotExist, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Contacts, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
EmailInput, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
SMSInput, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
export const TailwindModal: React.FC< | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -78,17 +91,29 @@ export const TailwindModal: React.FC< | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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')") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setCurrentView(ModalView.QRCode); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setQRWallet(wallet); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -111,6 +136,49 @@ export const TailwindModal: React.FC< | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.log('Setting login hint:', email); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
// Handle the error appropriately in your UI | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
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); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add error handling for email/SMS submission The email and SMS submission logic needs better error handling and user feedback. Add proper error handling and user feedback: onSubmit={async email => {
try {
const emailWallet = walletRepo?.wallets.find(
w => w.walletInfo.prettyName === 'Email'
) as Web3AuthWallet | undefined;
if (emailWallet?.client instanceof Web3AuthClient) {
- console.log('Setting login hint:', email);
+ // Avoid logging sensitive information
emailWallet.client.setLoginHint(email);
await walletRepo?.connect(emailWallet.walletInfo.name);
} else {
- console.error('Email wallet or client not found');
+ throw new Error('Email wallet configuration not found');
}
} catch (error) {
- console.error('Email login error:', error);
+ // Handle specific error types
+ if (error instanceof Error) {
+ // Show user-friendly error message
+ throw new Error(`Failed to login: ${error.message}`);
+ }
}
}}
Comment on lines
+165
to
+181
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 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
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case ModalView.Connected: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
<Connected | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -125,11 +193,11 @@ export const TailwindModal: React.FC< | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
case ModalView.Connecting: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
let subtitle: string; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (currentWalletData!.mode === 'wallet-connect') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (currentWalletData!?.mode === 'wallet-connect') { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
subtitle = `Approve ${currentWalletData!.prettyName} connection request on your mobile.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
subtitle = `Open the ${ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
currentWalletData!.prettyName | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
currentWalletData!?.prettyName | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+196
to
+200
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Replace unsafe non-null assertions The current code uses multiple non-null assertions (!), which could lead to runtime errors if 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
Suggested change
🧰 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 [warning] 138-138: components/react/modal.tsx#L138 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} browser extension to connect your wallet.`; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,7 +43,7 @@ export const Connecting = ({ | |
</div> | ||
<div className="flex flex-col w-full h-full mt-4 sm:px-8 sm:py-6"> | ||
<img | ||
src={getRealLogo(logo)} | ||
src={name === 'Cosmos MetaMask Extension' ? '/metamask.svg' : getRealLogo(logo)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification 🛠️ Refactor suggestion Refactor wallet name comparison for maintainability The string 'Cosmos MetaMask Extension' is used consistently across multiple view components for wallet identification and logo rendering. To improve maintainability, create a new constant in // utils/constants.ts
+ export const WALLET_IDENTIFIERS = {
+ METAMASK: 'Cosmos MetaMask Extension'
+ } as const; Issues found:
Please consolidate these hardcoded values into constants and update all occurrences for better maintainability. 🔗 Analysis chainRefactor wallet name comparison for maintainability The hardcoded string comparison makes the code fragile and harder to maintain. Consider extracting wallet identifiers into constants. + const WALLET_TYPES = {
+ METAMASK: 'Cosmos MetaMask Extension'
+ } as const;
+
export const Connecting = ({
// ...
}) => {
return (
// ...
src={name === WALLET_TYPES.METAMASK ? '/metamask.svg' : getRealLogo(logo)}
// ...
);
}; Additionally, please add test coverage for this new conditional logic. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check if MetaMask logo exists
if [ ! -f "public/metamask.svg" ]; then
echo "Warning: MetaMask logo file not found at public/metamask.svg"
exit 1
fi
# Search for similar hardcoded strings across codebase
rg -l "Cosmos MetaMask Extension"
Length of output: 254 Script: #!/bin/bash
# Let's check how this string is used across files to understand the pattern
rg "Cosmos MetaMask Extension" -A 2 -B 2
# Also check if there are any existing constants for wallet types
rg "const.*WALLET|METAMASK" --type typescript
Length of output: 2892 Script: #!/bin/bash
# Let's check for any existing type definitions or constants in the codebase
rg "type.*Wallet|enum.*Wallet|const.*Wallet|METAMASK" --type ts
# Also check if there's a constants file or types file
fd "constants|types" -e ts -e tsx
Length of output: 2154 Script: #!/bin/bash
# Let's check the content of these files for any existing wallet-related constants
cat utils/constants.ts
cat components/types.tsx
Length of output: 1770 🧰 Tools🪛 GitHub Check: codecov/patch[warning] 46-46: components/react/views/Connecting.tsx#L46 |
||
alt={name} | ||
className="flex-shrink-0 w-20 h-20 mx-auto aspect-1" | ||
/> | ||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,63 @@ | ||||||||||||||||||||||||||||||
import { XMarkIcon, ArrowLeftIcon } from '@heroicons/react/24/outline'; | ||||||||||||||||||||||||||||||
import { Formik, Form } from 'formik'; | ||||||||||||||||||||||||||||||
import * as Yup from 'yup'; | ||||||||||||||||||||||||||||||
import { TextInput } from '../inputs/TextInput'; | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
const validationSchema = Yup.object({ | ||||||||||||||||||||||||||||||
email: Yup.string().email('Invalid email address').required('Email is required'), | ||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
export const EmailInput = ({ | ||||||||||||||||||||||||||||||
onClose, | ||||||||||||||||||||||||||||||
onReturn, | ||||||||||||||||||||||||||||||
onSubmit, | ||||||||||||||||||||||||||||||
}: { | ||||||||||||||||||||||||||||||
onClose: () => void; | ||||||||||||||||||||||||||||||
onReturn: () => void; | ||||||||||||||||||||||||||||||
onSubmit: (email: string) => void; | ||||||||||||||||||||||||||||||
}) => { | ||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||
<div className="p-1 relative max-w-sm mx-auto"> | ||||||||||||||||||||||||||||||
<div className="flex items-center justify-between mb-6"> | ||||||||||||||||||||||||||||||
<button | ||||||||||||||||||||||||||||||
onClick={onReturn} | ||||||||||||||||||||||||||||||
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700" | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
<ArrowLeftIcon className="w-5 h-5" /> | ||||||||||||||||||||||||||||||
</button> | ||||||||||||||||||||||||||||||
<h1 className="text-sm font-semibold">Enter Email</h1> | ||||||||||||||||||||||||||||||
<button | ||||||||||||||||||||||||||||||
onClick={onClose} | ||||||||||||||||||||||||||||||
className="p-2 text-primary bg-neutral rounded-full hover:bg-gray-200 dark:hover:bg-gray-700" | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
<XMarkIcon className="w-5 h-5" /> | ||||||||||||||||||||||||||||||
</button> | ||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
<Formik | ||||||||||||||||||||||||||||||
initialValues={{ email: '' }} | ||||||||||||||||||||||||||||||
validationSchema={validationSchema} | ||||||||||||||||||||||||||||||
onSubmit={values => onSubmit(values.email)} | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
{({ isValid, dirty }) => ( | ||||||||||||||||||||||||||||||
<Form className="space-y-4"> | ||||||||||||||||||||||||||||||
<TextInput | ||||||||||||||||||||||||||||||
name="email" | ||||||||||||||||||||||||||||||
type="email" | ||||||||||||||||||||||||||||||
placeholder="[email protected]" | ||||||||||||||||||||||||||||||
className="w-full p-3 rounded-lg dark:bg-[#ffffff0c] bg-[#f0f0ff5c]" | ||||||||||||||||||||||||||||||
/> | ||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Enhance accessibility for email input. The email input field should have proper accessibility attributes. <TextInput
name="email"
type="email"
+ aria-label="Email address"
+ aria-required="true"
placeholder="[email protected]"
className="w-full p-3 rounded-lg dark:bg-[#ffffff0c] bg-[#f0f0ff5c]"
/> 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
<button | ||||||||||||||||||||||||||||||
type="submit" | ||||||||||||||||||||||||||||||
disabled={!isValid || !dirty} | ||||||||||||||||||||||||||||||
className="w-full p-3 rounded-lg bg-primary text-white disabled:opacity-50 transition" | ||||||||||||||||||||||||||||||
> | ||||||||||||||||||||||||||||||
Continue with Email | ||||||||||||||||||||||||||||||
</button> | ||||||||||||||||||||||||||||||
</Form> | ||||||||||||||||||||||||||||||
)} | ||||||||||||||||||||||||||||||
</Formik> | ||||||||||||||||||||||||||||||
</div> | ||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -45,7 +45,11 @@ export const Error = ({ | |
<div className="flex flex-col w-full h-full py-6 mt-4 sm:px-8"> | ||
<div className="p-3 border rounded-full border-red-600 mx-auto aspect-1 flex-shrink-0"> | ||
<Image | ||
src={getRealLogo(logo)} | ||
src={ | ||
currentWalletName === 'cosmos-extension-metamask' | ||
? '/metamask.svg' | ||
: getRealLogo(logo) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Standardize MetaMask wallet identifier The MetaMask check uses 'cosmos-extension-metamask' while other components use 'Cosmos MetaMask Extension'. This inconsistency could lead to bugs. - currentWalletName === 'cosmos-extension-metamask'
+ currentWalletName === WALLET_TYPES.METAMASK
🧰 Tools🪛 GitHub Check: codecov/patch[warning] 48-52: components/react/views/Error.tsx#L48-L52 |
||
alt="Wallet type logo" | ||
className="flex-shrink-0 w-16 h-16 aspect-1" | ||
width={16} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,7 +28,7 @@ export const NotExist = ({ | |
<ChevronLeftIcon className="w-5 h-5" aria-hidden="true" /> | ||
</button> | ||
<Dialog.Title as="h3" className="text-lg font-semibold"> | ||
{name} | ||
{name === 'Cosmos MetaMask Extension' ? 'Metamask' : name} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Refactor duplicated wallet name checks and logo logic The condition Consider extracting these into shared utilities: + // utils/wallet.ts
+ export const WALLET_TYPES = {
+ METAMASK: 'Cosmos MetaMask Extension'
+ } as const;
+
+ export const getWalletDisplayName = (name: string) => {
+ return name === WALLET_TYPES.METAMASK ? 'Metamask' : name;
+ };
+
+ export const getWalletLogo = (name: string, defaultLogo: string) => {
+ return name === WALLET_TYPES.METAMASK ? '/metamask.svg' : getRealLogo(defaultLogo);
+ };
// In component
- name === 'Cosmos MetaMask Extension' ? 'Metamask' : name
+ getWalletDisplayName(name)
- src={name === 'Cosmos MetaMask Extension' ? '/metamask.svg' : getRealLogo(logo)}
+ src={getWalletLogo(name, logo)} Also applies to: 43-43, 48-48, 51-51, 59-59 🧰 Tools🪛 GitHub Check: codecov/patch[warning] 31-31: components/react/views/NotExist.tsx#L31 💡 Codebase verification Add test coverage for NotExist component's wallet name rendering The verification confirms that:
You should:
🔗 Analysis chainAdd test coverage for wallet name and logo rendering logic The new conditional logic for wallet names and logos lacks test coverage. Would you like me to help generate test cases for the new wallet rendering logic? Also applies to: 43-43, 48-48, 51-51, 59-59 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Check current test coverage for wallet-related components
fd -e test.tsx -e spec.tsx . | xargs rg "describe.*NotExist|test.*MetaMask"
Length of output: 77 Script: #!/bin/bash
# Let's first check if the NotExist component exists and its test files
fd NotExist
# Then let's look for any existing test files in the components directory
fd -e test.tsx -e spec.tsx -e test.ts -e spec.ts components/
# Finally, let's check the content of NotExist.tsx to understand the full context
cat components/react/views/NotExist.tsx
Length of output: 2886 Script: #!/bin/bash
# Let's check for any existing test files in the components directory with correct path
fd -e test.tsx -e spec.tsx -e test.ts -e spec.ts . components
# Let's also check if there are any test files that might test wallet-related functionality
rg -l "wallet.*test|test.*wallet" -g "*.test.*" -g "*.spec.*"
# Let's see if there are any similar components that might have test patterns we can follow
fd -e tsx -e ts . components | rg -i "wallet|connect"
Length of output: 2177 🧰 Tools🪛 GitHub Check: codecov/patch[warning] 31-31: components/react/views/NotExist.tsx#L31 |
||
</Dialog.Title> | ||
<button | ||
type="button" | ||
|
@@ -40,20 +40,23 @@ export const NotExist = ({ | |
</div> | ||
<div className="flex flex-col w-full h-full py-6 mt-4 sm:px-8"> | ||
<img | ||
src={getRealLogo(logo)} | ||
src={name === 'Cosmos MetaMask Extension' ? '/metamask.svg' : getRealLogo(logo)} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification 🛠️ Refactor suggestion Confirmed: Wallet logo logic duplication needs refactoring The verification shows clear evidence of duplicated wallet logo logic across multiple components:
The original review suggestion to extract this logic is valid and would improve code maintainability. 🔗 Analysis chainExtract shared wallet logo logic to avoid duplication The wallet logo rendering logic is duplicated across multiple components. Consider extracting this into a shared utility function. + // utils/wallet.ts
+ export const getWalletLogo = (name: string, defaultLogo: string) => {
+ return name === WALLET_TYPES.METAMASK ? '/metamask.svg' : getRealLogo(defaultLogo);
+ };
// In component
src={getWalletLogo(name, logo)} Please add test coverage for the new logic. Let me check the actual implementation of these files to verify the duplication pattern. Let me try a different approach to verify the pattern. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Find all components using similar wallet logo logic
rg -l "metamask\.svg"
# Check for existing wallet-related utilities
fd -e ts -e tsx -p "wallet.*\.(ts|tsx)$" src utils components
Length of output: 379 Script: #!/bin/bash
# Check the actual implementation of wallet logo logic in all relevant files
rg -A 2 "metamask\.svg" --type tsx
# Check if there's any existing wallet utility functions
ast-grep --pattern 'function $_(name: string, $_) {
$$$
metamask$$$
}'
Length of output: 141 Script: #!/bin/bash
# Check the actual implementation of wallet logo logic in all relevant files
rg -A 2 "metamask\.svg"
# Look for any existing utility functions related to wallet logos
rg "getRealLogo" -A 2
# Check for any constants or types related to wallet names
rg "WALLET_TYPES|WalletType" -A 2
Length of output: 5100 🧰 Tools🪛 GitHub Check: codecov/patch[warning] 43-43: components/react/views/NotExist.tsx#L43 |
||
alt={name} | ||
className="flex-shrink-0 w-16 h-16 mx-auto aspect-1" | ||
/> | ||
<p className="mt-3 font-medium text-black dark:text-white">Install {name}</p> | ||
<p className="mt-3 font-medium text-black dark:text-white"> | ||
Install {name === 'Cosmos MetaMask Extension' ? 'Metamask' : name} | ||
</p> | ||
<p className="mt-1 text-sm text-gray-500 dark:text-white/75"> | ||
To connect your {name} wallet, install the browser extension. | ||
To connect your {name === 'Cosmos MetaMask Extension' ? 'Metamask' : name} wallet, install | ||
the browser extension. | ||
</p> | ||
<button | ||
className={`rounded-lg btn-primary btn btn-md ${name.length >= 12 ? 'w-1/2' : 'w-1/3'} mx-auto inline-flex justify-center items-center py-2.5 font-medium mt-4 text-white`} | ||
onClick={onInstall} | ||
> | ||
<ArrowDownTrayIcon className="flex-shrink-0 w-5 h-5 mr-2 text-white" /> | ||
Install {name} | ||
Install {name === 'Cosmos MetaMask Extension' ? 'Metamask' : name} | ||
</button> | ||
</div> | ||
</div> | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: