Skip to content

JustaName Integration#563

Closed
Ghadi8 wants to merge 8 commits intopeanutprotocol:mainfrom
JustaName-id:main
Closed

JustaName Integration#563
Ghadi8 wants to merge 8 commits intopeanutprotocol:mainfrom
JustaName-id:main

Conversation

@Ghadi8
Copy link
Copy Markdown

@Ghadi8 Ghadi8 commented Dec 5, 2024

This is a v1 of the justaname integration into peanut protocol. Subject to change according to received feedback.

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new ClaimSubname component for users to claim subnames.
    • Added a profile page for claiming subnames with metadata support.
    • Enhanced the Header component to conditionally render based on wallet connection status and account subnames.
    • Expanded the TableComponent to display ENS information in the contacts and accounts tabs.
  • Improvements

    • Updated input validation for Ethereum Name Service (ENS) addresses.
    • Enhanced the way module resolution is handled for specific imports.
  • Configuration Updates

    • New configuration files for JustaName and JustWeb3 providers to streamline integration.
    • Added new environment variable declarations for improved service integration.
  • Bug Fixes

    • Improved error handling and loading states in various components.
  • Chores

    • Updated dependencies to include new libraries for enhanced functionality and testing capabilities.
    • Added entries to .gitignore to exclude specific directories from version control.

@vercel
Copy link
Copy Markdown

vercel bot commented Dec 5, 2024

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
peanut-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 17, 2024 2:05pm

@vercel
Copy link
Copy Markdown

vercel bot commented Dec 5, 2024

@Ghadi8 is attempting to deploy a commit to the squirrellabs Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Dec 5, 2024

Walkthrough

This pull request introduces several changes across various files, primarily focused on enhancing environment variable configurations, adding new components, and updating existing functionalities. Key modifications include the introduction of new environment variables related to the "JustaName" service, updates to dependency management in package.json, and the addition of new React components for handling subnames. Additionally, configuration files have been updated to integrate new SDKs and improve module resolution. Overall, these changes aim to expand the application's capabilities and improve its structure.

Changes

File Path Change Summary
.env.example Added new environment variables: NEXT_PUBLIC_JUSTANAME_CHAIN_ID, NEXT_PUBLIC_JUSTANAME_ENS_DOMAIN, JUSTANAME_CHAIN_ID, JUSTANAME_API_KEY.
.gitignore Added entry to ignore the .idea directory.
package.json Added dependencies: @justaname.id/react, @justaname.id/sdk, @justweb3/ui, @justweb3/widget. Updated devDependencies for testing libraries.
postcss.config.js Updated postcss-import to include a custom resolve function for imports starting with @justweb3.
src/app/api/subnames/add/route.ts Added asynchronous POST handler for processing subname requests with validation and error handling.
src/app/claim-subname/page.tsx Introduced a new React component for the profile page, utilizing ClaimSubname and defining page metadata.
src/components/ClaimSubname/index.tsx Added a new React component for claiming subnames, including form handling and validation logic.
src/components/Create/Link/Initial.view.tsx Updated ENS address validation using a regular expression for improved accuracy.
src/components/Global/AddressLink/index.tsx Replaced useEnsName with usePrimaryName for retrieving ENS names.
src/components/Global/Header/index.tsx Enhanced Header component to include new hooks for account subnames and improved rendering logic.
src/components/Profile/Components/TableComponent.tsx Added new "ENS" columns to the table for displaying addresses in 'contacts' and 'accounts' tabs.
src/components/index.ts Added export statement for the ClaimSubname component.
src/config/justaname.config.ts Introduced a configuration file for initializing the JustaName singleton instance.
src/config/justweb3.config.tsx Added configuration for the JustWeb3 provider, including network details and a provider component.
src/config/peanut.config.tsx Modified PeanutProvider to wrap its children with JustWeb3Provider.
src/utils/general.utils.ts Updated resolveFromEnsName function to use the JustaName SDK for resolving ENS names.

Possibly related PRs

Suggested reviewers

  • Hugo0

🐰 In a world of code and names,
New variables join the game!
With subnames claimed and hooks anew,
Our app's more vibrant, it's true!
So hop along, let's celebrate,
For changes big, we can't be late! 🎉

Tip

CodeRabbit's docstrings feature is now available as part of our Early Access Program! Simply use the command @coderabbitai generate docstrings to have CodeRabbit automatically generate docstrings for your pull request.


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 16

🧹 Outside diff range and nitpick comments (13)
src/components/ClaimSubname/index.tsx (1)

200-200: Correct invalid Tailwind CSS class opacity-55

The class opacity-55 is not a valid Tailwind CSS class. Tailwind opacity classes increment by 5, such as opacity-50, opacity-60, etc.

Replace opacity-55 with the closest valid class, for example, opacity-50:

 className={`z-20 w-full border border-black bg-primary px-4 py-2 text-h6 text-black ${
     isSubnameAvailableFetching || !isSubnameAvailable?.isAvailable
-        ? 'cursor-not-allowed opacity-55'
+        ? 'cursor-not-allowed opacity-50'
         : ''
 }`}
src/utils/general.utils.ts (1)

292-297: Make chainId configurable in resolveFromEnsName function

The chainId is hardcoded to 1, which limits the function to Ethereum Mainnet. Making chainId a parameter enhances the function's flexibility across different networks.

Modify the function to accept chainId as an argument:

-export async function resolveFromEnsName(ensName: string): Promise<string | undefined> {
+export async function resolveFromEnsName(ensName: string, chainId: number): Promise<string | undefined> {
     const records = await JustaName.init().subnames.getRecords({
         ens: ensName,
-        chainId:1,
+        chainId: chainId,
         providerUrl: 'https://mainnet.infura.io/v3/' +  process.env["NEXT_PUBLIC_INFURA_API_KEY"]
     })

You'll also need to update any calls to resolveFromEnsName to pass the appropriate chainId.

postcss.config.js (1)

3-10: Ensure custom resolve function handles all import cases

The custom resolve function for postcss-import may not handle all possible import paths, potentially causing issues with module resolution.

Consider enhancing the resolve function to handle other scoped packages or document its limitations. Alternatively, test thoroughly to ensure no import paths are broken due to this custom resolver.

.env.example (2)

16-18: Document the purpose and expected values of JustaName environment variables

Add comments explaining:

  • What these variables are used for
  • Expected values and formats
  • Whether they are required or optional
 # JustaName Env Vars
+# Required for JustaName integration:
+# NEXT_PUBLIC_JUSTANAME_CHAIN_ID: Chain ID for JustaName service (e.g., "1" for mainnet, "11155111" for Sepolia)
+# NEXT_PUBLIC_JUSTANAME_ENS_DOMAIN: The ENS domain to use for JustaName service (e.g., "example.eth")
 export NEXT_PUBLIC_JUSTANAME_CHAIN_ID=""
 export NEXT_PUBLIC_JUSTANAME_ENS_DOMAIN=""

29-29: Consolidate JustaName environment variables

The JustaName environment variables are currently split into two sections. Consider consolidating them into a single section for better maintainability.

-export JUSTANAME_CHAIN_ID="1"
-
-# JustaName Env Vars
-export JUSTANAME_ENS_DOMAIN=""
-export JUSTANAME_API_KEY=""
+# JustaName Env Vars
+# JUSTANAME_CHAIN_ID: Default chain ID for JustaName service
+# JUSTANAME_ENS_DOMAIN: ENS domain for the service
+# JUSTANAME_API_KEY: API key for JustaName service authentication
+export JUSTANAME_CHAIN_ID=""  # Default: "1" for mainnet
+export JUSTANAME_ENS_DOMAIN=""
+export JUSTANAME_API_KEY=""

Also applies to: 33-35

src/components/Global/AddressLink/index.tsx (1)

22-28: Add error handling for the primaryName hook

The component should handle potential errors from the usePrimaryName hook and provide appropriate fallback behavior.

     // Update display: prefer ENS name, fallback to shortened address
-    if (primaryName) {
+    if (primaryName && !error) {
         setDisplayAddress(primaryName)
     } else {
+        // Log error if present
+        if (error) {
+            console.error('Error fetching primary name:', error)
+        }
         setDisplayAddress(utils.printableAddress(address))
     }
src/config/justweb3.config.tsx (1)

35-37: Add error boundary for provider initialization

The provider should handle initialization errors gracefully.

Consider wrapping the provider with an error boundary:

+class JustWeb3ProviderErrorBoundary extends React.Component<{children: React.ReactNode}, {hasError: boolean}> {
+    constructor(props: {children: React.ReactNode}) {
+        super(props)
+        this.state = { hasError: false }
+    }
+    static getDerivedStateFromError() {
+        return { hasError: true }
+    }
+    render() {
+        if (this.state.hasError) {
+            return <div>Error initializing JustWeb3Provider. Please check your configuration.</div>
+        }
+        return this.props.children
+    }
+}

 export const JustWeb3Provider: React.FC<JustaNameProviderConfig> = ({ children }) => {
-    return <JustWeb3ProviderPrimitive config={justweb3Config}>{children}</JustWeb3ProviderPrimitive>
+    return (
+        <JustWeb3ProviderErrorBoundary>
+            <JustWeb3ProviderPrimitive config={justweb3Config}>{children}</JustWeb3ProviderPrimitive>
+        </JustWeb3ProviderErrorBoundary>
+    )
 }
src/app/api/subnames/add/route.ts (1)

5-8: Add request size limit and rate limiting

The API endpoint needs protection against abuse.

Consider implementing:

  1. Request size limits to prevent memory exhaustion
  2. Rate limiting to prevent abuse
  3. Input validation middleware

Example implementation using middleware:

import rateLimit from 'express-rate-limit'
import { NextResponse } from 'next/server'

const MAX_REQUEST_SIZE = '10kb'
const RATE_LIMIT = 100 // requests
const RATE_LIMIT_WINDOW = 15 * 60 * 1000 // 15 minutes

export const config = {
    api: {
        bodyParser: {
            sizeLimit: MAX_REQUEST_SIZE
        }
    }
}

const limiter = rateLimit({
    windowMs: RATE_LIMIT_WINDOW,
    max: RATE_LIMIT
})
src/components/Create/Link/Initial.view.tsx (1)

Line range hint 119-134: Add error handling for ENS resolution timeout

The ENS name resolution lacks timeout handling and could potentially hang. Consider adding a timeout and proper error handling.

 if (ensRegex.test(inputValue)) {
-    const _address = await utils.resolveFromEnsName(inputValue)
+    try {
+        const controller = new AbortController();
+        const timeoutId = setTimeout(() => controller.abort(), 5000);
+        const _address = await utils.resolveFromEnsName(inputValue, { signal: controller.signal })
+        clearTimeout(timeoutId);
         if (_address) setRecipient({ name: inputValue, address: _address })
         else {
             setErrorState({
                 showError: true,
                 errorMessage: 'Please enter a valid address or ENS name.',
             })
             setLoadingState('Idle')
             return
         }
+    } catch (error) {
+        setErrorState({
+            showError: true,
+            errorMessage: 'ENS resolution failed. Please try again.',
+        })
+        setLoadingState('Idle')
+        return
+    }
src/components/Global/Header/index.tsx (2)

282-286: Optimize hooks usage with proper memoization

The useAccountSubnames hook result should be memoized to prevent unnecessary rerenders. Also, consider handling the loading state more gracefully.

-const { accountSubnames, isAccountSubnamesPending } = useAccountSubnames()
+const { accountSubnames = [], isAccountSubnamesPending } = useAccountSubnames()
 const router = useRouter()
-const peanutSubname = useMemo(() => {
-    return accountSubnames.find((subname) => subname.ens.endsWith(peanutEnsDomain))
-}, [accountSubnames])
+const peanutSubname = useMemo(() => 
+    accountSubnames.find((subname) => subname.ens.endsWith(peanutEnsDomain)),
+    [accountSubnames, peanutEnsDomain]
+)

318-320: Improve loading state feedback

The current loading state display is too simple. Consider adding a proper loading spinner or skeleton UI.

-{
-    isAccountSubnamesPending ? 'Loading...' : peanutSubname?.ens ?? 'Claim ENS'
-}
+{isAccountSubnamesPending ? (
+    <div className="flex items-center gap-2">
+        <span className="loading loading-spinner loading-sm" />
+        <span>Loading ENS...</span>
+    </div>
+) : (
+    peanutSubname?.ens ?? 'Claim ENS'
+)}
src/components/Profile/Components/TableComponent.tsx (2)

92-94: Remove commented out code

The implementation looks good, but there's unnecessary commented code that should be removed if it's no longer needed.

-                            {/* <th className="th-custom"></th> */}

236-242: Simplify conditional rendering

The nested ternary operator makes the code harder to read. Consider simplifying it using logical AND operator.

-                                    {
-                                        data.address ?
-                                            <AddressLink address={data.address} />
-                                            : null
-                                    }
+                                    {data.address && <AddressLink address={data.address} />}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 6c6cc04 and ea5a440.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (16)
  • .env.example (2 hunks)
  • .gitignore (1 hunks)
  • package.json (3 hunks)
  • postcss.config.js (1 hunks)
  • src/app/api/subnames/add/route.ts (1 hunks)
  • src/app/claim-subname/page.tsx (1 hunks)
  • src/components/ClaimSubname/index.tsx (1 hunks)
  • src/components/Create/Link/Initial.view.tsx (3 hunks)
  • src/components/Global/AddressLink/index.tsx (2 hunks)
  • src/components/Global/Header/index.tsx (3 hunks)
  • src/components/Profile/Components/TableComponent.tsx (4 hunks)
  • src/components/index.ts (1 hunks)
  • src/config/justaname.config.ts (1 hunks)
  • src/config/justweb3.config.tsx (1 hunks)
  • src/config/peanut.config.tsx (2 hunks)
  • src/utils/general.utils.ts (2 hunks)
✅ Files skipped from review due to trivial changes (1)
  • .gitignore
🔇 Additional comments (8)
src/components/ClaimSubname/index.tsx (1)

189-189: Verify peanutEnsDomain is defined and imported correctly

Ensure that peanutEnsDomain is correctly defined and imported to prevent undefined values in the rendered output.

Run the following script to confirm that peanutEnsDomain is properly exported:

✅ Verification successful

Let me verify if this variable is properly imported in the component. I'll generate a script to check this.


peanutEnsDomain is properly defined and imported

The variable is correctly defined in src/config/justweb3.config.tsx and properly imported and used in the ClaimSubname component. It's used consistently in the component for the ENS domain display and configuration.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that 'peanutEnsDomain' is defined and exported.

# Test: Search for the export of 'peanutEnsDomain'. Expect: At least one match.
rg "export\s+(const|let|var)\s+peanutEnsDomain" src/

Length of output: 167


Script:

#!/bin/bash
# Check if peanutEnsDomain is imported in ClaimSubname component
rg "import.*peanutEnsDomain" src/components/ClaimSubname/index.tsx

# Also check for any usage of peanutEnsDomain in the file
rg "peanutEnsDomain" src/components/ClaimSubname/index.tsx

Length of output: 452

src/utils/general.utils.ts (1)

299-299: Confirm correct coin ID in records lookup

When accessing coins with coin.id === 60, ensure that this ID corresponds to the expected cryptocurrency (e.g., Ethereum).

Run the following script to list available coin IDs and verify that ID 60 is correct:

Replace $ENS_NAME with a valid ENS name to test.

src/components/index.ts (1)

12-12: Export of ClaimSubname component is correct

The new export statement correctly adds ClaimSubname to the components index.

src/app/claim-subname/page.tsx (1)

1-30: New page component is properly implemented

The ProfilePage component correctly imports and renders the ClaimSubname component within the Layout.

src/config/peanut.config.tsx (1)

31-34: Verify provider order and initialization

The provider order looks correct, but we should verify that the JustWeb3Provider doesn't interfere with existing functionality.

Let's check for any potential provider conflicts:

✅ Verification successful

Let's examine the provider implementations to understand their relationships and potential conflicts.


Let's check if there are any dependencies between these providers and if JustWeb3Provider is used correctly in the context hierarchy.


Let's check the app layout and entry points to understand the complete provider hierarchy.


Let's check the config index file and search for the root component where these providers are initialized.


Based on the analysis of the providers and their implementations, I can now provide the final response:

Provider order is correctly implemented

The JustWeb3Provider integration is safe because:

  • It's properly imported and doesn't conflict with existing providers
  • It wraps ChakraProvider, which is the correct order as it's a UI-level provider
  • The implementation is isolated and doesn't interfere with other context providers
  • The Analytics component placement after ChakraProvider is maintained
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other providers that might conflict with JustWeb3Provider
rg -l "Provider.*children.*Provider" src/

Length of output: 163


Script:

#!/bin/bash
# Check the implementation of providers and their dependencies
echo "=== contextProvider.tsx ==="
rg -A 5 "export.*Provider" src/context/contextProvider.tsx

echo -e "\n=== wagmi.config.tsx ==="
rg -A 5 "export.*Provider" src/config/wagmi.config.tsx

echo -e "\n=== justweb3.config.tsx ==="
rg -A 5 "export.*Provider" src/config/justweb3.config.tsx

# Check for any imports of these providers
echo -e "\n=== Provider imports in peanut.config.tsx ==="
rg "import.*Provider" src/config/peanut.config.tsx

Length of output: 1438


Script:

#!/bin/bash
# Check for JustWeb3Provider dependencies and usage
echo "=== JustWeb3Provider dependencies ==="
rg -B 3 -A 3 "JustWeb3ProviderPrimitive" src/

# Check for imports and usage of other providers in the app
echo -e "\n=== App entry point providers ==="
rg -B 3 -A 3 "Provider" src/app.tsx src/main.tsx src/index.tsx 2>/dev/null

# Check if ContextProvider or WagmiProvider are used alongside JustWeb3Provider
echo -e "\n=== Provider usage patterns ==="
rg -l "ContextProvider|WagmiProvider" src/

Length of output: 1374


Script:

#!/bin/bash
# Check app layout implementation
echo "=== App layout implementation ==="
rg -B 5 -A 10 "export.*layout" src/app/layout.tsx

# Check where peanut.config is being used
echo -e "\n=== Peanut config usage ==="
rg -l "peanut\.config" src/

# Check the actual provider order in layout files
echo -e "\n=== Provider order in layout files ==="
rg -B 3 -A 3 "Provider.*children" src/app/layout.tsx src/layout.tsx 2>/dev/null

Length of output: 412


Script:

#!/bin/bash
# Check config index implementation
echo "=== Config index implementation ==="
cat src/config/index.ts

# Find the root component or entry point
echo -e "\n=== Root component search ==="
rg -l "ReactDOM.render|createRoot" src/

# Check main entry point implementation
echo -e "\n=== Main entry point implementation ==="
rg -B 5 -A 10 "render|createRoot" src/ --type ts --type tsx

Length of output: 471

package.json (1)

73-74: LGTM: Testing setup looks good

The addition of Jest and related testing libraries with their latest stable versions is a good practice for ensuring code quality.

Also applies to: 83-84

src/components/Profile/Components/TableComponent.tsx (2)

Line range hint 1-272: Consider performance optimization for ENS resolution

Since the table might display multiple ENS names simultaneously, consider implementing batch resolution or caching mechanisms to optimize performance. The AddressLink component should ideally handle this internally.


75-77: Verify ENS column sorting implementation

The ENS column header is correctly added, but we should ensure that the sorting logic properly handles ENS names, which may require special comparison rules (e.g., case-insensitive, handling of special characters).

}

return (
<div className="relative flex h-full w-full flex-row flex-col items-center justify-start gap-4 px-4">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Remove conflicting Tailwind CSS classes

The div at line 67 has both flex-row and flex-col classes applied, which are contradictory. This may lead to unexpected layout behavior.

Remove the unnecessary flex-row class:

-<div className="relative flex h-full w-full flex-row flex-col items-center justify-start gap-4 px-4">
+<div className="relative flex h-full w-full flex-col items-center justify-start gap-4 px-4">
📝 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
<div className="relative flex h-full w-full flex-row flex-col items-center justify-start gap-4 px-4">
<div className="relative flex h-full w-full flex-col items-center justify-start gap-4 px-4">

Comment on lines +56 to +64
const handleClaim = async (data: ISubnameForm) => {
addSubname({
username: data.username,
ensDomain: peanutEnsDomain,
chainId: chainId
}).then(() => {
router.push('/profile')
})
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Handle errors in handleClaim function

The handleClaim function currently does not handle errors from the addSubname call. This might lead to unhandled promise rejections and a poor user experience if the claim fails.

Consider refactoring to use async/await with a try...catch block to handle errors gracefully:

 const handleClaim = async (data: ISubnameForm) => {
-    addSubname({
+    try {
+        await addSubname({
         username: data.username,
         ensDomain: peanutEnsDomain,
         chainId: chainId
-    }).then(() => {
+        })
+        router.push('/profile')
+    } catch (error) {
+        // Handle error (e.g., display an error message)
+        console.error('Failed to claim subname:', error)
+    }
 }

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

Comment on lines +13 to 16
const { primaryName } = usePrimaryName({
address: isAddress(address) ? (address as `0x${string}`) : undefined,
chainId: 1, // Mainnet for ENS lookups
})
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use environment variable for chain ID instead of hardcoding

The chain ID is hardcoded to 1 (mainnet) in the usePrimaryName hook. Consider using the NEXT_PUBLIC_JUSTANAME_CHAIN_ID environment variable for flexibility across different environments.

 const { primaryName } = usePrimaryName({
     address: isAddress(address) ? (address as `0x${string}`) : undefined,
-    chainId: 1, // Mainnet for ENS lookups
+    chainId: Number(process.env.NEXT_PUBLIC_JUSTANAME_CHAIN_ID) || 1, // Fallback to mainnet
 })
📝 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
const { primaryName } = usePrimaryName({
address: isAddress(address) ? (address as `0x${string}`) : undefined,
chainId: 1, // Mainnet for ENS lookups
})
const { primaryName } = usePrimaryName({
address: isAddress(address) ? (address as `0x${string}`) : undefined,
chainId: Number(process.env.NEXT_PUBLIC_JUSTANAME_CHAIN_ID) || 1, // Fallback to mainnet
})

Comment on lines +6 to +7
const ensDomain = process.env.JUSTANAME_ENS_DOMAIN as string
const infuraApiKey = process.env.INFURA_API_KEY as string
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add validation for required environment variables

The configuration assumes environment variables are present without validation. Add checks to ensure required variables are available before initialization.

+    if (!ensDomain) {
+        throw new Error('JUSTANAME_ENS_DOMAIN environment variable is not set')
+    }
+    if (!infuraApiKey) {
+        throw new Error('INFURA_API_KEY environment variable is not set')
+    }
📝 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
const ensDomain = process.env.JUSTANAME_ENS_DOMAIN as string
const infuraApiKey = process.env.INFURA_API_KEY as string
const ensDomain = process.env.JUSTANAME_ENS_DOMAIN as string
const infuraApiKey = process.env.INFURA_API_KEY as string
if (!ensDomain) {
throw new Error('JUSTANAME_ENS_DOMAIN environment variable is not set')
}
if (!infuraApiKey) {
throw new Error('INFURA_API_KEY environment variable is not set')
}

Comment on lines +25 to +27
const chainId = parseInt(
message.split('Chain ID: ')[1].split('\n')[0],
) as ChainId
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Improve message parsing security

The current message parsing is fragile and could break with malformed input.

Add robust parsing with proper error handling:

-    const chainId = parseInt(
-        message.split('Chain ID: ')[1].split('\n')[0],
-    ) as ChainId
+    const chainId = (() => {
+        try {
+            const match = message.match(/Chain ID: (\d+)/i)
+            if (!match) throw new Error('Chain ID not found in message')
+            const id = parseInt(match[1])
+            if (isNaN(id)) throw new Error('Invalid Chain ID format')
+            return id as ChainId
+        } catch (error) {
+            throw new Error(`Invalid message format: ${error.message}`)
+        }
+    })()
📝 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
const chainId = parseInt(
message.split('Chain ID: ')[1].split('\n')[0],
) as ChainId
const chainId = (() => {
try {
const match = message.match(/Chain ID: (\d+)/i)
if (!match) throw new Error('Chain ID not found in message')
const id = parseInt(match[1])
if (isNaN(id)) throw new Error('Invalid Chain ID format')
return id as ChainId
} catch (error) {
throw new Error(`Invalid message format: ${error.message}`)
}
})()

Comment on lines +322 to +326
<div className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
onClick={(event) => {
web3modalOpen()
event.stopPropagation()
}}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve event handling in nested button

The current event handling could lead to confusing UX where both parent and child buttons respond to clicks. Consider restructuring the component.

-<div className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
+<button
+    type="button"
+    className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
     onClick={(event) => {
+        event.preventDefault()
         web3modalOpen()
         event.stopPropagation()
     }}
->
📝 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
<div className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
onClick={(event) => {
web3modalOpen()
event.stopPropagation()
}}
<button
type="button"
className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
onClick={(event) => {
event.preventDefault()
web3modalOpen()
event.stopPropagation()
}}

Comment on lines +263 to +264
<td className="td-custom font-bold">
<AddressLink address={data.tertiaryText} /></td>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Add validation and improve formatting

There are several issues with this implementation:

  1. Missing null check for tertiaryText before using it as an address
  2. No validation that tertiaryText is actually an address
  3. Inconsistent formatting with the closing tag on the same line
-                                    <td className="td-custom font-bold">
-                                        <AddressLink address={data.tertiaryText} /></td>
+                                    <td className="td-custom font-bold">
+                                        {utils.isAddress(data.tertiaryText) && (
+                                            <AddressLink address={data.tertiaryText} />
+                                        )}
+                                    </td>

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🔭 Outside diff range comments (1)
src/components/Global/GeneralRecipientInput/index.tsx (1)

Line range hint 118-126: Apply learned bank account autocomplete attribute

Based on previous learnings, the autocomplete attribute should be conditionally set for bank accounts.

Apply this change:

 <ValidatedInput
     label="To"
     value={recipient.name ?? recipient.address}
     placeholder={placeholder}
     validate={checkAddress}
     className={className}
     autoComplete="on"
-    name="bank-account"
+    name={recipientType.current === 'us' || recipientType.current === 'iban' ? 'bank-account-number' : undefined}
     suggestions={getSuggestions(recipientType.current)}
     infoText={infoText}
     formatDisplayValue={formatDisplayValue}
 />
🧹 Nitpick comments (5)
src/components/Global/GeneralRecipientInput/index.tsx (1)

Line range hint 55-64: Enhance error handling for ENS resolution

The ENS validation logic is sound but could benefit from more specific error messages.

Consider enhancing the error messages:

 } else if (validateEnsName(trimmedInput.toLowerCase())) {
     type = 'ens'
     const address = await utils.resolveFromEnsName(trimmedInput.toLowerCase())
     if (address) {
         resolvedAddress.current = address
         isValid = true
     } else {
-        errorMessage.current = 'ENS name not found'
+        errorMessage.current = 'ENS name could not be resolved. Please verify the name or try again later.'
         isValid = false
     }
src/components/Request/Pay/Pay.tsx (1)

Line range hint 45-52: Improve error handling in ENS name resolution

While the ENS validation logic has been improved, the error handling could be more informative.

Consider enhancing the error message to provide more context:

-            throw new Error('Failed to resolve ENS name')
+            throw new Error(`Failed to resolve ENS name: ${address}. Please verify the name is correct.`)
src/components/Create/Link/Input.view.tsx (1)

278-279: Consider extracting recipient display logic

The recipient name display logic is duplicated across components. Consider extracting it into a reusable utility function.

Create a new utility function:

// utils/display.utils.ts
export const getDisplayName = (recipient: { name?: string, address?: string }): string => {
  if (recipient?.name && validateEnsName(recipient.name)) {
    return recipient.name;
  }
  return shortenAddressLong(recipient.address ?? '');
};

Then use it in the component:

-  ? `Send to ${recipient?.name && validateEnsName(recipient?.name) ? recipient.name : shortenAddressLong(recipient.address ?? '')}`
+  ? `Send to ${getDisplayName(recipient)}`
src/components/Create/Link/Confirm.view.tsx (2)

237-238: Consolidate recipient display logic

The recipient name display logic is duplicated from Input.view.tsx. This should use the same utility function suggested earlier.

Apply the same pattern:

-  ? `Send to ${recipient?.name && validateEnsName(recipient?.name) ? recipient.name : printableAddress(recipient.address ?? '')}`
+  ? `Send to ${getDisplayName(recipient)}`

Line range hint 353-367: Address TODO comment about points estimation

There's an unaddressed TODO comment regarding points estimation that should be resolved.

Would you like me to help implement the correct points estimation logic or create a GitHub issue to track this task?

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ea5a440 and 8c2854a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (9)
  • package.json (3 hunks)
  • src/components/Create/Link/Confirm.view.tsx (2 hunks)
  • src/components/Create/Link/Initial.view.tsx (3 hunks)
  • src/components/Create/Link/Input.view.tsx (2 hunks)
  • src/components/Create/Link/Success.view.tsx (2 hunks)
  • src/components/Global/AddressInput/index.tsx (2 hunks)
  • src/components/Global/GeneralRecipientInput/index.tsx (2 hunks)
  • src/components/Request/Pay/Pay.tsx (2 hunks)
  • src/utils/general.utils.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/components/Create/Link/Initial.view.tsx
  • package.json
🧰 Additional context used
📓 Learnings (1)
src/components/Global/GeneralRecipientInput/index.tsx (1)
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#545
File: src/components/Global/GeneralRecipientInput/index.tsx:118-126
Timestamp: 2024-11-26T12:06:11.603Z
Learning: For bank account input fields, use `autocomplete="bank-account-number"` when the recipient type is `'us'` or `'iban'`.
🔇 Additional comments (7)
src/components/Global/AddressInput/index.tsx (2)

6-6: LGTM: Clean import of new utility function

The import of validateEnsName from utils is properly placed with other utility imports.


Line range hint 18-23: Verify ENS resolution behavior

The ENS validation logic looks correct, but we should ensure proper error handling for network issues during ENS resolution.

Let's check for other ENS resolution implementations:

Consider adding a specific error message for network-related ENS resolution failures:

 if (validateEnsName(recipient.toLowerCase())) {
     const resolvedAddress = await resolveFromEnsName(recipient.toLowerCase())
     return !!resolvedAddress
+ } catch (error) {
+    console.error('ENS resolution failed:', error)
+    return false
 } else {
     return isAddress(recipient, { strict: false })
 }
src/components/Global/GeneralRecipientInput/index.tsx (1)

10-10: LGTM: Clean import of validation utility

The import is properly placed with other utility imports.

src/components/Create/Link/Success.view.tsx (1)

11-11: LGTM: Clean import of validation utility

The import is properly placed with other utility imports.

src/utils/general.utils.ts (3)

21-21: LGTM! Improved ENS name validation

The change from a simple .eth suffix check to using a proper regex validation through validateEnsName is a good improvement that makes the validation more robust.


894-894: LGTM! Clean import statement

The import of the JustaName SDK is clean and properly placed at the end of the imports section.


296-302: ⚠️ Potential issue

Add error handling and environment variable validation

The resolveFromEnsName function has several potential issues:

  1. No validation of the NEXT_PUBLIC_INFURA_API_KEY environment variable
  2. No error handling for API failures
  3. No type checking for the returned records

Consider applying this improvement:

 export async function resolveFromEnsName(ensName: string): Promise<string | undefined> {
+    const infuraApiKey = process.env['NEXT_PUBLIC_INFURA_API_KEY'];
+    if (!infuraApiKey) {
+        throw new Error('NEXT_PUBLIC_INFURA_API_KEY is not defined');
+    }
+    try {
         const records = await JustaName.init().subnames.getRecords({
             ens: ensName,
             chainId: 1,
-            providerUrl: 'https://mainnet.infura.io/v3/' + process.env['NEXT_PUBLIC_INFURA_API_KEY'],
+            providerUrl: `https://mainnet.infura.io/v3/${infuraApiKey}`,
         })
+        if (!records?.records?.coins) {
+            return undefined;
+        }
         return records?.records?.coins?.find((coin) => coin.id === 60)?.value;
+    } catch (error) {
+        console.error('Error resolving ENS name:', error);
+        return undefined;
+    }
 }

Likely invalid or redundant comment.

Comment on lines +82 to 83
? `You have successfully sent the funds to ${recipient?.name && validateEnsName(recipient?.name) ? recipient.name : printableAddress(recipient.address ?? '')}.`
: 'Share this link or QR code with the recipient. They will be able to claim the funds on any chain in any token.'}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve null safety in recipient name validation

The recipient name validation logic could be more robust with null safety.

Consider this safer implementation:

-    ? `You have successfully sent the funds to ${recipient?.name && validateEnsName(recipient?.name) ? recipient.name : printableAddress(recipient.address ?? '')}.`
+    ? `You have successfully sent the funds to ${recipient?.name && recipient.name.trim() && validateEnsName(recipient.name) ? recipient.name : printableAddress(recipient?.address ?? '')}.`

This change:

  1. Ensures name is not empty after trimming
  2. Maintains consistent null safety for both name and address
📝 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
? `You have successfully sent the funds to ${recipient?.name && validateEnsName(recipient?.name) ? recipient.name : printableAddress(recipient.address ?? '')}.`
: 'Share this link or QR code with the recipient. They will be able to claim the funds on any chain in any token.'}
? `You have successfully sent the funds to ${recipient?.name && recipient.name.trim() && validateEnsName(recipient.name) ? recipient.name : printableAddress(recipient?.address ?? '')}.`
: 'Share this link or QR code with the recipient. They will be able to claim the funds on any chain in any token.'}

Comment on lines +25 to +27
export const validateEnsName = (ensName: string): boolean => {
return /(?:^|[^a-zA-Z0-9-_.])(([^\s.]{1,63}\.)+[^\s.]{2,63})/.test(ensName)
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Based on the code analysis, I can now provide a final response:

The ENS name validation needs both tests and improvements

The current regex pattern has potential issues:

  • It uses a positive lookbehind (?:^|[^a-zA-Z0-9-_.]) which may not work consistently across all JavaScript engines
  • The pattern may not correctly validate all ENS name requirements (e.g., valid characters, length limits)
  • The function is widely used across the codebase for critical functionality like address resolution and recipient validation

Suggested improvements:

  • Add comprehensive test cases covering:
    • Valid ENS names (e.g., "vitalik.eth", "sub.domain.eth")
    • Invalid ENS names (e.g., empty string, no TLD, invalid characters)
    • Edge cases (e.g., maximum length names, names with hyphens)
  • Consider using established ENS validation libraries or implementing the official ENS naming standards
  • Document the validation rules being enforced
🔗 Analysis chain

Consider adding test cases for the ENS name validation regex

The regex pattern for ENS name validation looks comprehensive but should be thoroughly tested with various edge cases to ensure it correctly validates all valid ENS names and rejects invalid ones.

Let's verify the regex pattern against common ENS name patterns:


Let me search for any existing tests for this validation function.


Let me check how validateEnsName is being used in these files to understand the validation requirements better.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Test the ENS name validation regex against various cases

echo "Testing ENS name validation regex..."
echo "vitalik.eth" | gawk '/(?:^|[^a-zA-Z0-9-_.])(([^\s.]{1,63}\.)+[^\s.]{2,63})/ {print "Valid: vitalik.eth"}'
echo "sub.domain.eth" | gawk '/(?:^|[^a-zA-Z0-9-_.])(([^\s.]{1,63}\.)+[^\s.]{2,63})/ {print "Valid: sub.domain.eth"}'
echo "invalid" | gawk '/(?:^|[^a-zA-Z0-9-_.])(([^\s.]{1,63}\.)+[^\s.]{2,63})/ {print "Should not match: invalid"}'
echo "invalid.." | gawk '/(?:^|[^a-zA-Z0-9-_.])(([^\s.]{1,63}\.)+[^\s.]{2,63})/ {print "Should not match: invalid.."}'

Length of output: 946


Script:

#!/bin/bash
# Search for test files related to general.utils.ts
fd "general.utils.test" --type f

# Search for any test files that might contain ENS validation tests
rg -l "validateEnsName" --type=test

Length of output: 97


Script:

#!/bin/bash
# Search for test files related to general.utils.ts with common test file extensions
fd "general.utils.(test|spec)\.(ts|js|tsx|jsx)$"

# Search for any files containing validateEnsName tests
rg -l "validateEnsName"

Length of output: 409


Script:

#!/bin/bash
# Check the implementation and usage of validateEnsName
rg "validateEnsName" -B 2 -A 2

# Look for any test-related code near validateEnsName usage
rg "test|describe|it\(" --type ts --type tsx -C 5 -l | xargs rg "validateEnsName" -C 5 || true

Length of output: 23819

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (1)
src/components/Global/Header/index.tsx (1)

322-326: ⚠️ Potential issue

Fix nested button click handling

The current implementation uses a div with onClick which can lead to accessibility issues and event bubbling problems.

-    <div className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
-        onClick={(event) => {
-            web3modalOpen()
-            event.stopPropagation()
-        }}
+    <button
+        type="button"
+        className={"bg-black h-full flex flex-col justify-center p-2 rounded-full"}
+        onClick={(event) => {
+            event.preventDefault()
+            web3modalOpen()
+            event.stopPropagation()
+        }}
+        aria-label="Connect wallet"
🧹 Nitpick comments (1)
src/components/Global/Header/index.tsx (1)

308-330: Improve button accessibility and loading state

The button lacks proper ARIA attributes and the loading state could be enhanced.

     <button
         className="btn btn-large bg-white px-2 py-2 gap-2"
+        aria-label={isAccountSubnamesPending ? "Loading ENS profile" : "Open ENS profile"}
+        disabled={isAccountSubnamesPending}
         onClick={() => {
             if (peanutSubname) {
                 openEnsProfile(peanutSubname.ens)
                 return
             }
             router.push('/claim-subname')
         }}
     >
-        {isAccountSubnamesPending ? 'Loading...' : peanutSubname?.ens ?? 'Claim ENS'}
+        {isAccountSubnamesPending ? (
+            <span className="flex items-center gap-2">
+                <span className="loading-spinner" aria-hidden="true" />
+                Loading...
+            </span>
+        ) : (
+            peanutSubname?.ens ?? 'Claim ENS'
+        )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8c2854a and a8e63a2.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • package.json (1 hunks)
  • src/components/Global/GeneralRecipientInput/index.tsx (2 hunks)
  • src/components/Global/Header/index.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/components/Global/GeneralRecipientInput/index.tsx
🔇 Additional comments (2)
package.json (1)

31-34: Verify compatibility between JustaName and JustWeb3 packages

The integration uses newer versions than previously recommended:

  • @justaname.id/react: 0.3.162 (was 0.3.158)
  • @justaname.id/sdk: 0.2.159 (was 0.2.155)
  • @justweb3/ui and @justweb3/widget: 0.0.98 (was 0.0.94)
✅ Verification successful

Based on the results, I can generate the final response since we have sufficient information about the package releases.

Package versions are compatible - all released together

All package updates were released within a 2-minute window on December 12, 2024:

  • @justaname.id/sdk: 09:55:15 UTC
  • @justweb3/ui: 09:55:30 UTC
  • @justaname.id/react: 09:55:37 UTC
  • @justweb3/widget: 09:56:37 UTC

The synchronized release timing strongly indicates these versions were tested and released together as a compatible set.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for any breaking changes or compatibility issues between these versions

# Check the changelog for breaking changes
curl -s https://registry.npmjs.org/@justaname.id/react | jq -r '.versions["0.3.162"].dist.tarball' | xargs curl -s | tar -xzO package/CHANGELOG.md 2>/dev/null || echo "No CHANGELOG.md found"
curl -s https://registry.npmjs.org/@justaname.id/sdk | jq -r '.versions["0.2.159"].dist.tarball' | xargs curl -s | tar -xzO package/CHANGELOG.md 2>/dev/null || echo "No CHANGELOG.md found"

# Check if these versions were released together
curl -s https://registry.npmjs.org/@justaname.id/react | jq -r '.time["0.3.162"]'
curl -s https://registry.npmjs.org/@justaname.id/sdk | jq -r '.time["0.2.159"]'
curl -s https://registry.npmjs.org/@justweb3/ui | jq -r '.time["0.0.98"]'
curl -s https://registry.npmjs.org/@justweb3/widget | jq -r '.time["0.0.98"]'

Length of output: 823

src/components/Global/Header/index.tsx (1)

2-2: LGTM: Clean import organization

The imports are well-organized, with related hooks and configurations grouped together.

Also applies to: 14-16

Comment on lines +282 to +287
const { accountSubnames, isAccountSubnamesPending } = useAccountSubnames()
const router = useRouter()
const peanutSubname = useMemo(() => {
return accountSubnames.find((subname) => subname.ens.endsWith(peanutEnsDomain))
}, [accountSubnames])
const { openEnsProfile } = useJustWeb3()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider adding error handling for accountSubnames

The useAccountSubnames hook might fail to fetch subnames, but there's no error handling in place.

-    const { accountSubnames, isAccountSubnamesPending } = useAccountSubnames()
+    const { accountSubnames, isAccountSubnamesPending, error } = useAccountSubnames()
+    useEffect(() => {
+        if (error) {
+            console.error('Failed to fetch subnames:', error)
+            // Consider showing a user-friendly error message
+        }
+    }, [error])

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants