feat(wallet): integrate RainbowKit + Wagmi to enable multi-wallet support#25
Conversation
WalkthroughIntroduces wallet integration infrastructure using Wagmi and RainbowKit, including provider configuration, supported chain definitions, wallet state management hook, and a ConnectButton wrapper component. Updates Navbar to use wallet connection state for conditional rendering. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes
Possibly related issues
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
.gitignore(1 hunks)src/Navbar.tsx(3 hunks)src/app/providers.tsx(1 hunks)src/components/wallet-connect.tsx(1 hunks)src/hooks/useWallet.ts(1 hunks)src/lib/wallet/chains.ts(1 hunks)src/lib/wallet/config.ts(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
src/app/providers.tsx (1)
src/lib/wallet/config.ts (1)
wagmiConfig(6-11)
src/lib/wallet/config.ts (1)
src/lib/wallet/chains.ts (1)
supportedChains(3-8)
🔇 Additional comments (5)
.gitignore (1)
27-27: LGTM! Correct addition for local environment files.Adding
.env.localto.gitignoreis appropriate for excluding environment-specific configuration that may contain theNEXT_PUBLIC_WALLETCONNECT_PROJECT_IDand other sensitive values used by the wallet integration.src/lib/wallet/chains.ts (1)
3-8: LGTM! Clean chain configuration.The supported chains are clearly defined and exported. The selection of mainnet, Polygon, Optimism, and Arbitrum provides a good mix of Layer 1 and Layer 2 networks for multi-chain support.
src/Navbar.tsx (3)
2-9: LGTM! Clean wallet state integration.The migration from
Account.addresstouseAccount'sisConnectedis correct and follows Wagmi best practices. The hook provides proper reactivity for wallet connection state.
63-70: LGTM! Proper conditional rendering based on wallet state.The "Raise Funds for a New Project" button is correctly gated behind
isConnected, ensuring only connected users can access the create flow. The navigation to/createis straightforward and appropriate.
72-77: LGTM! Good responsive configuration for ConnectButton.The
accountStatusprop configuration provides a good user experience by showing an avatar on small screens and full account details on larger screens, optimizing for different viewport sizes.
| import { QueryClient, QueryClientProvider } from "@tanstack/react-query" | ||
| import { wagmiConfig } from "@/lib/wallet/config" | ||
|
|
||
| const queryClient = new QueryClient() |
There was a problem hiding this comment.
Move QueryClient instantiation into component state.
Creating the QueryClient at module level is an anti-pattern in React. The same instance will be shared across all component mounts, potentially causing stale cache issues, memory leaks, and unexpected behavior during hot reloads or in SSR contexts.
Apply this diff to instantiate the client per component:
-const queryClient = new QueryClient()
-
export function Providers({ children }: { children: React.ReactNode }) {
+ const [queryClient] = useState(() => new QueryClient())
+
return (
<WagmiProvider config={wagmiConfig}>Don't forget to import useState:
"use client"
+import { useState } from "react"
import { WagmiProvider } from "wagmi"📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const queryClient = new QueryClient() | |
| "use client" | |
| import { useState } from "react" | |
| import { WagmiProvider } from "wagmi" | |
| export function Providers({ children }: { children: React.ReactNode }) { | |
| const [queryClient] = useState(() => new QueryClient()) | |
| return ( | |
| <WagmiProvider config={wagmiConfig}> | |
| {children} | |
| </WagmiProvider> | |
| ) | |
| } |
🤖 Prompt for AI Agents
In src/app/providers.tsx around line 8, the QueryClient is created at module
scope which can cause shared-instance issues; move its instantiation into the
Providers component by importing useState and creating the client inside the
component (e.g., useState with an initializer to return a new QueryClient) so
each mount gets its own instance, then use that state-held client for
QueryClientProvider and remove the module-level const.
| export default function WalletConnect() { | ||
| return <ConnectButton /> | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for imports or usage of WalletConnect component
rg -nP --type=ts --type=tsx -C3 '\bWalletConnect\b' -g '!src/components/wallet-connect.tsx'Repository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 115
🏁 Script executed:
#!/bin/bash
# Search for imports or usage of WalletConnect component
rg -nP -t ts -C3 '\bWalletConnect\b' -g '!src/components/wallet-connect.tsx'Repository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 70
🏁 Script executed:
#!/bin/bash
# Check if Navbar.tsx exists and examine its imports
fd -e tsx -e ts 'Navbar' | head -5Repository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 102
🏁 Script executed:
#!/bin/bash
# Read the first part of Navbar.tsx to see imports
head -80 src/Navbar.tsx | cat -nRepository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 3238
Remove the unused WalletConnect wrapper component.
The WalletConnect component is not imported or used anywhere in the codebase. Navbar.tsx imports ConnectButton directly from @rainbow-me/rainbowkit (line 3) and renders it with custom props (lines 72-77). This wrapper provides no value and should be deleted.
🤖 Prompt for AI Agents
In src/components/wallet-connect.tsx around lines 5 to 7, the WalletConnect
wrapper simply returns <ConnectButton /> and is unused; delete this file and
remove any imports referencing it (if present) so components import
ConnectButton directly from @rainbow-me/rainbowkit (like Navbar.tsx already
does). Ensure there are no leftover exports or barrel-file references to
src/components/wallet-connect.tsx and run the build/tests to confirm nothing
else depends on it.
| export function useWallet() { | ||
| const { address, isConnected, connector } = useAccount() | ||
| const chainId = useChainId() | ||
|
|
||
| return { | ||
| address, | ||
| isConnected, | ||
| chainId, | ||
| connector, | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
rg -nP --type=ts --type=tsx -C3 '\buseWallet\b' -g '!src/hooks/useWallet.ts'Repository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 115
🏁 Script executed:
rg -nP '\buseWallet\b' -g '*.ts' -g '*.tsx' --exclude='src/hooks/useWallet.ts'Repository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 499
🏁 Script executed:
rg '\buseWallet\b' -g '*.ts' -g '*.tsx'Repository: StabilityNexus/Bene-FundRaising-EVM-Frontend
Length of output: 140
Remove the unused useWallet hook.
This custom hook is not referenced anywhere in the codebase and is dead code. Since components import useAccount directly from wagmi instead, the wrapper provides no value.
🤖 Prompt for AI Agents
In src/hooks/useWallet.ts around lines 3 to 13, the useWallet hook is unused
dead code; delete the file (or remove the exported function) and clean up any
exports/index barrel that re-exports it; search the repo for imports of
src/hooks/useWallet.ts and replace them to import useAccount/useChainId directly
from wagmi where needed, then run tests/TypeScript build to ensure no missing
references remain.
|
|
||
|
|
||
| export const wagmiConfig = getDefaultConfig({ | ||
| appName: "YourAppName", |
There was a problem hiding this comment.
Replace placeholder appName with actual application name.
The appName is set to "YourAppName", which is clearly a placeholder. This value appears in wallet connection prompts and should reflect the actual application name "Bene" (as seen in the Navbar logo).
Apply this diff:
export const wagmiConfig = getDefaultConfig({
- appName: "YourAppName",
+ appName: "Bene",
projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| appName: "YourAppName", | |
| appName: "Bene", |
🤖 Prompt for AI Agents
In src/lib/wallet/config.ts around line 7, the appName is currently set to the
placeholder "YourAppName"; update this value to the real application name "Bene"
so wallet connection prompts and related UI display the correct app name
(replace the placeholder string with "Bene").
|
|
||
| export const wagmiConfig = getDefaultConfig({ | ||
| appName: "YourAppName", | ||
| projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!, |
There was a problem hiding this comment.
Add runtime validation for required environment variable.
The non-null assertion operator (!) on NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID will fail silently if the variable is undefined, leading to runtime errors when wallet functionality is used. Add explicit validation with a helpful error message.
Apply this diff to validate the environment variable:
+const projectId = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID
+if (!projectId) {
+ throw new Error(
+ "NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID is not defined. " +
+ "Please add it to your .env.local file."
+ )
+}
+
export const wagmiConfig = getDefaultConfig({
appName: "YourAppName",
- projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!,
+ projectId,
chains: supportedChains as const,📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| projectId: process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!, | |
| const projectId = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID | |
| if (!projectId) { | |
| throw new Error( | |
| "NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID is not defined. " + | |
| "Please add it to your .env.local file." | |
| ) | |
| } | |
| export const wagmiConfig = getDefaultConfig({ | |
| appName: "YourAppName", | |
| projectId, | |
| chains: supportedChains as const, |
🤖 Prompt for AI Agents
In src/lib/wallet/config.ts around line 8, the code uses a non-null assertion
for NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID which can fail silently; replace this
with an explicit runtime validation: read
process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID into a const, check if it's
missing or empty, and if so throw a clear Error (e.g. "Missing
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID environment variable - required for
WalletConnect") so the application fails fast with an actionable message;
otherwise assign the validated value to projectId.
Summary
This PR resolves the wallet connection issue by integrating RainbowKit and Wagmi, enabling a provider-agnostic and multi-wallet connection flow.
What was the issue
Previously, clicking the “Connect Wallet” button did not reliably display available wallet options and depended on ReOwn’s WalletConnect SDK, introducing centralization and reliability concerns.
What changed
Result
Verification
Closes #ISSUE_NUMBER
Summary by CodeRabbit
Release Notes
New Features
Improvements
Chores
✏️ Tip: You can customize this high-level summary in your review settings.