Skip to content

Feat/tailwind #90

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

Merged
merged 19 commits into from
Apr 11, 2025
Merged

Feat/tailwind #90

merged 19 commits into from
Apr 11, 2025

Conversation

nitegeist
Copy link
Contributor

@nitegeist nitegeist commented Mar 29, 2025

Summary by CodeRabbit

  • New Features

    • Introduced a new layout structure for the application, enhancing user experience with global styles and responsive design.
    • Added a Home component for wrapping and unwrapping ETH, featuring improved wallet connection prompts and dynamic button actions.
    • Implemented a Skeleton loading component for better visual feedback during data fetching.
    • Added a Toaster component for displaying notifications with customizable themes.
    • Introduced a set of new UI components including Card, Form, and Button, enhancing modularity and design consistency.
    • Added a new configuration file for UI components, defining settings and aliases for easier imports.
    • Enhanced the ConnectWallet component for improved wallet connection management and responsiveness.
  • Style

    • Established a foundational styling system with global CSS variables for light and dark themes, along with gradient backgrounds.
    • Redesigned layouts using utility-first CSS for responsive interfaces, ensuring seamless light/dark theme support.

@nitegeist nitegeist self-assigned this Mar 29, 2025
Copy link

vercel bot commented Mar 29, 2025

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

Name Status Preview Comments Updated (UTC)
wrapeth ✅ Ready (Inspect) Visit Preview 💬 Add feedback Apr 11, 2025 4:37pm

Copy link

coderabbitai bot commented Mar 29, 2025

Walkthrough

The pull request refactors the project’s configuration, UI components, and blockchain interaction hooks. ESLint, Next.js, and TypeScript settings have been updated while dependencies have been revised. New UI components and icons have been introduced, replacing legacy design system components with Tailwind-based primitives. The hooks for deposit, withdraw, and balance management have been reworked for better on-chain interaction and validation. Additionally, the old pages and Storybook setups were removed in favor of a new app directory structure featuring a RootLayout, Home, and Provider component.

Changes

File(s) Change Summary
.eslintrc, next.config.js, tsconfig.json, .prettierrc, package.json, postcss.config.mjs, next-env.d.ts, README.md Updated linting rules, build configurations, dependency versions, module paths, and documentation links; removed deprecated settings.
components/ConnectWallet.tsx, Header.tsx, TokenInfo.tsx, WrapperForm.tsx Revised core UI components with updated hooks, improved user interaction logic, and styling adjustments (e.g., replacing design system components with Tailwind CSS and NavigationMenu).
components.json, components/icons/RaidGuild.tsx, components/ui//* (button, card, form, input, label, navigation-menu, sonner, skeleton)** Introduced a new UI component library for consistent styling, modular design, and enhanced visual elements (including SVG icons and configurable navigation menus).
hooks/useBalances.ts, useDeposit.ts, useGasFee.ts, useWithdraw.ts, lib/utils.ts, utils/contracts.ts, utils/general.ts, utils/unitConverter.ts, utils/wagmiConfig.ts Refactored blockchain interaction hooks and utility functions with updated contract methods, streamlined logic, new validation via zod, and removal of legacy configurations.
pages/_app.tsx, pages/index.tsx, utils/chains.ts, .storybook/main.js, .storybook/preview.js, app/layout.tsx, app/page.tsx, app/providers.tsx Removed legacy Next.js pages and Storybook files; introduced a new Next.js app directory structure with RootLayout, Home, and Provider components for improved architecture and state management.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant H as Home
    participant P as Provider
    participant WF as WrapperForm
    participant HD as Deposit/Withdraw Hook
    participant C as Contract
    participant T as Toast

    U->>H: Select deposit/withdraw action
    H->>P: Validate wallet connection
    alt Wallet Not Connected
      P-->>H: Prompt user to connect
    else Wallet Connected
      H->>WF: Render transaction form
      WF->>HD: Submit form with amount
      HD->>C: Execute transaction call
      C-->>HD: Return transaction result
      HD->>T: Trigger status notifications
      T-->>U: Display outcome to user
    end
Loading

Poem

Hop, hop, hooray—new code delights,
My whiskers twitch with every refactored line.
UI components and hooks now shine so bright,
Tailwind styles and functions all align.
I bounce through changes with a joyful heart,
Celebrating progress and fresh, smart art! 🐇🎉

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

hooks/useWithdraw.tsx

Oops! Something went wrong! :(

ESLint: 8.57.1

ESLint couldn't determine the plugin "jsx-a11y" uniquely.

Please remove the "plugins" setting from either config or remove either plugin installation.

If you still can't figure out the problem, please stop by https://eslint.org/chat/help to chat with the team.

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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.

@nitegeist nitegeist marked this pull request as ready for review March 29, 2025 22:50
Copy link

@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: 5

🧹 Nitpick comments (21)
utils/wagmiConfig.ts (1)

26-53: Consider additional or fallback transports.
Using http() for every chain ensures a straightforward approach, but might reduce redundancy protections if one endpoint fails. Consider specifying multiple providers or fallback URLs for added resilience.

hooks/useBalances.ts (3)

13-15: Verify fallback for chain?.name lookups.
chain?.name.toLowerCase() || 'homestead' might cause unexpected behavior if an unknown chain name is returned. Consider gracefully handling unrecognized networks.


17-17: Continuous block height watching.
Watching block numbers is helpful for real-time updates of balances. Ensure this polling or event subscription doesn’t create performance overhead.


47-52: Query invalidation on block changes.
Invalidating the queries each time a new block arrives is beneficial for ensuring up-to-date balances. Monitor for potential performance impacts if high block frequencies become excessive.

lib/utils.ts (1)

4-4: Use targeted ESLint disables instead of global disables.

Rather than disabling all ESLint rules for the entire file, consider using more targeted disables for specific rules if needed.

-/* eslint-disable */
+// If needed, disable specific rules:
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
utils/chainMap.ts (1)

1-23: Consider a more maintainable approach for bidirectional mappings.

The current implementation duplicates data by storing both directions of the mapping in the same object. This could lead to maintenance issues if chain data needs to be updated.

Consider generating one mapping direction from the other:

-const chainMappings = {
-  // Chain name → URL slug
-  Ethereum: 'ethereum',
-  Polygon: 'polygon',
-  'OP Mainnet': 'optimism',
-  'Arbitrum One': 'arbitrum',
-  Base: 'base',
-  Gnosis: 'gnosis',
-  Sepolia: 'sepolia',
-  Blast: 'blast',
-  Zora: 'zora',
-
-  // URL slug → Chain name
-  ethereum: 'Ethereum',
-  polygon: 'Polygon',
-  optimism: 'OP Mainnet',
-  arbitrum: 'Arbitrum One',
-  base: 'Base',
-  gnosis: 'Gnosis',
-  sepolia: 'Sepolia',
-  blast: 'Blast',
-  zora: 'Zora',
-};
+// Primary mapping: Chain name → URL slug
+const chainToSlug = {
+  Ethereum: 'ethereum',
+  Polygon: 'polygon',
+  'OP Mainnet': 'optimism',
+  'Arbitrum One': 'arbitrum',
+  Base: 'base',
+  Gnosis: 'gnosis',
+  Sepolia: 'sepolia',
+  Blast: 'blast',
+  Zora: 'zora',
+};
+
+// Generate reverse mapping: URL slug → Chain name
+const slugToChain = Object.entries(chainToSlug).reduce(
+  (acc, [chain, slug]) => ({
+    ...acc,
+    [slug]: chain,
+  }),
+  {}
+);
+
+const chainMappings = {
+  ...chainToSlug,
+  ...slugToChain,
+};

This approach generates the reverse mapping dynamically, ensuring consistency and making updates easier.

components/ui/input.tsx (1)

5-19: Optional: Add support for refs (accessibility & form libraries).
Currently, the component doesn't use React.forwardRef. Ref forwarding can be helpful for advanced form handling or focusing logic.

-function Input({ className, type, ...props }: React.ComponentProps<"input">) {
+const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<"input">>(
+  ({ className, type, ...props }, ref) => {
     return (
       <input
+        ref={ref}
         type={type}
         ...
       />
     );
   }
+);
components/icons/RaidGuild.tsx (1)

1-27: Optional: Make the fill color configurable.
Currently, the SVG is hard-coded to use “#FF3864”. If you want to allow theming, expose a prop or reuse props.fill.

- fill='#FF3864'
+ fill={props.fill ?? '#FF3864'}
components/TokenInfo.tsx (1)

17-19: Button styling & balance truncation
Using a secondary variant and uppercase text is fine. Truncating balance to 6 characters is user-friendly, but consider providing a tooltip or full balance elsewhere in the UI for transparency.

components/ui/button.tsx (1)

7-36: Consider extracting common styling for easier maintenance.
While buttonVariants is well-implemented, there are potential shared styling rules across variants (e.g., shadow-xs, hover: classes). You could refactor them into smaller base styles within CVA to avoid repetition.

styles/globals.css (1)

5-98: Add fallback colors for OKLCH to support older browsers.
The OKLCH color space is not fully supported by older browsers. Including a fallback color (e.g., hex or HSL) for --chart-* and similar variables may help broaden compatibility.

hooks/useDeposit.tsx (1)

88-93: Improve offline or chain mismatch detection.
Currently, executeDeposit triggers the write request only if simulation succeeded. Additional checks could ensure that chain is valid and user is properly connected (e.g., show a toast if the chain is unsupported).

Also applies to: 95-105

components/ui/form.tsx (2)

17-18: Consider adding a named wrapper component for clarity.
Re-exporting FormProvider as Form is concise, but you may want to wrap FormProvider in a short function component to maintain naming clarity, add custom logic (if needed), and improve maintainability.


156-165: Add test coverage for form components.
These components form critical infrastructure for your forms. Unit or integration tests can ensure robust validation, error handling, and accessibility over time.

Would you like support creating initial unit tests for these components?

pages/index.tsx (2)

53-71: Confirm Tailwind class usage.
You're using className={cn('pointer ...')}. Check whether 'pointer' is a valid Tailwind utility or a custom utility class. Typically, Tailwind’s pointer utility is cursor-pointer. If 'pointer' isn’t recognized, the user’s cursor style may not update as expected.

- 'pointer rounded-xs rounded-r-none hover:bg-purple-600 uppercase'
+ 'cursor-pointer rounded-xs rounded-r-none hover:bg-purple-600 uppercase'

74-81: Consider fallback UI when disconnected.
When mounted && isConnected is false, you display a heading. If there’s a more robust onboarding or a helpful CTA (e.g., "Connect your wallet to continue"), consider elaborating the message to improve user guidance.

components/ConnectWallet.tsx (3)

140-149: Provide a fallback image if no chain icon is available.
Using buttonChain.iconUrl ?? '' may result in a broken link or 404 if iconUrl is unavailable. Consider a default placeholder or a fallback to ensure a predictable user experience.

 <Image
   className='rounded-full'
   unoptimized
   alt={buttonChain.name ?? 'Chain icon'}
-  src={buttonChain.iconUrl ?? ''}
+  src={buttonChain.iconUrl ?? '/images/placeholder-chain.png'}
   width={25}
   height={25}
 />

153-159: Improve discoverability of the account menu.
A simple “Wallet” label or icon might not be obvious enough for first-time users. You could use tooltips, additional text, or a more explicit label to guide them to account-related actions.


23-40: Consider extracting router push logic into a dedicated helper.
Multiple lines handle async router updates to reflect the new chain in the URL. Extracting this to a helper function, e.g., updateUrlWithChain(), reduces duplication and can simplify debugging.

components/WrapperForm.tsx (1)

131-132: Potentially unused container
Double-check if the empty <div> is necessary. If not, consider removing to keep the DOM clean.

hooks/useWithdraw.tsx (1)

28-45: Console error logging
While it’s helpful for debugging, ensure no sensitive data is exposed.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 9cced64 and 53d6d7b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (29)
  • .eslintrc (1 hunks)
  • components.json (1 hunks)
  • components/ConnectWallet.tsx (1 hunks)
  • components/Header.tsx (1 hunks)
  • components/TokenInfo.tsx (1 hunks)
  • components/WrapperForm.tsx (4 hunks)
  • components/icons/RaidGuild.tsx (1 hunks)
  • components/ui/button.tsx (1 hunks)
  • components/ui/card.tsx (1 hunks)
  • components/ui/form.tsx (1 hunks)
  • components/ui/input.tsx (1 hunks)
  • components/ui/label.tsx (1 hunks)
  • components/ui/navigation-menu.tsx (1 hunks)
  • components/ui/sonner.tsx (1 hunks)
  • hooks/useBalances.ts (1 hunks)
  • hooks/useDeposit.tsx (1 hunks)
  • hooks/useGasFee.ts (1 hunks)
  • hooks/useWithdraw.tsx (1 hunks)
  • lib/utils.ts (1 hunks)
  • next-env.d.ts (1 hunks)
  • next.config.js (1 hunks)
  • package.json (1 hunks)
  • pages/_app.tsx (2 hunks)
  • pages/index.tsx (3 hunks)
  • postcss.config.mjs (1 hunks)
  • styles/globals.css (1 hunks)
  • utils/chainMap.ts (1 hunks)
  • utils/chains.ts (2 hunks)
  • utils/wagmiConfig.ts (1 hunks)
🧰 Additional context used
🧬 Code Definitions (9)
components/ui/input.tsx (1)
lib/utils.ts (1)
  • cn (5-7)
components/ui/label.tsx (1)
lib/utils.ts (1)
  • cn (5-7)
components/ui/card.tsx (1)
lib/utils.ts (1)
  • cn (5-7)
components/ui/button.tsx (1)
lib/utils.ts (1)
  • cn (5-7)
components/ui/form.tsx (2)
lib/utils.ts (1)
  • cn (5-7)
components/ui/label.tsx (1)
  • Label (24-24)
components/WrapperForm.tsx (3)
components/ui/form.tsx (5)
  • Form (158-158)
  • FormField (164-164)
  • FormItem (159-159)
  • FormControl (161-161)
  • FormMessage (163-163)
components/ui/input.tsx (1)
  • Input (21-21)
components/ui/button.tsx (1)
  • Button (59-59)
components/ui/navigation-menu.tsx (1)
lib/utils.ts (1)
  • cn (5-7)
pages/index.tsx (3)
components/ui/card.tsx (1)
  • Card (85-85)
components/ui/button.tsx (1)
  • Button (59-59)
lib/utils.ts (1)
  • cn (5-7)
components/ConnectWallet.tsx (4)
lib/utils.ts (1)
  • cn (5-7)
components/ui/button.tsx (1)
  • Button (59-59)
components/ui/navigation-menu.tsx (6)
  • NavigationMenu (159-159)
  • NavigationMenuList (160-160)
  • NavigationMenuItem (161-161)
  • NavigationMenuTrigger (163-163)
  • NavigationMenuContent (162-162)
  • NavigationMenuLink (164-164)
utils/general.ts (1)
  • truncateAddress (2-3)
🔇 Additional comments (75)
next-env.d.ts (1)

5-5: Documentation URL updated appropriately.

The URL has been updated to point to the latest TypeScript configuration documentation for Next.js.

next.config.js (1)

10-12: Image optimization disabled for static export.

Setting images.unoptimized to true is consistent with the static export configuration (output: 'export') since Next.js image optimization doesn't work with static exports.

However, be aware that disabling image optimization may impact page performance if images aren't optimized through alternative means.

Are you using any alternative image optimization strategy for the static build? If not, consider pre-optimizing images before adding them to the project or using an external image optimization service.

hooks/useGasFee.ts (1)

2-2:

✅ Verification successful

Updated wagmi hooks with equivalent functionality.

The changes appear to be adapting to API changes in the wagmi library:

  • Replaced useFeeData with useEstimateFeesPerGas
  • Replaced useNetwork with useAccount for accessing chain information

The functionality remains the same while keeping up with the library's latest API.

Verify that the chain data is consistently available via useAccount():

Also applies to: 5-6


🏁 Script executed:

#!/bin/bash
# Check for other uses of useNetwork in the codebase that might need updating
rg "useNetwork" --type ts --type tsx

Length of output: 64


Below is an updated review comment that highlights the wagmi hook changes and clarifies the verification step for chain data. Note that our original search command returned an error due to the tsx file type not being recognized. Please run the revised command below for manual verification to ensure that no residual usage of useNetwork exists:

Chain Data Consistency Check

  • The code now replaces useFeeData with useEstimateFeesPerGas and useNetwork with useAccount to retrieve chain information.
  • Verify that all instances previously using useNetwork have been updated, ensuring that chain data is consistently available via useAccount().

Please run the updated search command above and confirm that no instances of useNetwork remain, so we can confidently finalize these changes.


🏁 Script executed:

#!/bin/bash
# Revised command: Search for "useNetwork" in TypeScript and TSX files using file globs.
rg "useNetwork" -g "*.ts" -g "*.tsx"

Length of output: 158


Wagmi Hooks API Update Verification

The code now properly replaces the deprecated hooks:

  • useFeeDatauseEstimateFeesPerGas
  • useNetworkuseAccount (for chain information)

No references to useNetwork were found in TypeScript files by the revised search command. However, please manually verify that chain data is consistently available via useAccount(). You can run this command (ensuring you do not include the `` line as literal input):

This manual check will confirm that no obsolete usage remains.


🏁 Script executed:

rg "useNetwork" -g "*.ts" -g "*.tsx"

Length of output: 36


Wagmi Hooks API Update Approved

  • The updated hooks/useGasFee.ts now correctly imports and uses useAccount for accessing chain data and useEstimateFeesPerGas for fee estimation.
  • A search for any remaining occurrences of useNetwork in TypeScript files produced no output, supporting the conclusion that all instances have been updated.
  • Please perform a final manual check to ensure that chain data is consistently and correctly available via useAccount() across the codebase.
utils/wagmiConfig.ts (3)

19-24:

✅ Verification successful

Validate existence of custom chain icon.
Using the custom Gnosis icon under /chains/gnosis.jpg is a good approach. Ensure the icon file is actually present to avoid 404 errors in production.


🏁 Script executed:

#!/bin/bash
# Search for gnosis.jpg in the repository
fd gnosis.jpg

Length of output: 40


Custom Gnosis Icon Verified
The file public/chains/gnosis.jpg exists in the repository, and the usage of iconUrl: '/chains/gnosis.jpg' is consistent with serving static assets from the public directory. No further action is needed.


5-15:

❓ Verification inconclusive

Confirm chain support and naming consistency.
Additional chains (e.g., blast, base, zora) are included. Make sure all chain definitions, IDs, and names match the expected values on your application side.


🏁 Script executed:

#!/bin/bash
# Verify references to the chain names and IDs within the codebase to ensure consistency
rg -A 2 "chain.*(blast|base|zora)"

Length of output: 36


Please verify chain support and naming consistency

The automated search did not return any output regarding the references for blast, base, or zora. While the file utils/wagmiConfig.ts imports these chains from 'wagmi/chains' (lines 5–15), the grep search didn’t confirm any usages or references that would help verify their definitions and IDs against our expected values. Since this may be due to the search query’s limitations, please verify manually that:

  • The chain definitions (including blast, base, and zora) in 'wagmi/chains' match the expected IDs, names, and configurations used throughout the application.
  • All references to these chains in the codebase are consistent with the definitions.

2-3:

❓ Verification inconclusive

Use caution with environment-based configuration.
The imports from @rainbow-me/rainbowkit and wagmi look correct. However, if projectId is left empty, the default behavior might be unexpected. Consider verifying that NEXT_PUBLIC_PROJECT_ID is set in all required environments.


🏁 Script executed:

#!/bin/bash
# Check for presence of NEXT_PUBLIC_PROJECT_ID in environment and .env.* files
rg "NEXT_PUBLIC_PROJECT_ID" .env*

Length of output: 81


Configuration Verification Needed:
The import statements in utils/wagmiConfig.ts (lines 2–3) are correct. However, since the critical environment variable NEXT_PUBLIC_PROJECT_ID is used to configure the project, an empty or unset value may lead to unexpected defaults. The initial search in .env* files did not locate any instances of NEXT_PUBLIC_PROJECT_ID, so please manually verify that this variable is properly defined in all required deployment contexts (development, staging, production) via your environment configuration or alternative configuration files.

  • Ensure NEXT_PUBLIC_PROJECT_ID is set in your runtime environment or provided through another configuration mechanism.
  • Confirm that any alternative approaches to managing this environment variable are consistently applied across all deployment environments.
utils/chains.ts (5)

1-2: Updated imports improve code clarity.
Switching to getDefaultConfig from @rainbow-me/rainbowkit is consistent with the refactor in utils/wagmiConfig.ts and simplifies the chain config flow.


8-8: Confirm removal or deprecation of Goerli.
It’s commented out—verify that you no longer need Goerli for staging or testing. Otherwise, reintroduce it or confirm other test networks are sufficient.


13-13: Added Zora chain.
Ensure that the code referencing Zora’s chain is tested, including contract deployments, explorers, and faucets if needed.


23-50: Centralized configuration with RainbowKit.
Exporting a single default config is a clean approach. If you need to differentiate chain behaviors later (e.g., different providers per chain), you can still extend this configuration.


5-6:

✅ Verification successful

Double-check the new chain references.
base and blast are newly added. Make sure their IDs and endpoints are correct within the ecosystem.


🏁 Script executed:

#!/bin/bash
# Verify references to "base" and "blast" in the codebase for potential chain ID usage
rg -A 2 "base|blast"

Length of output: 6646


Verified chain references:
The grep search confirms that both base and blast are defined and used consistently across the ecosystem (e.g., in utils/chains.ts, utils/wagmiConfig.ts, and utils/chainMap.ts). Their identifiers and the corresponding endpoint mappings via http() match the patterns established by related chains (such as gnosis and zora). Please ensure that the actual endpoints behind these IDs are aligned with the expected configuration in our ecosystem.

hooks/useBalances.ts (4)

1-9: Refined imports and structure.
The addition of useQueryClient, useBlockNumber, and useReadContracts is a strong improvement for managing dynamic balance data.


19-24: Conditional enabling is appropriate.
Using enabled: !!address && !!contractAddress ensures you don’t fetch balance data unnecessarily. This approach helps avoid errors if the user is not connected or on an unsupported chain.


26-45: Group read contracts to reduce network overhead.
Fetching both balanceOf and decimals in the same query is a good pattern, consolidating multiple calls into one. No concerns here.


54-63:

✅ Verification successful

Accurate token formatting.
Formatting the balance data using formatUnits is correct for user display. Just ensure that the decimals property never conflicts with actual token decimals in edge cases.


🏁 Script executed:

#!/bin/bash
#!/usr/bin/env bash
# Attempt to detect references to tokens with decimals mismatches around the codebase
rg -A 2 "decimals.*="

Length of output: 221


Token Decimal Formatting Verified
The verification confirms that the decimals property is handled only in the expected location (hooks/useBalances.ts, lines 54-63) and is used correctly with formatUnits for user display. There’s no evidence of conflicting decimal values in the nearby code.

package.json (1)

13-35: Significant dependency updates indicate architectural UI shift.

The major updates to the dependencies reflect a comprehensive migration to modern UI libraries and Tailwind CSS, along with updated blockchain connectivity libraries.

postcss.config.mjs (1)

1-6:

❓ Verification inconclusive

Check the Tailwind PostCSS plugin name.

The plugin name @tailwindcss/postcss is unusual - the standard plugin name in most Tailwind setups is tailwindcss. Verify this matches the official documentation and your installed package.


🌐 Web query:

What is the correct postcss plugin name for tailwindcss?

💡 Result:

The correct PostCSS plugin name for Tailwind CSS depends on your version:

For Tailwind CSS v4+
Use @tailwindcss/postcss[9][15]. This is now a separate package requiring explicit installation and configuration:

// postcss.config.js
module.exports = {
  plugins: {
    "@tailwindcss/postcss": {}
  }
}

For Tailwind CSS v3
Use tailwindcss directly[1][4][7]:

// postcss.config.js
module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {}
  }
}

Key differences:

  • Version 4 requires installing @tailwindcss/postcss explicitly via npm[8][9]
  • Version 3 uses the core tailwindcss package as the plugin[4][7]
  • The v4 error message explicitly warns about this change: "The PostCSS plugin has moved to a separate package"[15]

If you encounter the error "It looks like you're trying to use tailwindcss directly as a PostCSS plugin", upgrade your configuration to use @tailwindcss/postcss and ensure you're running Tailwind v4+[15].

Citations:


Tailwind CSS Plugin Configuration – Verify Tailwind Version

Based on the official documentation, using @tailwindcss/postcss is correct for Tailwind CSS v4 and later. If your project is running v4 or above, no changes are necessary. However, if you’re using Tailwind CSS v3, you should update your configuration to use tailwindcss instead.

  • File: postcss.config.mjs (lines 1–6)
  • Action: Confirm your installed Tailwind CSS version to ensure that the plugin name matches the correct version requirement.
lib/utils.ts (1)

5-7: LGTM!

The cn utility function is a standard pattern for Tailwind projects that effectively combines clsx for conditional classes with twMerge for proper Tailwind class merging.

utils/chainMap.ts (1)

25-25: LGTM!

The export provides a clean interface for accessing the chain mappings throughout the application.

components/ui/input.tsx (1)

1-4: Imports look good.
No issues with the import statements. The usage of React and cn is in line with your typical patterns.

components/ui/label.tsx (1)

1-25: Looks great.
Clean usage of Radix Label and well-structured Tailwind classes. Accessibility and disabled states are nicely handled.

components/ui/sonner.tsx (1)

1-24: Implementation is clean and flexible.
Using useTheme with a fallback to "system" is a neat approach. The inline CSS variables nicely control the toast styling.

components/Header.tsx (2)

3-3: Unused import removal
Removing the commented-out import makes sense since it's no longer in use.


10-11: Tailwind approach
Switching to Tailwind utility classes is consistent with the broader refactor. The layout, spacing, and responsiveness are configured appropriately.

Also applies to: 14-14

components/TokenInfo.tsx (1)

2-3: Confirm the chain object from useAccount
Ensure the wagmi version you’re using actually provides chain from useAccount(). Consider verifying or updating references if needed.

Also applies to: 11-11

components/ui/card.tsx (8)

1-16: Card component
Good modular structure. Using cn for class concatenation is a neat approach.


18-29: CardHeader
Grid layout with utility classes is well-applied.


31-39: CardTitle
Straightforward, no concerns.


41-49: CardDescription
Clear usage of muted-foreground for descriptive text. Looks good.


51-62: CardAction
Positioning in second column for optional action elements is logical.


64-72: CardContent
Good usage of padding.


74-82: CardFooter
Including items-center for alignment is standard.


84-92: Exported components
Comprehensive grouping of card subcomponents.

components.json (1)

1-21: Validate Tailwind config references
The empty "config" field might need updating if you use a custom tailwind.config.js. Everything else looks aligned with a typical utility-first setup.

components/ui/button.tsx (2)

1-6: Well-structured imports for styling and radial slot usage.
The imports from React, @radix-ui/react-slot, and class-variance-authority look well-organized and appropriate for this component’s requirements.


38-57: Good approach with asChild and dynamic class merging.
The usage of Slot for rendering as a child element provides flexibility. The className={cn(buttonVariants({ variant, size, className }))} usage is also neat and clear.

styles/globals.css (2)

1-4: Imports for fonts and Tailwind integration verified.
You correctly import Google fonts, Tailwind, and the tw-animate-css library at the top, ensuring they load globally.


182-189:

❓ Verification inconclusive

Universal border styles may cause unintended overrides.
Applying @apply border-border outline-ring/50; inside a global * selector imposes borders and outlines on all elements, including semantic tags and container elements. Confirm that this is the intended design choice.


🏁 Script executed:

#!/bin/bash
# Checking for local overrides of border or outline classes
rg -A3 "border-border" 

Length of output: 195


Attention: Verify the Intentional Use of Global Border Styles

The rule in styles/globals.css (lines 182–189) applies @apply border-border outline-ring/50; using the universal selector, which could unintentionally affect all elements, including semantic and container elements. The grep search confirms that this styling is defined only in the global file, with no local overrides present. Please verify that applying these universal border and outline styles is the intended design choice. If not, consider narrowing the scope of these styles.

pages/_app.tsx (3)

1-2: Efficient adoption of React Query & analytics.
Transitioning to @tanstack/react-query for data fetching and adding Vercel Analytics is a cohesive update.

Also applies to: 6-6, 8-10


17-17: Single shared QueryClient instance.
Defining queryClient outside the component is best practice for React Query, avoiding re-creation on each render.


29-37: Layered provider structure looks correct.
WagmiProviderQueryClientProviderRainbowKitProvider is logically ordered. Including Toaster after these providers ensures toast notifications function alongside your app’s state.

hooks/useDeposit.tsx (4)

1-3: Seamless switch to sonner toast and useDebounceValue.
Your migration away from the previous toast and debounce hooks is consistent. The switch helps maintain a uniform notification approach across the codebase.


17-31: Robust fallback handling for malformed input.
Returning BigInt(0) if the debounced value is invalid ensures the contract call won’t fail on parse errors.


42-48: Success and error toasts are well-handled.
The transaction’s “pending” and “error” states dispatch appropriate toast notifications. This is good feedback for the user.


62-86: One-time success toast logic is implemented correctly.
Keeping a ref-based short-circuit check prevents repeated success notifications for subsequent renders.

components/ui/form.tsx (2)

74-86: Validate nested usage of FormItem.
FormItem generates a unique id internally. Further nested or repeated usage of FormItem within the same hierarchy might inadvertently override or reuse these contexts. If nesting multiple form items is intentional, ensure each usage is distinct or consider scoping the IDs more explicitly.


136-154: Guard against untrusted error messages.
In FormMessage, you convert error?.message to a string. If these messages can come from user or external input, ensure you sanitize or validate them before rendering to avoid potential injection or other security concerns.

pages/index.tsx (1)

44-45: Ensure intentional full-screen scrolling behavior.
You set className='h-screen w-screen max-w-full bg-background overflow-auto'. This enforces a full-screen layout with auto-scroll. Verify that this is the desired user experience, as it might limit nested scroll containers.

components/WrapperForm.tsx (7)

2-3: Good usage of react-hook-form & zod
You are making effective use of type inference and validation, which helps maintain strong typing and data integrity.


9-11: Consistent usage of local UI components
Switching from external design components to local ones fosters consistency and easier customization.


20-24: Ensure correct data type from form
Defining the z.number().min(0) schema prevents invalid requests and early user errors.


33-37: Proper typed form
Using z.infer<typeof formSchema> keeps the form strongly typed, minimizing runtime issues.


60-64: Avoid logging sensitive info
Please confirm that console.log(data) does not leak confidential details in production.

Potentially guard or remove console logs in non-development environments.


85-86: Layout changes
Adding spacing with utility classes looks fine.


121-128: Button usage
Utilizing the local Button component with variant styling is consistent and clear.

hooks/useWithdraw.tsx (9)

1-3: New library usage
Using the toast from 'sonner' and useDebounceValue from 'usehooks-ts' effectively addresses feedback and debouncing.


6-10: WAGMI hooks
Leveraging WAGMI’s hooks for contract interactions is a robust approach.


16-18: Verify chain existence
Consider handling a scenario where chain is undefined if the user is disconnected.

Offer to implement a safe fallback for missing chain data.


20-26: Contract pre-flight check
Simulating the contract call before writing is a great way to catch errors early.


47-49: Clever toast gating
Storing displayed transaction hashes in a ref avoids repeated toasts for the same transaction.


50-58: Comprehensive transaction tracking
useWaitForTransactionReceipt properly ensures you wait for final confirmation.


60-71: Single-show toast logic
Your useEffect approach prevents redundant success notifications. Nicely done.


73-78: Conditional execution
Checking simulateData?.request prevents invalid writes. This is a good safeguard.


81-90: Comprehensive hook return
Aggregate states for confirmation, errors, and pending statuses simplifies the UI logic.

components/ui/navigation-menu.tsx (11)

1-7: Clean import organization
All necessary imports are consolidated in a straightforward manner.


8-30: Well-implemented NavigationMenu
Leveraging the viewport prop keeps the menu modular and flexible.


32-46: List structure
Separating NavigationMenuList into its own component clarifies layout responsibilities.


48-59: Item wrapper
Good job ensuring each item is a self-contained component in the menu hierarchy.


61-64: Leverage cva
Utilizing class-variance-authority helps unify styling and theme control for triggers.


65-83: NavigationMenuTrigger
The icon animation upon opening or closing is user-friendly and visually clear.


85-100: Menu content transitions
The fade-in and slide-in animations yield a smooth user experience.


102-122: Viewport container
Positioning and isolation logic ensure the menu’s viewport renders smoothly without conflicts.


124-138: NavigationMenuLink
Using data attributes for interactive styling is consistent and flexible for future expansions.


140-156: Indicator styling
The 45° rotated box elegantly serves as an arrow indicator. Good use of transitions.


158-168: Unified exports
Exporting related menu components in one place promotes reusability and clear imports.

@nitegeist nitegeist marked this pull request as draft March 29, 2025 22:59
@nitegeist nitegeist marked this pull request as ready for review April 4, 2025 03:18
This was linked to issues Apr 4, 2025
@nitegeist nitegeist requested a review from scottrepreneur April 4, 2025 03:19
Copy link

@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: 3

🧹 Nitpick comments (20)
hooks/useDeposit.tsx (1)

39-41: Provide more descriptive error feedback
The error message 'Error... transaction reverted...' is somewhat generic. Providing a more informative message—such as "Transaction failed. Check your wallet or blockchain explorer for details."—can help users troubleshoot.

- error: 'Error... transaction reverted...'
+ error: 'Deposit failed. Please check the transaction details or try again.'
app/layout.tsx (1)

37-47: Conditionally render analytics in production
If you’d prefer to avoid analytics in non-production environments, consider adding an environment check:

- <Analytics mode='production' />
+ {process.env.NODE_ENV === 'production' && <Analytics mode='production' />}
hooks/useChainSwitch.ts (2)

27-53: Consider refactoring complex chain update logic.

The handleChainUpdate function handles multiple conditions and performs several operations. Consider breaking it down into smaller helper functions to improve readability and maintainability.

 const handleChainUpdate = useCallback(async () => {
   if (!isConnected || !accountChain || isSyncing || chainModalOpen) return;

-  const searchParams = new URLSearchParams(window.location.search);
-  const chainName = searchParams.get('chain')?.toLowerCase() || null;
-  const currentChainName = chainMappings[accountChain.id];
+  const { chainName, currentChainName } = getChainNames(accountChain.id);

   if (
     chainName &&
     chainMappings[chainName] &&
     chainMappings[chainName] !== accountChain.id
   ) {
-    const targetChain = chains.find((c) => c.id === chainMappings[chainName]);
-    if (targetChain) {
-      setIsSyncing(true);
-      try {
-        await switchChain({ chainId: targetChain.id });
-        updateUrl(chainName);
-      } finally {
-        setTimeout(() => setIsSyncing(false), 500);
-      }
-    }
+    await switchToNewChain(chainName);
   } else if (currentChainName && chainName !== currentChainName) {
     setIsSyncing(true);
     updateUrl(currentChainName);
     setTimeout(() => setIsSyncing(false), 500);
   }
 }, [
   // dependencies remain the same
 ]);

+const getChainNames = (accountChainId: number) => {
+  const searchParams = new URLSearchParams(window.location.search);
+  const chainName = searchParams.get('chain')?.toLowerCase() || null;
+  const currentChainName = chainMappings[accountChainId];
+  return { chainName, currentChainName };
+};

+const switchToNewChain = async (chainName: string) => {
+  const targetChain = chains.find((c) => c.id === chainMappings[chainName]);
+  if (targetChain) {
+    setIsSyncing(true);
+    try {
+      await switchChain({ chainId: targetChain.id });
+      updateUrl(chainName);
+    } finally {
+      setTimeout(() => setIsSyncing(false), 500);
+    }
+  }
+};

46-47: Consider adding proper error handling.

The try-finally block should include a catch clause to properly handle and log any errors that might occur during chain switching.

 try {
   await switchChain({ chainId: targetChain.id });
   updateUrl(chainName);
+} catch (error) {
+  console.error('Error switching chain:', error);
+  // Consider adding user feedback for failed chain switches
 } finally {
   setTimeout(() => setIsSyncing(false), 500);
 }
hooks/useBalances.ts (2)

19-24: Consider extracting the common enabled condition.

The same enabled condition !!address && !!contractAddress is used multiple times. Consider extracting it to a variable for better maintainability.

+const isQueryEnabled = !!address && !!contractAddress;

 const { data: ethBalanceData, queryKey: ethQueryKey } = useBalance({
   address,
   query: {
-    enabled: !!address && !!contractAddress,
+    enabled: isQueryEnabled,
   },
 });

54-63: Consider safer type handling for contract results.

Using type assertions for balanceResult and decimalsResult could lead to runtime errors if the returned types don't match expectations. Consider more robust type checking.

-const balanceResult = wethBalanceData?.[0]?.result as bigint | undefined;
-const decimalsResult = wethBalanceData?.[1]?.result as number | undefined;
+const balanceResult = typeof wethBalanceData?.[0]?.result === 'bigint' 
+  ? wethBalanceData[0].result 
+  : undefined;
+const decimalsResult = typeof wethBalanceData?.[1]?.result === 'number' 
+  ? wethBalanceData[1].result 
+  : undefined;

 const wethBalance =
   balanceResult && decimalsResult
     ? formatUnits(balanceResult, decimalsResult)
     : '0';
components/ConnectWallet.tsx (2)

59-71: Consider extracting button styles to a common variable.

The button styles are quite lengthy. Consider extracting them to reusable variables or custom classes for better maintainability.

+const connectButtonClasses = 'bg-purple-600 text-purple-50 rounded-xs uppercase transition-all duration-100 ease-in-out hover:bg-purple-600 hover:border-2 hover:border-purple-50';

 <Button
-  className='bg-purple-600 text-purple-50 rounded-xs uppercase transition-all duration-100 ease-in-out hover:bg-purple-600 hover:border-2 hover:border-purple-50'
+  className={connectButtonClasses}
   disabled={mounted ? isConnecting : false}
   onClick={openConnectModal}
   data-cy='connect-wallet'
   variant='default'
 >

103-136: Consider extracting NavigationMenuLink components.

The NavigationMenuLink components have repeated styling patterns. Consider extracting them to a reusable component.

+const MenuLink = ({ 
+  onClick, 
+  icon, 
+  text, 
+  textColor = 'text-white',
+  iconColor = 'text-white'
+}) => (
+  <NavigationMenuLink
+    onClick={onClick}
+    className="hover:bg-gray-600 select-none"
+  >
+    <div className='flex items-center gap-2'>
+      <span className={iconColor}>{icon}</span>
+      <p className={textColor}>{text}</p>
+    </div>
+  </NavigationMenuLink>
+);

 <ul className="w-[150px]">
-  <NavigationMenuLink
-    onClick={() => openAccountModal()}
-    className="hover:bg-gray-600 select-none"
-  >
-    <div className='flex items-center gap-2'>
-      <FiKey className='text-white' />
-      <p className='text-white'>Wallet</p>
-    </div>
-  </NavigationMenuLink>
-  <NavigationMenuLink
-    onClick={() => disconnect()}
-    className="hover:bg-gray-600 select-none"
-  >
-    <div className='flex items-center gap-2'>
-      <FiXCircle className='text-red-300' />
-      <p className='text-red-300'>Sign Out</p>
-    </div>
-  </NavigationMenuLink>
+  <MenuLink 
+    onClick={() => openAccountModal()} 
+    icon={<FiKey />} 
+    text="Wallet" 
+  />
+  <MenuLink 
+    onClick={() => disconnect()} 
+    icon={<FiXCircle />} 
+    text="Sign Out" 
+    textColor="text-red-300"
+    iconColor="text-red-300"
+  />
 </ul>
app/providers.tsx (1)

59-146: Consider refactoring the repetitive transport configuration.

The transport configuration is highly repetitive across different chains. Consider extracting this into a helper function.

+const createChainTransport = (chainId: number, chainName: string) => {
+  return fallback([
+    http(),
+    http(`https://${chainName}.infura.io/v3/${process.env.NEXT_PUBLIC_RPC_KEY}`),
+    http(
+      `https://${chainName === 'mainnet' ? 'eth' : chainName}-${
+        chainName === 'mainnet' ? '' : 'mainnet'
+      }.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`,
+    ),
+  ]);
+};

 transports: {
-  [mainnet.id]: fallback([
-    http(),
-    http(`https://mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_RPC_KEY}`),
-    http(
-      `https://eth-mainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`,
-    ),
-  ]),
+  [mainnet.id]: createChainTransport(mainnet.id, 'mainnet'),
-  [customGnosis.id]: fallback([
-    http(),
-    http(`https://gnosis.infura.io/v3/${process.env.NEXT_PUBLIC_RPC_KEY}`),
-    http(
-      `https://gnosis-mainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`,
-    ),
-  ]),
+  [customGnosis.id]: createChainTransport(customGnosis.id, 'gnosis'),
   // Similarly for other chains...
styles/globals.css (2)

99-132: Dark theme contrast could be improved

The dark theme's background color (#171923) is very similar to the light theme's background color (#1a202c), creating minimal visual differentiation between themes. Consider using a greater contrast difference.

.dark {
-  --background: #171923; /* colors.gray.900 */
+  --background: #0f1117; /* darker shade for better contrast */
  --foreground: #ffffff; /* colors.base.white */

130-132: Potential WCAG contrast issues with sidebar-border

The --sidebar-border: oklch(1 0 0 / 10%) in dark mode may have insufficient contrast for accessibility standards. Consider increasing the opacity or using a more visible color for better accessibility.

  --sidebar-accent-foreground: oklch(0.985 0 0);
-  --sidebar-border: oklch(1 0 0 / 10%);
+  --sidebar-border: oklch(1 0 0 / 20%);
  --sidebar-ring: oklch(0.556 0 0);
app/page.tsx (5)

15-37: Consider enhancing state management logic

The current implementation uses basic state management with a boolean toggle for deposit state. For better maintainability, consider using an enum or constants for action types.

-	const [deposit, setDeposit] = useState<boolean>(true);
+	type ActionType = 'deposit' | 'withdraw';
+	const [action, setAction] = useState<ActionType>('deposit');

	const onButtonSelection = (index: number) => {
		switch (index) {
			case 0:
-				setDeposit(true);
+				setAction('deposit');
				break;
			case 1:
-				setDeposit(false);
+				setAction('withdraw');
				break;
			default:
				// eslint-disable-next-line no-console
				console.log(`Invalid input: ${index}`);
		}
	};

33-35: Remove or improve console.log in production code

The console.log statement should be removed or replaced with proper error handling in production code.

			default:
-				// eslint-disable-next-line no-console
-				console.log(`Invalid input: ${index}`);
+				// No-op or add proper error handling

44-73: Fixed padding may cause responsive design issues

The Card component uses a fixed padding (p-32) which might not be responsive on smaller screens. Consider using responsive padding values.

-			<Card className='mt-6 p-32 w-full border-2 border-white rounded-xs'>
+			<Card className='mt-6 p-8 md:p-16 lg:p-32 w-full border-2 border-white rounded-xs'>

65-73: Improve conditional rendering with ternary operator

The conditional rendering is good, but you can make it more concise by using a ternary operator directly in the component tree.

-				{mounted && isConnected ? (
-					<WrapperForm action={deposit ? 'deposit' : 'withdraw'} />
-				) : (
-					<h1 className='mt-5 font-uncial font-semibold text-2xl text-white text-center'>
-						Connect to {deposit ? 'wrap' : 'unwrap'} ETH
-					</h1>
-				)}
+				{mounted && isConnected 
+					? <WrapperForm action={deposit ? 'deposit' : 'withdraw'} />
+					: <h1 className='mt-5 font-uncial font-semibold text-2xl text-white text-center'>
+						Connect to {deposit ? 'wrap' : 'unwrap'} ETH
+					  </h1>
+				}

75-87: Improve responsive layout for footer

The footer with the RaidGuild link uses a fixed margin (mr-48) which might cause layout issues on smaller screens. Consider using a more responsive approach.

-			<div className='flex justify-center md:justify-end w-full my-6 mr-48'>
+			<div className='flex justify-center md:justify-end w-full my-6 px-4 md:pr-12 lg:pr-24'>
components/WrapperForm.tsx (4)

52-61: Remove any type for better type safety

The handleSetMax function is typed as any, which reduces type safety. Consider using a proper function type.

-  const handleSetMax: any = (): void => {
+  const handleSetMax = (): void => {

68-84: Remove commented code

The commented-out validation code should be removed as it's no longer needed and clutters the codebase.

-  // const customValidations = {
-  //   required: 'Input cannot be blank',
-  //   validate: (value: number) => {
-  //     if (action === 'deposit') {
-  //       return value > 0 && value < +ethBalance - +txFeeEther;
-  //     }
-  //     return value > 0 && value <= +wethBalance;
-  //   },
-  //   max: {
-  //     value: action === 'deposit' ? +ethBalance - +txFeeEther : +wethBalance,
-  //     message: `Input must be less than your full balance, plus transaction fees...`,
-  //   },
-  //   min: {
-  //     value: 0,
-  //     message: 'Value must be greater than 0',
-  //   },
-  // };

132-133: Remove empty div

The empty div at the end of the component doesn't serve any purpose and should be removed.

-      <div className='flex justify-center mt-5 text-white' />

91-130: Add loading state for better UX

Consider adding a loading state to the Submit button during transaction processing to provide better user feedback.

+  const [isSubmitting, setIsSubmitting] = useState(false);

  const onSubmit = async (data: z.infer<typeof formSchema>) => {
+    setIsSubmitting(true);
    if (data.amount > 0 && action === 'deposit' && writeDeposit) writeDeposit();
    else if (data.amount > 0 && action === 'withdraw' && writeWithdraw) writeWithdraw();
+    setIsSubmitting(false);
  };

// In the button JSX:
  <Button
    variant='default'
    type='submit'
    className='w-full rounded-xs bg-purple-600 uppercase'
+    disabled={isSubmitting}
  >
-    Submit
+    {isSubmitting ? 'Processing...' : 'Submit'}
  </Button>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 53d6d7b and 75ef84b.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (19)
  • app/layout.tsx (1 hunks)
  • app/page.tsx (1 hunks)
  • app/providers.tsx (1 hunks)
  • components/ConnectWallet.tsx (1 hunks)
  • components/WrapperForm.tsx (3 hunks)
  • components/ui/skeleton.tsx (1 hunks)
  • hooks/useBalances.ts (1 hunks)
  • hooks/useChainSwitch.ts (1 hunks)
  • hooks/useDeposit.tsx (1 hunks)
  • hooks/useWithdraw.tsx (1 hunks)
  • next-env.d.ts (1 hunks)
  • next.config.js (0 hunks)
  • package.json (1 hunks)
  • pages/_app.tsx (0 hunks)
  • pages/index.tsx (0 hunks)
  • styles/globals.css (1 hunks)
  • tsconfig.json (2 hunks)
  • utils/chainMap.ts (1 hunks)
  • utils/chains.ts (2 hunks)
💤 Files with no reviewable changes (3)
  • next.config.js
  • pages/index.tsx
  • pages/_app.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • next-env.d.ts
  • utils/chainMap.ts
🧰 Additional context used
🧬 Code Definitions (5)
hooks/useDeposit.tsx (1)
utils/wagmiConfig.ts (1)
  • wagmiConfig (26-53)
components/ConnectWallet.tsx (4)
lib/utils.ts (1)
  • cn (5-7)
components/ui/button.tsx (1)
  • Button (59-59)
components/ui/navigation-menu.tsx (6)
  • NavigationMenu (159-159)
  • NavigationMenuList (160-160)
  • NavigationMenuItem (161-161)
  • NavigationMenuTrigger (163-163)
  • NavigationMenuContent (162-162)
  • NavigationMenuLink (164-164)
utils/general.ts (1)
  • truncateAddress (2-3)
app/layout.tsx (1)
app/providers.tsx (1)
  • Provider (148-160)
hooks/useWithdraw.tsx (1)
utils/wagmiConfig.ts (1)
  • wagmiConfig (26-53)
components/WrapperForm.tsx (3)
components/ui/form.tsx (5)
  • Form (158-158)
  • FormField (164-164)
  • FormItem (159-159)
  • FormControl (161-161)
  • FormMessage (163-163)
components/ui/input.tsx (1)
  • Input (21-21)
components/ui/button.tsx (1)
  • Button (59-59)
🔇 Additional comments (42)
hooks/useDeposit.tsx (2)

14-16: Guard against a null or undefined wallet address
Similar to a previous review comment, there's still no safeguard in place if address is null or undefined. This can cause unexpected behavior if a user attempts a deposit without a connected wallet.


33-33: Validate user input to prevent negative or invalid amounts
parseEther(debouncedValue.toString()) may fail or produce unexpected results if debouncedValue is non-numeric or negative. Consider adding a check to enforce valid and positive inputs before attempting the deposit.

Would you like me to generate a shell script to see if any upstream code guards against invalid debouncedValue usage beyond this file?

app/layout.tsx (2)

22-28: Good use of Next.js metadata configuration
Defining the application’s title, description, and favicon via metadata aligns well with recommended Next.js patterns.


30-35: Viewport rules are correctly implemented
Applying theme-specific colors in this manner ensures consistent UI theming across light/dark modes.

utils/chains.ts (1)

37-99:

✅ Verification successful

Verify environment variables for Infura & Alchemy
Multiple fallback URLs rely on NEXT_PUBLIC_RPC_KEY and NEXT_PUBLIC_ALCHEMY_KEY. Ensure both are defined to prevent invalid or failing connections on certain chains.


🏁 Script executed:

#!/bin/bash
# Description: checking all references to environment variables relevant to your fallback configuration
rg "NEXT_PUBLIC_(RPC_KEY|ALCHEMY_KEY)" -A2

Length of output: 5109


Environment Variable Consistency for Infura & Alchemy Endpoints

The fallback URLs in utils/chains.ts and similar references in app/providers.tsx consistently use the NEXT_PUBLIC_RPC_KEY and NEXT_PUBLIC_ALCHEMY_KEY environment variables. Please ensure that both variables are properly defined in your deployment environment (using, for example, a .env file) since placeholder values in env.example indicate that valid keys must be provided. This will help prevent connection failures on any chain relying on these endpoints.

hooks/useChainSwitch.ts (2)

9-17: State management and account details are well structured.

The hook properly retrieves account and chain information from wagmi hooks. The isSyncing state helps prevent multiple chain updates from occurring simultaneously.


18-25: Clean URL parameter handling with proper memoization.

The updateUrl function uses URLSearchParams correctly to manage query parameters and is properly memoized with useCallback.

hooks/useBalances.ts (4)

13-15: Good extraction of account details and contract address.

The code correctly extracts the account address and chain from useAccount, and determines the contract address using the chain name.


17-17: Effective use of block number subscription.

Using useBlockNumber with watch: true is an excellent way to keep track of new blocks for refreshing balances.


26-45: Good use of contract batching for efficiency.

Using useReadContracts to fetch both balanceOf and decimals in a single call is an efficient approach.


47-52: Good practice for query invalidation.

Invalidating the queries when the block number changes ensures balances stay up-to-date with blockchain state.

components/ConnectWallet.tsx (4)

16-23: Good state management and provider integration.

The component properly uses the Wagmi hooks and integrates the new useChainSwitch hook.


25-35: Effective synchronization with chain modal state.

The useEffect properly updates the URL when the chain modal closes, ensuring the UI remains in sync with the selected chain.


37-39: Clean implementation of chain update effect.

The second useEffect calls handleChainUpdate at the right time and includes the proper dependency.


84-137: Great UI improvements with NavigationMenu.

The connected state UI has been significantly improved with better organization using NavigationMenu components. The chain selection button now displays useful visual information.

app/providers.tsx (3)

26-48: Effective query client management with server/client handling.

The code properly handles query client creation differently for server and client environments, which is a good pattern for Next.js applications.


52-57: Good customization of Gnosis chain display.

Adding custom icon and styling for the Gnosis chain improves the user experience.


148-160: Clean Provider implementation with proper nesting.

The Provider component is well-structured with the correct nesting order of providers. Including the Toaster here ensures it's available throughout the application.

hooks/useWithdraw.tsx (6)

1-2: Good move replacing toast with sonner and using useDebounceValue.

The change from a UI component library toast to sonner and updating the debounce hook improves consistency with other files in the project.


4-9: Proper import restructuring for the wagmi v2 API.

The changes correctly adapt to the new wagmi v2 API by:

  1. Adding waitForTransactionReceipt for transaction tracking
  2. Replacing useNetwork with useAccount for accessing chain information
  3. Using useWriteContract instead of the previously separated preparation and execution hooks

This modernization aligns with current best practices for blockchain interactions.


14-16: Chain access and debounce implementation look good.

Properly extracting the chain from useAccount and using the debounced value with the appropriate timeout.


18-22: Improved state management with useWriteContract.

The hook properly destructures the necessary states from useWriteContract for better tracking of the transaction status.


24-46: Well-implemented async transaction flow with user feedback.

The executeWithdraw function is well structured with:

  1. Promise-based toast notifications
  2. Proper async/await pattern
  3. Error handling with console logging
  4. Clear success messaging that dynamically shows the chain's native currency symbol

This provides a much better user experience than the previous implementation.


48-53: Enhanced return object with more detailed transaction states.

The updated return object provides better transaction state management by:

  1. Replacing the old withdraw function with the new executeWithdraw
  2. Including isWritePending and isWriteError states
  3. Adding a canWithdraw flag based on the debounced value

This allows consuming components to show appropriate UI states during transactions.

tsconfig.json (4)

42-66: Improved path aliases for better module resolution.

The expanded path configuration provides more granular and explicit mappings for different directories, which:

  1. Makes imports more readable and maintainable
  2. Improves IDE autocomplete suggestions
  3. Prevents path resolution ambiguities

This change will make development more efficient and reduce import-related errors.


87-92: Added Next.js TypeScript plugin for enhanced type checking.

The Next.js plugin addition is important as it enables:

  1. Better type checking for Next.js specific features
  2. Auto-completion for Next.js specific props and components
  3. Integration with the Next.js compiler

This is a necessary addition when working with modern Next.js applications.


94-102: Updated include paths to match project structure.

The include paths have been properly updated to:

  1. Add the app directory (for App Router)
  2. Include hooks directory explicitly
  3. Add Next.js generated types
  4. Remove the pages directory (likely transitioning to App Router)

These changes align with modern Next.js project structures.


103-106: Added node_modules to exclude list.

Adding node_modules to the exclude list is a good practice to:

  1. Improve TypeScript compilation performance
  2. Prevent potential type conflicts with node_modules

This is especially important for large projects with many dependencies.

package.json (2)

13-35: Major dependency upgrade with modern UI components.

The dependency updates make significant improvements:

  1. Added Radix UI components for accessible, unstyled UI primitives
  2. Updated wagmi/viem to v2 for improved blockchain interactions
  3. Added styling utilities like clsx and tailwind-merge
  4. Added sonner for toast notifications
  5. Updated React to v19 and Next.js to v15

These changes modernize the tech stack and improve component architecture.


38-38: Verify Tailwind and PostCSS version compatibility.

The specified versions for tailwindcss (^4.0.17) and PostCSS (^8.5.3) appear unusually high compared to the current stable releases.

Also applies to: 52-53

components/ui/skeleton.tsx (1)

1-13: Well-implemented Skeleton component for loading states.

This is a clean and reusable Skeleton component with:

  1. Proper use of the utility function for class name merging
  2. Appropriate animation for loading states
  3. Flexible props spreading for customization
  4. Data attribute for potential styling/testing hooks

The component follows modern React patterns and will be useful for consistent loading states throughout the application.

styles/globals.css (5)

4-97: Well-organized color system with comprehensive variables

The CSS variables defined here create a solid foundation for theming across the application. The commented color references (e.g., /* colors.gray.800 */) provide helpful context about the color system.


178-185: Well-structured Tailwind layering

Good use of Tailwind's @layer base to apply universal styling to all elements and set default styles for the body.


187-209: Excellent gradient utility classes

The gradient utility classes provide an easy way to apply consistent gradients across the application. This approach follows the best practice of abstracting complex styles into reusable utility classes.


134-176:

✅ Verification successful

Validate non-standard @theme directive compatibility

The @theme and @theme inline directives appear to be non-standard CSS. Verify that your build system properly processes these directives to avoid potential browser compatibility issues.


🌐 Web query:

Is @theme a standard CSS directive or part of a specific CSS preprocessor?

💡 Result:

The @theme directive is not a standard CSS feature but rather a tool-specific construct used in certain frameworks and preprocessors. Here's a breakdown:


Tailwind CSS Implementation

@theme is a Tailwind-specific directive that defines design tokens influencing utility classes and responsive variants. Key characteristics:

  • Utility class generation: Variables in specific namespaces (like --font-*, --breakpoint-*) automatically create corresponding utility classes (e.g., font-script, 3xl:* variants) [1][4].
  • Top-level requirement: Variables must be defined globally, not nested under selectors/medias [1].
  • Dynamic CSS output: Unlike standard CSS variables, @theme modifies Tailwind's generated utility classes [1][4].

Example:

@import "tailwindcss";
@theme {
  --font-script: Great Vibes, cursive;
  --breakpoint-3xl: 120rem;
}

Marpit Framework Usage

Marpit (a Markdown slide framework) also uses @theme in its theme system:

  • Slide viewport definition: Targets <section> elements as slide containers, with :root referring to each slide’s section [10].
  • Metadata requirement: Requires /* @theme name */ comment for theme identification [10].

Standard CSS Context

Standard CSS does not include @theme:

  • CSS variables are defined via :root or element selectors.
  • Native at-rules include @media, @keyframes, and @font-face, but no @theme [7][8].

Comparison Table

Feature Tailwind CSS @theme Standard CSS Variables (:root)
Purpose Generates utility classes Defines reusable values
Scope Global (Tailwind-specific) Global or scoped
Framework dependency Required None
Browser support Via Tailwind processing Native (CSS Custom Properties)

Conclusion: @theme is a custom directive used by Tailwind CSS and Marpit for framework-specific theming systems, not part of standard CSS or general-purpose preprocessors like Sass/Less.

Citations:


Non-Standard @theme Directive Compatibility Check

The @theme and @theme inline blocks are not part of standard CSS—they are custom directives typically used with frameworks like Tailwind CSS or Marpit. Please ensure your build system (e.g., Tailwind's configuration) is correctly processing these directives so that the final CSS output is compatible with browsers. If your build pipeline is properly configured for these constructs, no further changes are needed.


1-3:

✅ Verification successful

Verify Tailwind imports approach

The imports used here differ from Tailwind's typical approach. Standard practice is to use Tailwind directives (@tailwind base;, etc.) rather than CSS imports.


🌐 Web query:

What is the correct way to import Tailwind CSS in a CSS file?

💡 Result:

To import Tailwind CSS in a CSS file, the correct approach varies by version but has been significantly simplified in Tailwind CSS v4.0:

Modern Approach (Tailwind CSS v4.0+)

  1. Single Import Directive
    Add the following line at the top of your CSS file:

    @import "tailwindcss";

    This replaces the legacy @tailwind base, @tailwind components, and @tailwind utilities directives with a single import[4][5].

  2. Optional Theme Configuration
    Define custom design tokens directly in your CSS using @theme:

    @import "tailwindcss";
    @theme {
      --font-display: "Satoshi", "sans-serif";
      --color-primary: oklch(0.84 0.18 117.33);
      --breakpoint-3xl: 1920px;
    }

    This CSS-first configuration replaces tailwind.config.js[5][8].

Legacy Approach (Pre-v4)

For older versions, use these steps:

  1. Install Required Packages

    npm install postcss-import tailwindcss autoprefixer
  2. Configure PostCSS
    Add postcss-import first in your postcss.config.js:

    module.exports = {
      plugins: {
        'postcss-import': {},
        'tailwindcss/nesting': {}, // For nested CSS
        tailwindcss: {},
        autoprefixer: {},
      }
    }
  3. Import Tailwind Layers
    In your main CSS file:

    @import "tailwindcss/base";
    @import "tailwindcss/components";
    @import "tailwindcss/utilities";

Key Differences in v4

  • Zero configuration: No tailwind.config.js required[5]
  • Built-in nesting: Uses native CSS nesting instead of Sass-like syntax[9]
  • Lightning CSS: Replaces PostCSS for faster builds[5]
  • CSS Variables: All theme values are exposed as CSS custom properties (var(--color-primary))[8]

Common Pitfalls

  • Import order: In older versions using postcss-import, @import statements must come before other CSS rules[1]
  • Legacy projects: Migrate from @tailwind directives to @import "tailwindcss" when upgrading to v4[5]
  • External styles: Use separate files for imports vs. CSS rules to avoid spec compliance issues[1]

For new projects, Tailwind recommends the v4 approach for its simplicity and modern CSS standards compliance[4][5].

Citations:


Tailwind CSS Import Verification

  • The import @import "tailwindcss"; is correct and aligns with the modern Tailwind CSS v4.0+ approach.
  • The legacy use of individual @tailwind base;, @tailwind components;, and @tailwind utilities; directives applies primarily to earlier versions.
  • Ensure that the separate import for tw-animate-css is intentional and integrates properly with your project.
app/page.tsx (1)

1-14: Good setup with required imports

Appropriate imports are included for the required functionality, with client-side rendering enabled via the 'use client' directive.

components/WrapperForm.tsx (5)

2-11: Good migration to modern UI components

The component has been effectively updated to use modern form components with proper imports from local UI components, replacing the older design system dependencies.


27-34: Well-structured zod validation schema

The zod schema provides clear error messages and appropriate validation rules for the form input. Good use of dynamic max validation based on the current action and balance.


36-40: Type-safe form with zod integration

Great implementation using zod schema for type inference with react-hook-form, which provides type safety and improves code reliability.


63-66: Good implementation of typed submission handler

The onSubmit function now properly accepts and uses the typed data from the zod schema, improving type safety.


87-130: Clean and structured form implementation

The form implementation is well-structured using the new UI components, with appropriate layout and styling. The form elements are organized logically and provide clear feedback through FormMessage.

Copy link

@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

♻️ Duplicate comments (1)
hooks/useDeposit.tsx (1)

24-47: ⚠️ Potential issue

Guard Against Unconnected Wallet in Deposit Execution

The executeDeposit function doesn't check if address is defined before attempting the transaction, which could lead to errors when the wallet is disconnected.

Add a guard clause to prevent execution when the wallet is not connected:

const executeDeposit = async () => {
  try {
+   if (!address) {
+     toast.error('Please connect your wallet first');
+     return;
+   }
    toast.promise(
      // rest of the function...

Additionally, the error handling could be more specific:

  } catch (error) {
    console.error('Deposit error:', error);
+   toast.error(error instanceof Error ? error.message : 'Unknown error occurred');
  }
🧹 Nitpick comments (3)
utils/wagmiConfig.ts (2)

2-14: Import structure looks good but consider organizing imports.

The imports are structured well with all chains imported from 'wagmi/chains'. Good job removing the wallet-specific connectors in favor of the more streamlined getDefaultConfig approach.

Consider organizing your imports alphabetically within the grouped import for better readability:

import {
  arbitrum,
  base,
  blast,
  gnosis,
  mainnet,
  optimism,
  polygon,
  sepolia,
  zora,
} from 'wagmi/chains';

25-50: Configuration structure looks good, but consider optimizing transports.

The new configuration using getDefaultConfig is more streamlined and easier to maintain than the previous wallet-specific approach. The chain support is comprehensive.

Consider using a more DRY approach for the transports configuration, especially since all chains are using the same HTTP transport function:

- transports: {
-   [mainnet.id]: http(),
-   [customGnosis.id]: http(),
-   [polygon.id]: http(),
-   [arbitrum.id]: http(),
-   [optimism.id]: http(),
-   [sepolia.id]: http(),
-   [base.id]: http(),
-   [blast.id]: http(),
-   [zora.id]: http(),
- },
+ transports: Object.fromEntries(
+   [mainnet, customGnosis, polygon, arbitrum, optimism, sepolia, base, blast, zora]
+     .map(chain => [chain.id, http()])
+ ),

Also, consider adding optional parameters to the http() function for retries or error handling for more robust connections, especially for public RPC endpoints which may have rate limits.

hooks/useDeposit.tsx (1)

18-22: Simplified contract interaction with useWriteContract

The switch to useWriteContract from the previous combination of useContractWrite and usePrepareContractWrite streamlines the code, but removes the automatic simulation step previously provided.

Consider using useSimulateContract before executing the transaction to detect potential failures early:

const { data: simulationData, isError: isSimulationError } = useSimulateContract({
  address: contractAddress || '',
  abi: WethAbi,
  functionName: 'deposit',
  account: address,
  value: BigInt(parseEther(debouncedValue.toString() || '0')),
  enabled: Boolean(address) && debouncedValue > 0,
});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 75ef84b and 438e90e.

📒 Files selected for processing (3)
  • hooks/useDeposit.tsx (1 hunks)
  • utils/chains.ts (0 hunks)
  • utils/wagmiConfig.ts (1 hunks)
💤 Files with no reviewable changes (1)
  • utils/chains.ts
🧰 Additional context used
🧬 Code Definitions (1)
hooks/useDeposit.tsx (1)
utils/wagmiConfig.ts (1)
  • wagmiConfig (25-50)
🔇 Additional comments (4)
utils/wagmiConfig.ts (1)

18-23: Good customization of the Gnosis chain.

Creating a custom Gnosis chain with visual properties is a good practice for providing a consistent UI experience. The implementation extends the base chain without modifying its core properties.

hooks/useDeposit.tsx (3)

1-9: Updated imports align with modern patterns

The shift from @raidguild/design-system's useToast to sonner's toast and updated wagmi imports reflect modern React patterns. The addition of waitForTransactionReceipt is appropriate for tracking transaction completion.


53-53: Proper validation for deposit amount

The change from Boolean(debouncedValue) to debouncedValue > 0 properly restricts deposits to positive values only.

This addresses the previous suggestion to restrict zero or negative deposit attempts.


14-16:

✅ Verification successful

Chain identification method changed - ensure consistency

Changing from chain?.network to chain?.name.toLowerCase() for contract address lookup is a significant change in how chains are identified. This appears consistent with wagmi's API but should be verified across all chain interactions.


🏁 Script executed:

#!/bin/bash
# Check for consistency in chain identification methods
rg -A 2 "chain\?\.name\.toLowerCase\(\)" --type ts
rg -A 2 "chain\?\.network" --type ts

Length of output: 595


Consistency of Chain Identification Confirmed

The code now consistently uses chain?.name.toLowerCase() for contract address lookup across all related hooks (e.g., in hooks/useDeposit.tsx, hooks/useBalances.ts, and hooks/useWithdraw.tsx). No instances of the old chain?.network method were found, ensuring the changes are uniformly applied in line with wagmi's API.

@scottrepreneur
Copy link
Member

good stuff. i'm not able to switch chains currently

Copy link

@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: 0

♻️ Duplicate comments (3)
package.json (1)

37-56: Updated devDependencies with Tailwind ecosystem

The version numbers for tailwindcss (^4.0.17) and postcss (^8.5.3) appear to be slightly ahead of the latest stable releases mentioned in previous comments (Tailwind CSS v4.0.16). Please verify if these are intentional version bumps.

app/providers.tsx (1)

4-4: ⚠️ Potential issue

Update the wagmiConfig import style.

The import is using a default import style, but based on previous review comments, wagmiConfig was being exported as a named export.

-import wagmiConfig from '@/utils/wagmiConfig';
+import { wagmiConfig } from '@/utils/wagmiConfig';
components/ui/form.tsx (1)

74-95: ⚠️ Potential issue

Handle missing itemContext gracefully.

If FormItem is omitted, itemContext can be null or empty, leading to undefined properties when destructuring. Add proper error handling to guide developers in correct usage.

  const useFormField = () => {
    const fieldContext = React.useContext(FormFieldContext);
    const itemContext = React.useContext(FormItemContext);
    const { getFieldState } = useFormContext();
    const formState = useFormState({ name: fieldContext.name });
    const fieldState = getFieldState(fieldContext.name, formState);

    if (!fieldContext) {
      throw new Error('useFormField should be used within <FormField>');
    }

+   if (!itemContext) {
+     throw new Error('useFormField should be used within <FormItem>');
+   }

    const { id } = itemContext;

    return {
      id,
      name: fieldContext.name,
      formItemId: `${id}-form-item`,
      formDescriptionId: `${id}-form-item-description`,
      formMessageId: `${id}-form-item-message`,
      ...fieldState
    };
  };
🧹 Nitpick comments (12)
hooks/useDeposit.tsx (1)

10-13: Potential unconnected wallet scenario.
While deriving chain and address from useAccount(), consider adding a guard to check whether address is present before executing the contract write. This avoids unexpected errors if a user attempts to deposit without a connected wallet.

 const { address, chain } = useAccount();
+if (!address) {
+  return {
+    writeDeposit: () => {},
+    isWritePending: false,
+    isWriteError: false,
+    canDeposit: false,
+  };
+}
.prettierrc (1)

1-8: Updated Prettier configuration with Tailwind plugin

Good addition of the Tailwind plugin for Prettier, which will automatically sort Tailwind CSS classes following the recommended order. Note that changing trailingComma from "all" to "none" might create formatting inconsistencies with previously committed code.

Consider adding a note to the PR description or team documentation about this formatting change to ensure all developers are aware of the new standard.

app/page.tsx (3)

16-37: Add error handling to the onButtonSelection function.

While the function handles button selection well, it logs to the console on invalid input without any user feedback. Consider adding a toast notification for invalid inputs.

  const onButtonSelection = (index: number) => {
    switch (index) {
      case 0:
        setDeposit(true);
        break;
      case 1:
        setDeposit(false);
        break;
      default:
        // eslint-disable-next-line no-console
        console.log(`Invalid input: ${index}`);
+       // Consider adding a toast notification here
+       // import { toast } from 'sonner';
+       // toast.error(`Invalid button selection: ${index}`);
    }
  };

49-78: Improve responsiveness of the Card component.

The Card has a fixed padding (p-32) which might cause layout issues on smaller screens. Consider using responsive padding classes to ensure a better mobile experience.

-      <Card className='mt-6 w-full rounded-xs border-2 border-white p-32'>
+      <Card className='mt-6 w-full rounded-xs border-2 border-white p-6 sm:p-12 md:p-24 lg:p-32'>

80-92: Make the footer section fully responsive.

The current footer has a fixed margin (mr-48) which might cause layout issues on smaller screens. Consider using responsive margin classes.

-      <div className='my-6 mr-48 flex w-full justify-center md:justify-end'>
+      <div className='my-6 flex w-full justify-center md:mr-12 lg:mr-24 xl:mr-48 md:justify-end'>
components/ui/form.tsx (3)

97-112: Consider adding display name to FormLabel component.

For better debugging in React DevTools, consider adding a display name to the FormLabel component.

  const FormLabel = ({
    className,
    ...props
  }: React.ComponentProps<typeof LabelPrimitive.Root>) => {
    const { error, formItemId } = useFormField();

    return (
      <Label
        data-slot='form-label'
        data-error={!!error}
        className={cn('data-[error=true]:text-destructive', className)}
        htmlFor={formItemId}
        {...props}
      />
    );
  };
+ FormLabel.displayName = 'FormLabel';

121-129: Optimize accessibility attributes in FormControl.

The current implementation of aria-describedby can result in extra spaces when either formDescriptionId or formMessageId doesn't exist. Consider a more robust implementation.

  <Slot
    data-slot='form-control'
    id={formItemId}
-   aria-describedby={
-     !error
-       ? `${formDescriptionId}`
-       : `${formDescriptionId} ${formMessageId}`
-   }
+   aria-describedby={
+     [formDescriptionId, error && formMessageId].filter(Boolean).join(' ') || undefined
+   }
    aria-invalid={!!error}
    {...props}
  />

149-167: Handle potential null error message more robustly.

The current implementation uses nullish coalescing (??) to fall back to an empty string, but doesn't handle undefined error objects. Consider a more defensive approach.

  const FormMessage = ({ className, ...props }: React.ComponentProps<'p'>) => {
    const { error, formMessageId } = useFormField();
-   const body = error ? String(error?.message ?? '') : props.children;
+   const body = error ? String(error && error.message ? error.message : '') : props.children;

    if (!body) {
      return null;
    }

    return (
      <p
        data-slot='form-message'
        id={formMessageId}
        className={cn('text-destructive text-sm', className)}
        {...props}
      >
        {body}
      </p>
    );
  };
components/ConnectWallet.tsx (2)

31-52: Consider avoiding time-based synchronization.
Deferring the reset of isSyncing.current with a 500 ms timeout may introduce timing fragility. If chain updates or background processes take longer than expected, you might still risk dispatching changes too early. A more reliable pattern is to listen for chain-related events or confirmations, rather than relying on a fixed delay.


54-91: Add error handling for switchChain failures.
Inside the try/finally block of asyncChainSwitch(), there is no catch clause or user feedback if the chain switch fails. Consider providing at least some minimal warning or fallback to maintain user confidence and clarity.

components/WrapperForm.tsx (1)

62-66: Validate connectivity before executing deposit/withdraw.
While you check if data.amount > 0, it might also be worth confirming the user is properly connected (e.g., has an active signer) before calling writeDeposit or writeWithdraw. Otherwise, these calls could fail silently in certain edge cases.

components/ui/navigation-menu.tsx (1)

31-50: Optional viewport prop is well-handled.
Allowing consumers of NavigationMenu to toggle the viewport is a flexible design choice. The data-viewport attribute also helps with debugging. Just ensure the rest of the codebase handles the absence of a viewport gracefully if it’s ever disabled.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 438e90e and 11c1485.

⛔ Files ignored due to path filters (2)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (36)
  • .eslintrc (2 hunks)
  • .prettierrc (1 hunks)
  • .storybook/main.js (0 hunks)
  • .storybook/preview.js (0 hunks)
  • README.md (1 hunks)
  • app/layout.tsx (1 hunks)
  • app/page.tsx (1 hunks)
  • app/providers.tsx (1 hunks)
  • components.json (1 hunks)
  • components/ConnectWallet.tsx (1 hunks)
  • components/Header.tsx (1 hunks)
  • components/TokenInfo.tsx (1 hunks)
  • components/WrapperForm.tsx (3 hunks)
  • components/icons/RaidGuild.tsx (1 hunks)
  • components/ui/button.tsx (1 hunks)
  • components/ui/card.tsx (1 hunks)
  • components/ui/form.tsx (1 hunks)
  • components/ui/input.tsx (1 hunks)
  • components/ui/label.tsx (1 hunks)
  • components/ui/navigation-menu.tsx (1 hunks)
  • components/ui/skeleton.tsx (1 hunks)
  • components/ui/sonner.tsx (1 hunks)
  • hooks/useBalances.ts (1 hunks)
  • hooks/useDeposit.tsx (1 hunks)
  • hooks/useGasFee.ts (2 hunks)
  • hooks/useWithdraw.tsx (1 hunks)
  • lib/utils.ts (1 hunks)
  • next.config.js (1 hunks)
  • package.json (1 hunks)
  • postcss.config.mjs (1 hunks)
  • tsconfig.json (2 hunks)
  • utils/chainMap.ts (1 hunks)
  • utils/contracts.ts (1 hunks)
  • utils/general.ts (0 hunks)
  • utils/unitConverter.ts (0 hunks)
  • utils/wagmiConfig.ts (1 hunks)
💤 Files with no reviewable changes (4)
  • utils/general.ts
  • utils/unitConverter.ts
  • .storybook/main.js
  • .storybook/preview.js
✅ Files skipped from review due to trivial changes (2)
  • README.md
  • utils/contracts.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • components/ui/label.tsx
  • utils/chainMap.ts
  • next.config.js
  • hooks/useGasFee.ts
  • components/ui/skeleton.tsx
  • components/icons/RaidGuild.tsx
  • components/ui/card.tsx
  • components/ui/input.tsx
  • lib/utils.ts
  • components.json
  • components/Header.tsx
  • components/TokenInfo.tsx
  • components/ui/button.tsx
  • tsconfig.json
  • hooks/useBalances.ts
🧰 Additional context used
🧬 Code Definitions (7)
hooks/useDeposit.tsx (1)
utils/contracts.ts (1)
  • wethAddrs (1-13)
app/page.tsx (3)
components/ui/card.tsx (1)
  • Card (71-71)
components/ui/button.tsx (1)
  • Button (63-63)
lib/utils.ts (1)
  • cn (4-6)
app/layout.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
components/ui/form.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
components/ui/navigation-menu.tsx (2)
lib/utils.ts (1)
  • cn (4-6)
app/layout.tsx (1)
  • viewport (33-38)
components/ConnectWallet.tsx (4)
lib/utils.ts (1)
  • cn (4-6)
components/ui/button.tsx (1)
  • Button (63-63)
components/ui/navigation-menu.tsx (6)
  • NavigationMenu (154-154)
  • NavigationMenuList (159-159)
  • NavigationMenuItem (157-157)
  • NavigationMenuTrigger (160-160)
  • NavigationMenuContent (155-155)
  • NavigationMenuLink (158-158)
utils/general.ts (1)
  • truncateAddress (1-2)
components/WrapperForm.tsx (2)
components/ui/form.tsx (5)
  • Form (170-170)
  • FormField (173-173)
  • FormItem (174-174)
  • FormControl (171-171)
  • FormMessage (176-176)
components/ui/button.tsx (1)
  • Button (63-63)
🔇 Additional comments (31)
.eslintrc (4)

3-3: Good addition of the "react" plugin.
Including the "react" plugin ensures that React-specific lint rules are enforced, helping catch common pitfalls and maintain consistent code quality.


8-8: Welcome inclusion of "eslint:recommended".
The "eslint:recommended" configuration provides a solid baseline of rules. This helps ensure key best practices and error checks are covered.


53-57: Correct usage of “next” settings.
Defining "next": { "rootDir": "./" } is beneficial for Next.js-based projects, ensuring that ESLint can properly resolve imports and other Next.js-specific configurations.


58-62: Comprehensive parser options for TypeScript.
Pointing "project": "./tsconfig.json" and "tsconfigRootDir": "./" helps ESLint respect type information accurately. Specifying "ecmaVersion": 2022 and "sourceType": "module" also aligns with modern JavaScript usage.

hooks/useDeposit.tsx (3)

1-3: Imports look consistent with the updated project structure.
Using wagmiConfig from @/utils/wagmiConfig and toast from sonner aligns with the newly introduced notification approach. The useDebounceValue import from usehooks-ts is also a neat solution for debouncing logic.


21-53: Robust transaction flow with toast.promise.
Wrapping the asynchronous contract write and receipt wait in toast.promise provides clear feedback. Properly handling missing contractAddress with an error toast is also a good user experience.


59-59: Positive-only deposits ensure valid on-chain transactions.
Using debouncedValue > 0 is a straightforward way to disable the deposit flow for zero or negative values. This prevents erroneous transaction attempts.

app/layout.tsx (5)

1-6: Concise imports for styling and providers.
Imports for global styles, RainbowKit styles, and your Provider component nicely centralize the application’s top-level setup.


9-9: Use of Google Fonts via Next.js font utilities.
The Uncial_Antiqua and Texturina fonts with a 'swap' display strategy prevent layout shifts. This is a recommended approach for SSR font loading.


24-31: Well-defined metadata for SEO and branding.
The title, description, and icons provide clarity for search engines and brand identity in the browser toolbar.


33-38: Viewport theme color ensures a polished user experience.
Dynamically setting the theme color for light/dark modes can improve aesthetics on mobile UIs.


40-57: Structured RootLayout with Providers and Analytics.
Wrapping the children in your Provider plus including analytics at this level keeps the layout neat and consistent. Applying font classes at the <body> level ensures consistent typography throughout.

utils/wagmiConfig.ts (2)

20-24: Fail-fast approach for missing Project ID.
Throwing an error if NEXT_PUBLIC_PROJECT_ID is not defined ensures developers are made aware of vital missing configuration, preventing undefined runtime behavior.


37-124: Comprehensive multi-chain setup with fallback transports.
You’ve included multiple providers (Infura, Alchemy, etc.), improving reliability for each chain. Also, proper chaining of fallback ensures requests degrade gracefully if one provider is unavailable.

hooks/useWithdraw.tsx (5)

1-6: Updated import statements for better toast notifications and wagmi v2 integration

The imports have been updated to accommodate wagmi v2 APIs and sonner toast. The switch from useNetwork to useAccount for getting chain information, and the addition of waitForTransactionReceipt for transaction handling shows good adaptation to the new wagmi architecture.


11-13: Refactored to use useAccount instead of useNetwork

Good update to use useAccount which is the recommended way to access chain information in wagmi v2. The debounced value implementation has been kept consistent.


15-19: Simplified contract write hook usage

The implementation now uses the more streamlined useWriteContract hook from wagmi v2, which provides a cleaner API compared to the previous combination of usePrepareContractWrite and useContractWrite.


21-46: Enhanced withdrawal process with improved error handling and user feedback

Excellent improvement to the withdrawal process. The code now:

  1. Uses a promise-based toast notification system
  2. Properly awaits transaction confirmation
  3. Provides clear user feedback during each step
  4. Has robust error handling

This approach provides much better UX during blockchain transactions.


48-53: Updated hook return values for better state management

The return object now includes additional states like isWritePending and isWriteError that provide more granular control for UI components consuming this hook. Good practice to expose these states and map executeWithdraw to writeWithdraw for backward compatibility.

package.json (1)

13-36:

✅ Verification successful

Major dependency updates to support modern React ecosystem

The dependency updates are substantial and well-structured:

  1. Added UI component libraries from Radix UI
  2. Updated to React 19 and Next.js 15
  3. Upgraded to wagmi v2 and viem v2
  4. Added form validation with zod and @hookform/resolvers
  5. Added sonner for modern toast notifications

These updates align with current best practices for React applications in 2024/2025.


🌐 Web query:

What are the latest stable versions of React and Next.js?

💡 Result:

As of April 2025, the latest stable versions are:

React

  • React 19 is the current stable version, introduced with features like Server Components, enhanced Suspense, and compiler optimizations[1][3][4][10]. It requires updates to deprecated APIs like propTypes and defaultProps[10].

Next.js

  • Next.js 15.2.4 is the latest stable release, featuring React 19 support, improved error debugging, and Turbopack optimizations[6][8]. Key updates include:
    • Async metadata streaming for faster page transitions[8]
    • Experimental React View Transitions API[8]
    • Backward compatibility with React 18 for Pages Router users[2][3]

Both frameworks emphasize stability, with React 19 reducing client-side JavaScript via Server Components[1][7], while Next.js 15 enhances developer tooling and performance[2][3][8].

Citations:


Dependency Versions Verified
The dependency updates have been verified against the latest stable releases as of April 2025. In particular:

  • React 19 and Next.js 15.2.4 align with the stable versions, ensuring the project is up-to-date.
  • The inclusion of UI component libraries from Radix UI, Wagmi v2 coupled with Viem v2, form validation with Zod and @hookform/resolvers, and modern toast notifications with Sonner are well-considered for a modern React ecosystem.

No further changes are necessary based on the verification.

postcss.config.mjs (1)

1-6: Added PostCSS configuration for Tailwind CSS v4

This is a clean, minimal PostCSS configuration that correctly imports the Tailwind PostCSS plugin. In Tailwind v4, the PostCSS plugin is a separate package (@tailwindcss/postcss), and you've configured it correctly.

components/ui/sonner.tsx (1)

1-24: Well-structured Toaster component with good theme integration.

The Toaster component is implemented correctly, using the useTheme hook to determine the current theme and passing it to the underlying Sonner component. The custom CSS properties are appropriately set based on theme variables.

app/providers.tsx (2)

10-31: Well-implemented query client setup for SSR.

Your implementation correctly handles server-side rendering by creating a new query client on the server and maintaining a singleton on the client. The staleTime configuration prevents immediate refetching on the client side.


33-45: Clean provider structure with proper nesting.

The Provider component correctly wraps the children with the necessary providers in the proper order: WagmiProvider → QueryClientProvider → RainbowKitProvider. The Toaster component is also appropriately included for notifications.

components/ConnectWallet.tsx (3)

1-3: Imports look good.
No immediate concerns with these new imports. They effectively bring in cn, chainMappings, and useChainModal for improved chain handling and styling within ConnectWallet.


20-29: Be cautious with isSyncing state toggles.
The combination of isSyncing and lastModalState helps avoid race conditions when updating query parameters. However, the logic could become brittle if future asynchronous flows or additional modals get introduced. Consider centralizing modal and chain synchronization logic or adding robust tests to validate complex push scenarios.


146-196: Great integration of NavigationMenu for account actions.
This new structure improves clarity and usability of wallet-related controls, offering a clean, discoverable menu of connected account options. The usage of Radix UI primitives aligns with best practices for composable UIs.

components/WrapperForm.tsx (2)

27-38: Zod schema validation is a solid approach.
Defining explicit min/max constraints per action (deposit vs. withdraw) simplifies logic and ensures better user feedback. Keep an eye on potential edge cases when balances are near-zero or fees exceed the available amount.


91-129: Nice integration of react-hook-form with custom UI components.
Leveraging <FormField> and <FormMessage> centralizes validation feedback, and the Set Max button logic is straightforward. The updated layout with local UI components appears consistent and more maintainable.

components/ui/navigation-menu.tsx (2)

9-29: Viewport implementation is well-structured.
Forwarding refs via React.forwardRef ensures compatibility with the Radix primitives. The layered approach with absolute positioning is neatly handled, and the fallback container for NavigationMenuPrimitive.Viewport is cleanly separated.


86-102: Clear visual hint for open/closed state.
Using class-variance-authority and ChevronDownIcon to display rotation is a nice subtlety for user feedback. This pattern is typical for Radix-based menus, and the combined classes appear consistent with the codebase.

Copy link

@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: 0

🧹 Nitpick comments (5)
components/ui/form.tsx (5)

1-1: Consider using more specific ESLint disable directives.

Instead of disabling all prop-types rules with a blanket directive, consider using more targeted disables for specific components or issues. This maintains better linting coverage for the rest of the file.

-/* eslint-disable react/prop-types */
+/* eslint-disable react/prop-types -- Using TypeScript for prop validation instead */

32-34: Consider initializing context with null instead of empty object.

Creating contexts with empty objects and type assertions can hide type errors. A better pattern is to initialize with null and check for existence before use.

-const FormItemContext = React.createContext<FormItemContextValue>(
-  {} as FormItemContextValue
-);
+const FormItemContext = React.createContext<FormItemContextValue | null>(null);

Same applies to the FormFieldContext below.


58-58: Remove outdated comment.

The comment "Rest of the code remains the same, but add useMemo for FormItemContext.Provider value" seems to be a leftover from code adaptation and doesn't make sense in a new file.


155-155: Simplify error message extraction.

The current approach using optional chaining, nullish coalescing and String conversion can be simplified for better readability.

-  const body = error ? String(error?.message ?? '') : props.children;
+  const body = error ? String(error.message || '') : props.children;

118-135: Improve readability of aria-describedby conditional.

The conditional logic for the aria-describedby attribute could be simplified for better readability.

-  <Slot
-    data-slot='form-control'
-    id={formItemId}
-    aria-describedby={
-      !error
-        ? `${formDescriptionId}`
-        : `${formDescriptionId} ${formMessageId}`
-    }
-    aria-invalid={!!error}
-    {...props}
-  />
+  <Slot
+    data-slot='form-control'
+    id={formItemId}
+    aria-describedby={`${formDescriptionId}${error ? ` ${formMessageId}` : ''}`}
+    aria-invalid={!!error}
+    {...props}
+  />
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 11c1485 and afdafbf.

📒 Files selected for processing (1)
  • components/ui/form.tsx (1 hunks)
🧰 Additional context used
🧬 Code Definitions (1)
components/ui/form.tsx (1)
lib/utils.ts (1)
  • cn (4-6)
🔇 Additional comments (2)
components/ui/form.tsx (2)

74-99: Well implemented useFormField hook with proper error checking.

The hook correctly checks for both fieldContext and itemContext before use, providing clear error messages if the hook is used outside its intended contexts. This addresses the previous review comment and prevents potential runtime issues.


18-182: Overall well-structured form component system.

The implementation creates a comprehensive form system with good React patterns:

  • Proper use of context for state sharing
  • Composition with specialized components
  • Good accessibility with ARIA attributes
  • Performance optimization with useMemo
  • Clear separation of concerns between components
  • Strong TypeScript typing

This is a solid foundation for building forms with react-hook-form while maintaining good UI practices.

Copy link

@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

🧹 Nitpick comments (6)
hooks/useGasFee.ts (1)

6-10: Ensure fallback or error handling for fee data retrieval.

useEstimateFeesPerGas and useEstimateGas can occasionally return undefined or stale data. Verify that the parent components handle cases where fee estimates are not ready or fail to load.

Consider adding a check for !data or controlling the hook's usage to avoid computing fees with empty data.

hooks/useDeposit.tsx (1)

11-13: Debounced deposit value logic.

This pattern smooths out frequent state changes for typed amounts. Confirm that the 500ms delay is acceptable for the user experience, especially if real-time feedback is needed.

hooks/useWithdraw.tsx (2)

11-13: Debounced withdrawal value logic.

Similar to the deposit logic, ensuring that user input is stabilized before initiating transactions. Confirm that 500ms is acceptable for responsiveness.


49-52: Return object aligns with deposit hook.

Renaming writeWithdraw to executeWithdraw for clarity. canWithdraw: Boolean(debouncedValue) ensures some input but could be stricter (e.g., > 0). If zero or negative inputs are truly invalid, refine the check.

components/WrapperForm.tsx (2)

70-86: Remove commented-out validation code.

The commented-out validation code is no longer needed since you've implemented Zod schema validation.

-  // const customValidations = {
-  //   required: 'Input cannot be blank',
-  //   validate: (value: number) => {
-  //     if (action === 'deposit') {
-  //       return value > 0 && value < +ethBalance - +txFeeEther;
-  //     }
-  //     return value > 0 && value <= +wethBalance;
-  //   },
-  //   max: {
-  //     value: action === 'deposit' ? +ethBalance - +txFeeEther : +wethBalance,
-  //     message: `Input must be less than your full balance, plus transaction fees...`,
-  //   },
-  //   min: {
-  //     value: 0,
-  //     message: 'Value must be greater than 0',
-  //   },
-  // };

134-134: Remove empty div at the end of the component.

There's an empty div that doesn't serve any purpose and can be removed.

-  <div className='mt-5 flex justify-center text-white' />
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between afdafbf and c135327.

📒 Files selected for processing (8)
  • components/ConnectWallet.tsx (1 hunks)
  • components/WrapperForm.tsx (3 hunks)
  • hooks/useBalances.ts (1 hunks)
  • hooks/useDeposit.tsx (1 hunks)
  • hooks/useGasFee.ts (1 hunks)
  • hooks/useWithdraw.tsx (1 hunks)
  • utils/contracts.ts (2 hunks)
  • utils/wagmiConfig.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • utils/contracts.ts
🧰 Additional context used
🧬 Code Graph Analysis (2)
components/ConnectWallet.tsx (4)
lib/utils.ts (1)
  • cn (4-6)
components/ui/button.tsx (1)
  • Button (63-63)
components/ui/navigation-menu.tsx (6)
  • NavigationMenu (154-154)
  • NavigationMenuList (159-159)
  • NavigationMenuItem (157-157)
  • NavigationMenuTrigger (160-160)
  • NavigationMenuContent (155-155)
  • NavigationMenuLink (158-158)
utils/general.ts (1)
  • truncateAddress (1-2)
components/WrapperForm.tsx (2)
components/ui/form.tsx (5)
  • Form (174-174)
  • FormField (177-177)
  • FormItem (178-178)
  • FormControl (175-175)
  • FormMessage (180-180)
components/ui/button.tsx (1)
  • Button (63-63)
🔇 Additional comments (26)
hooks/useGasFee.ts (4)

2-2: Imports look good.

Switching to useEstimateFeesPerGas and useEstimateGas appears to align with the new approach of dynamically estimating fees, which provides more accurate data than hardcoded or previously used methods.


5-5: Confirm intent of commenting out the chain usage.

By commenting out chain, you no longer have chain-specific logic for fees. If you need multi-chain support or chain checks in the future, consider reinstating or refining this logic.

Are there any references in the codebase still expecting chain-based fee calculations?


13-21: Removal of gasUsedByChain logic.

Removing the hardcoded gasUsedByChain object is consistent with dynamic fee estimation. Just verify that you truly don't need these estimates for fallback or offline situations.


23-25: Validate the final fee calculation.

(estimatedGasUsed || BigInt(0)) ensures no runtime error if estimatedGasUsed is undefined, but confirm the zero fallback is acceptable in scenarios where the estimate fails to load.

Review any upstream or downstream usage to ensure this won't mislead users with a zero-fee display.

hooks/useDeposit.tsx (6)

1-3: Imports updated successfully.

These import changes reflect the migration to wagmiConfig, toast from sonner, and useDebounceValue. This aligns with the described refactoring and consolidates third-party dependencies.


5-6: Using useAccount and waitForTransactionReceipt.

Leveraging useAccount for both address and chain eliminates the need for separate network hooks. waitForTransactionReceipt is a straightforward approach to confirm transaction finality. Make sure to handle network changes or re-connections gracefully.

Check that upstream providers always supply a valid chain.


8-8: Centralizing WETH address in getWethAddress.

Using a utility to retrieve the WETH address promotes maintainability. Ensure the mapping in utils/contracts includes all relevant chain IDs if you intend to support multiple networks.


15-19: useWriteContract destructuring is clear.

Pulling out writeContractAsync and states (isPending, isError) simplifies the code. Just ensure that you handle potential contract config changes if the chain is switched.


21-53: Robust deposit function with user feedback.

This implementation handles:

  1. Missing contract addresses with an error toast.
  2. Transaction execution via a promise-based toast mechanism for loading/success/error states.
  3. Receipt retrieval to confirm finality.

Recommendations:

  • Log deposit errors more verbosely if additional debugging is needed.
  • Consider returning the transaction receipt so callers can respond to final states programmatically.

Other than that, logic is solid.


56-59: Streamlined return object.

Renaming writeDeposit to executeDeposit clarifies the intent. Using canDeposit: debouncedValue > 0 ensures negative or zero deposit attempts won't proceed. This is an improvement over less strict conditions.

hooks/useWithdraw.tsx (5)

1-3: Importing wagmiConfig and toast aligns with new architecture.

This change is consistent with the deposit hook’s refactor. The toast-based notifications unify user feedback across deposit/withdraw flows.


5-6: useAccount for chain detection and useWriteContract.

Reusing the pattern from useDeposit fosters a uniform approach. Confirm you handle cases where chain could be undefined if the wallet is disconnected.


8-8: Centralizing WETH address.

As in the deposit hook, referencing getWethAddress promotes consistency and maintainability.


15-19: useWriteContract destructuring is consistent.

Consistent with deposit hook. Check that any environment differences (testnet vs. mainnet, etc.) are handled as expected if chain changes mid-session.


21-46: Robust withdrawal function with user feedback.

Similar to the deposit function:

  • Uses toast-based loading/success/error states.
  • Waits for transaction receipt for finality.
  • Logs errors in the catch block.

Potential enhancement: Return or store the transaction receipt for further logic after withdrawal.

utils/wagmiConfig.ts (3)

26-30: Great improvement on error handling for missing project ID.

This change properly addresses the previous review comment and now explicitly throws an error during initialization when the project ID is missing.


36-41: Good addition with custom Gnosis chain configuration.

The extension of the standard Gnosis chain with visual properties improves the UI and user experience.


43-191: Well-structured configuration with comprehensive chain support.

The configuration is thorough and follows best practices:

  • Includes multiple chains for broad compatibility
  • Sets up fallback RPC providers using both Infura and Alchemy for reliability
  • Properly references the project ID from environment variables

The transports configuration for multiple chains is particularly robust, ensuring reliable blockchain connectivity across networks.

hooks/useBalances.ts (4)

10-16: Good patterns for hook initialization.

The hook properly retrieves user address and chain data, with a sensible fallback to mainnet (chain ID 1) when no chain is detected.


17-24: Effective ETH balance fetching with proper enabling conditions.

The approach to fetch ETH balance only when both address and contract address are available prevents unnecessary queries.


26-45: Smart optimization with batch contract reading.

Using useReadContracts to fetch both token balance and decimals in a single call reduces network traffic and improves performance.


47-52: Excellent real-time balance updating mechanism.

Invalidating balance queries on block updates ensures that balances stay in sync with on-chain state changes.

components/ConnectWallet.tsx (3)

30-51: Effective URL synchronization with chain selection.

This effect elegantly updates the URL to reflect the currently selected chain when the chain modal closes, improving the user experience by making chain selections shareable via URL.


53-94: Well-structured chain switching logic.

The chain synchronization effect:

  • Properly handles URL-based chain switching
  • Includes safeguards against race conditions with the isSyncing ref
  • Correctly updates the URL when the chain changes

This bidirectional sync between URL parameters and chain selection creates a seamless user experience.


158-190: Improved account management UI with NavigationMenu.

The new navigation menu provides a more structured and user-friendly interface for wallet actions compared to the previous implementation.

components/WrapperForm.tsx (1)

28-39: Well-implemented Zod validation schema.

The schema properly validates that:

  • The amount is a positive number
  • It doesn't exceed the user's balance
  • For deposits, it accounts for transaction fees

This ensures robust form validation and prevents invalid transactions.

Copy link

@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: 0

🧹 Nitpick comments (2)
components/WrapperForm.tsx (2)

28-39: Handle edge case when ethBalance - txFeeEther can be negative.
If the available ETH balance is smaller than the estimated fees, the .max() validation may become negative, causing confusion or error messages. Consider clamping the maximum value to zero to ensure a valid validation range.

- .max(action === 'deposit' ? +ethBalance - +txFeeEther : +wethBalance, {
+ .max(
+   action === 'deposit'
+     ? Math.max(0, +ethBalance - +txFeeEther)
+     : +wethBalance,
+ {
    message: 'Input must be less than your full balance, plus transaction fees...',
 }

70-86: Remove or clarify commented-out validation code.
Uncommented code is preferred over large commented blocks. If these validations are no longer needed now that Zod is used, removing them improves maintainability.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between c135327 and ed55ede.

📒 Files selected for processing (1)
  • components/WrapperForm.tsx (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
components/WrapperForm.tsx (2)
components/ui/form.tsx (5)
  • Form (174-174)
  • FormField (177-177)
  • FormItem (178-178)
  • FormControl (175-175)
  • FormMessage (180-180)
components/ui/button.tsx (1)
  • Button (63-63)
🔇 Additional comments (4)
components/WrapperForm.tsx (4)

5-8: Great adoption of Zod resolver for validation.
Switching to zodResolver(formSchema) is a clean and centralized approach for managing form validation. It reduces duplication and ensures consistent validation logic.


18-18: Nice improvement with the union type.
Defining action as 'deposit' | 'withdraw' helps ensure type safety and clarity in the code.


34-35: Check .min(0) vs. error message mentioning “greater than 0.”
.min(0) in Zod allows zero, but your message says “Amount must be greater than 0.” If you truly want the user’s amount to be strictly greater than 0, you may use a custom refine or .min(0.00000001).


95-108: Good consistency between Zod schema and input max attribute.
Previously, there was a mismatch in forms that displayed a max different from the actual validation logic. Now both match, making for a clearer user experience.

Copy link

@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: 3

🧹 Nitpick comments (4)
utils/wagmiConfig.ts (1)

60-133: Consider abstracting the repetitive transport configuration

The transport configuration for each chain follows the same pattern, which introduces repetition. Consider creating a helper function to generate the transport configuration for each chain.

-  transports: {
-    [mainnet.id]: fallback([
-      http(),
-      http(`https://mainnet.infura.io/v3/${process.env.NEXT_PUBLIC_RPC_KEY}`),
-      http(
-        `https://eth-mainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`
-      )
-    ]),
-    [customGnosis.id]: fallback([
-      http(),
-      http(`https://gnosis.infura.io/v3/${process.env.NEXT_PUBLIC_RPC_KEY}`),
-      // ...remaining chains...
+  transports: {
+    ...Object.fromEntries(
+      [
+        { chain: mainnet, infuraPath: 'mainnet', alchemyPath: 'eth-mainnet' },
+        { chain: customGnosis, infuraPath: 'gnosis', alchemyPath: 'gnosis-mainnet' },
+        // ...remaining chains...
+      ].map(({ chain, infuraPath, alchemyPath }) => [
+        chain.id,
+        fallback([
+          http(),
+          http(`https://${infuraPath}.infura.io/v3/${process.env.NEXT_PUBLIC_RPC_KEY}`),
+          http(`https://${alchemyPath}.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`)
+        ])
+      ])
+    )
hooks/useBalances.ts (3)

21-26: Question the enabled condition for fetching ETH balance.
You don’t actually need the WETH contract address to fetch native ETH balances, so enabled: !!address && !!contractAddress might be unnecessarily strict. Consider disabling the contract address check for the ETH balance query.

 useBalance({
   address,
   query: {
-    enabled: !!address && !!contractAddress
+    enabled: !!address
   }
 })

28-47: Add error handling for read contract calls.
Currently, if the contract does not support ERC20 calls or if the chain differs from expected, the hook will fail silently. Consider adding error handling or fallback logic, such as capturing any thrown exceptions or returning a default value for WETH balance in case of error.


49-54: Prevent repetitive query invalidations.
Invalidating queries on every new block might lead to frequent re-fetching and degrade performance on busy networks. Consider caching or throttling updates if the block rate causes excessive retries.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ed55ede and b4a3fb7.

📒 Files selected for processing (5)
  • hooks/useBalances.ts (1 hunks)
  • hooks/useDeposit.tsx (1 hunks)
  • hooks/useWithdraw.tsx (1 hunks)
  • utils/contracts.ts (1 hunks)
  • utils/wagmiConfig.ts (1 hunks)
🔇 Additional comments (8)
utils/wagmiConfig.ts (2)

21-25: Great improvement on error handling for missing Project ID

This change properly addresses the previous review comment by throwing an error when the project ID is missing rather than silently falling back to an empty string. This will immediately alert developers about the missing configuration rather than causing subtle runtime issues.


31-36: Good addition of custom chain icon

The custom Gnosis chain configuration with icon properties enhances the user experience by providing visual differentiation between chains in the UI.

utils/contracts.ts (2)

1-16: Good update to chain names and added new chains

The updates to chain names (e.g., 'matic' to 'polygon') and the addition of new chains (base, zora, blast) keep the contract mappings current with industry standards.


18-20: Better encapsulation with getWethAddress function

Converting from direct export of the address mapping to a function that handles fallback is a good design improvement. This encapsulates the implementation details and provides a safer interface for consumers.

hooks/useDeposit.tsx (2)

21-53: Improved deposit execution with proper error handling

The new executeDeposit function properly checks for the existence of the contract address before attempting to execute the transaction and provides excellent user feedback via toast notifications. This addresses previous review comments about handling invalid contract addresses.


59-59: Good fix: Properly restricting negative deposit amounts

The change from Boolean(debouncedValue) to debouncedValue > 0 properly restricts negative deposit attempts, addressing the previous review comment.

hooks/useBalances.ts (2)

60-65: Handle missing decimals gracefully.
decimalsResult relies on the contract implementing decimals. If it’s missing or returns an unexpected result, the user will see '0'. Consider adding a safety check or fallback to 18 decimals if the query fails, or display a warning if the contract is invalid.


14-16:

✅ Verification successful

Confirm the fallback chain name.
Using 'homestead' as a fallback is valid for Ethereum mainnet in many tooling contexts. However, some libraries might expect 'mainnet' instead. Consider verifying that your other code and third-party libraries (such as Wagmi) correctly handle 'homestead' as mainnet.

You can run this script to check all existing references to getWethAddress and usage of 'homestead':


🏁 Script executed:

#!/bin/bash
# Searching references of 'getWethAddress' and 'homestead' across the repo
rg -A 3 "getWethAddress|homestead"

Length of output: 2513


Action: Confirm Fallback Chain Name Usage

The verification shows that the codebase consistently uses 'homestead' as the fallback for the Ethereum mainnet. In particular:

  • Hooks (useBalances.ts, useWithdraw.tsx, useDeposit.tsx): These files use chain?.name.toLowerCase() || 'homestead' to obtain the fallback value.
  • Utilities (utils/contracts.ts): The fallback in getWethAddress defaults to wethAddrs.homestead, and a comment indicates use of 'homestead' to represent the Ethereum mainnet (using Rainbowkit's syntax).
  • Other Components: Files like components/ConnectWallet.tsx also follow this pattern.

Please verify that any external libraries (e.g., Wagmi) used in your project correctly interpret 'homestead' as mainnet. If they do, the current implementation is correct.

Copy link

@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: 0

♻️ Duplicate comments (2)
hooks/useWithdraw.tsx (2)

23-54: Well-implemented executeWithdraw function with proper validation.

The new executeWithdraw function includes contract address validation, intuitive toast notifications, and structured error handling. Previously identified issues have been addressed effectively.

This implementation properly addresses the previous review comment about missing contract address validation.


56-61: Fixed withdrawal validation logic.

The canWithdraw condition has been improved to properly check for positive values, addressing the previous issue that could have allowed zero or negative withdrawals.

This implementation properly addresses the previous review comment about restricting withdrawal of zero or negative amounts.

🧹 Nitpick comments (2)
hooks/useWithdraw.tsx (2)

39-43: Consider adding more robust transaction error handling.

While the current implementation properly waits for transaction receipt, consider enhancing error handling to capture specific transaction failure reasons and communicate them to users.

const receipt = await waitForTransactionReceipt(wagmiConfig, {
  hash
});
return receipt;
+// Improved version:
+// try {
+//   const receipt = await waitForTransactionReceipt(wagmiConfig, {
+//     hash
+//   });
+//   return receipt;
+// } catch (receiptError) {
+//   console.error('Transaction receipt error:', receiptError);
+//   throw new Error(`Transaction failed: ${receiptError.message || 'Unknown error'}`);
+// }

45-49: Enhance error messaging with more specific feedback.

The current error message is generic. Consider providing more specific error messages based on the type of error encountered.

{
  loading: 'Unwrapping in progress...',
  success: () =>
    `Successfully unwrapped ${chain?.nativeCurrency?.symbol || 'ETH'}`,
-  error: 'Error... transaction reverted...'
+  error: (error) => `Failed to unwrap: ${error?.message || 'Transaction reverted'}`
}
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b4a3fb7 and c5f3c04.

📒 Files selected for processing (1)
  • hooks/useWithdraw.tsx (1 hunks)
🔇 Additional comments (3)
hooks/useWithdraw.tsx (3)

1-8: Improved module organization with modern imports.

The imports have been updated to use the wagmi's latest approach for blockchain interactions and Sonner for toast notifications, which provides a more streamlined developer experience.


11-15: Appropriate use of useAccount hook for chain information.

The switch from useNetwork to useAccount is aligned with wagmi's recommended patterns for accessing chain information.


17-21: Simplified contract interaction with useWriteContract.

The use of useWriteContract is a more elegant approach than the previous separate usePrepareContractWrite and useContractWrite hooks, reducing complexity and potential points of failure.

@nitegeist nitegeist merged commit 309d9b5 into develop Apr 11, 2025
3 checks passed
@nitegeist nitegeist deleted the feat/tailwind branch April 11, 2025 20:16
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.

Add other OP networks Feature Request: Chain via URL Params
2 participants