Skip to content

feat: Add RainbowKit for multi-wallet support#18

Open
Amarudinn wants to merge 1 commit intogenlayerlabs:mainfrom
Amarudinn:main
Open

feat: Add RainbowKit for multi-wallet support#18
Amarudinn wants to merge 1 commit intogenlayerlabs:mainfrom
Amarudinn:main

Conversation

@Amarudinn
Copy link

@Amarudinn Amarudinn commented Jan 10, 2026

This PR replaces the MetaMask-only wallet connection with RainbowKit, enabling support for 100+ wallets including MetaMask, WalletConnect, Coinbase Wallet, Rainbow, and more

Summary by CodeRabbit

  • New Features
    • Added multi-wallet support—users can now connect using various wallet providers instead of a single option.
    • Introduced WalletConnect integration for enhanced wallet connectivity.
    • Streamlined wallet connection flow with one-click connection, network switching, and account management.
    • Enabled persistent wallet sessions, maintaining connection across browser sessions.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 10, 2026

📝 Walkthrough

Walkthrough

Migrates wallet integration from custom MetaMask implementation to RainbowKit and Wagmi-based multi-wallet support, introducing automated GenLayer chain configuration, simplified UI components, and consolidated wallet state management via wagmi hooks.

Changes

Cohort / File(s) Summary
Configuration & Build Setup
frontend/.env.example, frontend/next.config.ts, frontend/package.json
Added NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID environment variable; switched build system from Turbopack to Webpack with fallback and externals configuration; added RainbowKit dependency and updated dev/build scripts to use Turbopack/Webpack flags respectively.
Wallet Infrastructure & Chain Configuration
frontend/lib/wagmi/config.ts, frontend/lib/genlayer/WalletProvider.tsx, frontend/lib/genlayer/client.ts, frontend/lib/genlayer/wallet.ts
Introduced new wagmi/RainbowKit configuration with custom GenLayer chain definition; replaced manual MetaMask state management with wagmi hooks (useAccount, useChainId, useDisconnect) and RainbowKit modals; removed 15+ MetaMask-specific utilities; simplified createGenLayerClient to inject address when provided; changed WalletState.chainId from string|null to number|null and connectWallet from Promise to void.
Provider Setup
frontend/app/providers.tsx
Added WagmiProvider and RainbowKitProvider composition with dark theme configuration and CSS imports; reordered providers to nest WalletProvider inside RainbowKitProvider for proper context availability.
UI Components
frontend/components/AccountPanel.tsx, frontend/components/BetsTable.tsx, frontend/components/CreateBetModal.tsx
Replaced custom wallet connection dialogs with RainbowKit's ConnectButton.Custom integration; removed manual wallet state handlers; updated error handling to trigger connectWallet instead of showing error toasts when address is missing.
Utilities & Hooks
frontend/lib/utils/toast.ts, frontend/lib/hooks/useFootballBets.ts
Removed options parameter from toast.promise function signature (simplifying toast API); removed config error toast from useFootballBets contract initialization.
Documentation
frontend/README.md
Updated environment variables (renamed NEXT_PUBLIC_STUDIO_URL to NEXT_PUBLIC_GENLAYER_RPC_URL, added NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID); documented tech stack upgrades (Next.js 16, React 19, RainbowKit, wagmi, viem); added wallet connection flow sections with RainbowKit integration details and WalletConnect setup instructions.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant RainbowKit as RainbowKit UI
    participant Wagmi as Wagmi Hooks
    participant WalletProvider
    participant GenLayerClient as GenLayer Client
    participant RPC as GenLayer RPC

    User->>RainbowKit: Click Connect Wallet
    RainbowKit->>User: Show wallet options modal
    User->>RainbowKit: Select wallet (MetaMask, WalletConnect, etc.)
    RainbowKit->>Wagmi: Initiate connection
    Wagmi->>Wagmi: useAccount hook updates
    Wagmi->>WalletProvider: Provide address & chain info
    WalletProvider->>GenLayerClient: Initialize with address
    GenLayerClient->>GenLayerClient: Inject address into config
    GenLayerClient->>RPC: Ready for GenLayer RPC calls
    GenLayerClient-->>WalletProvider: Client ready
    WalletProvider-->>RainbowKit: Connection complete
    RainbowKit-->>User: Display connected wallet & balance
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~55 minutes

Possibly related PRs

Suggested reviewers

  • JoaquinBN

Poem

🐰 Hops with joy, whiskers twitching bright
From MetaMask chains to wagmi's light,
Multi-wallets bloom like garden beds,
RainbowKit buttons in rainbow threads!
One config, one truth, connection flows free, 🌈✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: adding RainbowKit for multi-wallet support, which aligns with the PR's core objective of replacing MetaMask-only connectivity with RainbowKit's 100+ wallet support.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
frontend/lib/hooks/useFootballBets.ts (1)

17-31: Add error feedback for read-only contract queries.

The useFootballBetsContract() hook silently returns null when NEXT_PUBLIC_CONTRACT_ADDRESS is not configured. While mutation operations (useCreateBet, useResolveBet) do provide error feedback via the error toast, read-only queries (useBets, useLeaderboard, usePlayerPoints) return empty data without notifying users that the contract is misconfigured. Users viewing the app initially will see an empty leaderboard and bets list without understanding why.

Consider adding a provider-level validation or initialization check that displays a setup warning when the contract address is missing, ensuring users are aware of the configuration issue regardless of which operation they attempt.

frontend/lib/genlayer/client.ts (1)

41-48: Silent fallback may mask account configuration issues.

When client creation fails with an address, the catch block returns a client without the account. The caller has no indication that the address wasn't applied, which could lead to confusing transaction failures.

Consider either re-throwing the error or returning a discriminated result so callers can handle the degraded state appropriately.

♻️ Alternative: Let errors propagate
   try {
     return createClient(config);
   } catch (error) {
     console.error("Error creating GenLayer client:", error);
-    return createClient({
-      chain: studionet,
-    });
+    throw error; // Let caller decide how to handle
   }
🤖 Fix all issues with AI agents
In @frontend/lib/utils/toast.ts:
- Around line 83-96: Restore the original promise signature to accept an
optional options parameter and ensure defaultOptions are applied like the other
toast helpers: update the export const promise<T>(promiseArg: Promise<T>,
messages: { loading: string; success: string | ((result: T) => string); error:
string | ((error: any) => string); }, options?: ToastOptions) => { ... } so you
pass merged options (e.g., { ...defaultOptions, ...options }) into
sonnerToast.promise; reference the promise function and defaultOptions variable
to locate where to merge and pass these options so existing callers and styling
remain unchanged.

In @frontend/lib/wagmi/config.ts:
- Around line 31-37: The fallback WALLETCONNECT_PROJECT_ID uses an invalid
placeholder ("demo-project-id") which breaks WalletConnect; update the
initialization so that when WALLETCONNECT_PROJECT_ID is missing or equals the
placeholder you either log a clear runtime warning or throw in development;
modify the code around the WALLETCONNECT_PROJECT_ID constant and the
getDefaultConfig call (where wagmiConfig is created) to validate the project id
at startup and abort or warn accordingly so misconfiguration is surfaced early.

In @frontend/package.json:
- Around line 7-8: The dev and build NPM scripts in package.json use different
bundlers ("dev": "next dev --turbopack" vs "build": "next build --webpack"),
which is inconsistent and can hide bundler-specific bugs; pick one bundler for
both or document the reason: either set "build" to use Turbopack (e.g., change
the build script to use next build or next build --turbopack) or change "dev" to
use Webpack (next dev --webpack) if you rely on Webpack-only features, or add a
clear comment in package.json explaining why the discrepancy is necessary
(mention the "dev" and "build" script entries when making the change).

In @frontend/README.md:
- Around line 59-60: The README incorrectly lists "Next.js 16" and imprecisely
"React 19"; update the version strings in the README: change the "Next.js 16"
entry to "Next.js 15" and change the "React 19" entry to "React 19.2" (locate
the lines containing the literal strings "Next.js 16" and "React 19" and replace
them accordingly).
🧹 Nitpick comments (6)
frontend/README.md (1)

26-27: Format URLs as markdown links.

The bare URLs should be formatted as proper markdown links for better readability and to pass linting.

📝 Proposed markdown formatting
-   - `NEXT_PUBLIC_GENLAYER_RPC_URL` - GenLayer RPC URL (default: https://studio.genlayer.com/api)
-   - `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` - WalletConnect Project ID (get free at https://cloud.walletconnect.com)
+   - `NEXT_PUBLIC_GENLAYER_RPC_URL` - GenLayer RPC URL (default: <https://studio.genlayer.com/api>)
+   - `NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID` - WalletConnect Project ID (get free at <https://cloud.walletconnect.com>)

Based on static analysis hints.

frontend/next.config.ts (1)

5-11: LGTM - Standard webpack fixes for RainbowKit/WalletConnect compatibility.

The fallbacks and externals configuration correctly handle Node.js-only modules that cause issues in browser/SSR contexts. This is a well-known pattern for wallet library integration.

Minor note: config.externals.push assumes externals is an array. This is the default in Next.js, but if you want to be defensive:

♻️ Optional defensive check
  webpack: (config) => {
    config.resolve.fallback = { fs: false, net: false, tls: false };
-   config.externals.push("pino-pretty", "lokijs", "encoding");
+   if (Array.isArray(config.externals)) {
+     config.externals.push("pino-pretty", "lokijs", "encoding");
+   } else {
+     config.externals = ["pino-pretty", "lokijs", "encoding"];
+   }
    return config;
  },
frontend/lib/wagmi/config.ts (3)

7-7: Add radix parameter to parseInt.

While parseInt defaults to base 10 for numeric strings, explicitly specifying the radix improves clarity and avoids edge cases with strings that might start with "0".

♻️ Suggested fix
-const GENLAYER_CHAIN_ID = parseInt(process.env.NEXT_PUBLIC_GENLAYER_CHAIN_ID || "61999");
+const GENLAYER_CHAIN_ID = parseInt(process.env.NEXT_PUBLIC_GENLAYER_CHAIN_ID || "61999", 10);

16-19: Consider using a descriptive name for nativeCurrency.name.

Currently both name and symbol use GENLAYER_SYMBOL. Wallet UIs typically display the name as a human-readable label (e.g., "GenLayer Token") while symbol is the ticker (e.g., "GEN").

♻️ Optional improvement
+const GENLAYER_CURRENCY_NAME = process.env.NEXT_PUBLIC_GENLAYER_CURRENCY_NAME || "GenLayer Token";
+
 nativeCurrency: {
-  name: GENLAYER_SYMBOL,
+  name: GENLAYER_CURRENCY_NAME,
   symbol: GENLAYER_SYMBOL,
   decimals: 18,
 },

35-36: Consider making appName configurable for boilerplate reuse.

The hardcoded app name "GenLayer Football Betting" is project-specific. For a boilerplate, consider sourcing this from an environment variable.

♻️ Optional improvement
+const APP_NAME = process.env.NEXT_PUBLIC_APP_NAME || "GenLayer App";
+
 export const wagmiConfig = getDefaultConfig({
-  appName: "GenLayer Football Betting",
+  appName: APP_NAME,
frontend/lib/genlayer/client.ts (1)

32-48: Avoid any type and ensure consistent RPC configuration.

Two concerns:

  1. Type safety: Using any for config defeats TypeScript's benefits. The ClientConfig type should be used instead.

  2. RPC configuration inconsistency: The function uses the studionet chain but does not explicitly set the endpoint parameter, while getStudioUrl() is defined in this same file and used elsewhere (e.g., useFootballBets.ts). For consistency with the environment-configured RPC URL, the endpoint should be explicitly set.

♻️ Suggested improvement
+import type { ClientConfig } from "genlayer-js";
+
 export function createGenLayerClient(address?: string) {
-  const config: any = {
+  const config: ClientConfig = {
     chain: studionet,
+    endpoint: getStudioUrl(),
   };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2164ec6 and 4b2f2e5.

⛔ Files ignored due to path filters (2)
  • frontend/public/genlayer-icon.svg is excluded by !**/*.svg
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (14)
  • frontend/.env.example
  • frontend/README.md
  • frontend/app/providers.tsx
  • frontend/components/AccountPanel.tsx
  • frontend/components/BetsTable.tsx
  • frontend/components/CreateBetModal.tsx
  • frontend/lib/genlayer/WalletProvider.tsx
  • frontend/lib/genlayer/client.ts
  • frontend/lib/genlayer/wallet.ts
  • frontend/lib/hooks/useFootballBets.ts
  • frontend/lib/utils/toast.ts
  • frontend/lib/wagmi/config.ts
  • frontend/next.config.ts
  • frontend/package.json
💤 Files with no reviewable changes (1)
  • frontend/lib/genlayer/wallet.ts
🧰 Additional context used
📓 Path-based instructions (4)
frontend/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Frontend should be implemented with Next.js 15, React 19, TypeScript, Tailwind CSS, TanStack Query, and Wagmi/Viem for wallet integration

Files:

  • frontend/components/AccountPanel.tsx
  • frontend/next.config.ts
  • frontend/lib/utils/toast.ts
  • frontend/app/providers.tsx
  • frontend/lib/genlayer/WalletProvider.tsx
  • frontend/lib/wagmi/config.ts
  • frontend/components/CreateBetModal.tsx
  • frontend/lib/hooks/useFootballBets.ts
  • frontend/components/BetsTable.tsx
  • frontend/lib/genlayer/client.ts
frontend/lib/genlayer/WalletProvider.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain wallet context provider in frontend/lib/genlayer/WalletProvider.tsx

Files:

  • frontend/lib/genlayer/WalletProvider.tsx
frontend/lib/hooks/use*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Store React hooks for contract interactions in frontend/lib/hooks/ directory with naming pattern use<ContractName>.ts

Files:

  • frontend/lib/hooks/useFootballBets.ts
frontend/lib/genlayer/client.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain GenLayer client initialization in frontend/lib/genlayer/client.ts

Files:

  • frontend/lib/genlayer/client.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/lib/genlayer/WalletProvider.tsx : Maintain wallet context provider in `frontend/lib/genlayer/WalletProvider.tsx`
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/**/*.{ts,tsx} : Frontend should be implemented with Next.js 15, React 19, TypeScript, Tailwind CSS, TanStack Query, and Wagmi/Viem for wallet integration
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/lib/genlayer/WalletProvider.tsx : Maintain wallet context provider in `frontend/lib/genlayer/WalletProvider.tsx`

Applied to files:

  • frontend/components/AccountPanel.tsx
  • frontend/app/providers.tsx
  • frontend/lib/genlayer/WalletProvider.tsx
  • frontend/.env.example
  • frontend/lib/wagmi/config.ts
  • frontend/README.md
  • frontend/components/CreateBetModal.tsx
  • frontend/components/BetsTable.tsx
  • frontend/lib/genlayer/client.ts
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/**/*.{ts,tsx} : Frontend should be implemented with Next.js 15, React 19, TypeScript, Tailwind CSS, TanStack Query, and Wagmi/Viem for wallet integration

Applied to files:

  • frontend/components/AccountPanel.tsx
  • frontend/next.config.ts
  • frontend/app/providers.tsx
  • frontend/lib/genlayer/WalletProvider.tsx
  • frontend/.env.example
  • frontend/lib/wagmi/config.ts
  • frontend/README.md
  • frontend/components/CreateBetModal.tsx
  • frontend/components/BetsTable.tsx
  • frontend/package.json
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/.env : Store contract address in `frontend/.env` as `NEXT_PUBLIC_CONTRACT_ADDRESS` environment variable after deployment

Applied to files:

  • frontend/.env.example
  • frontend/README.md
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/lib/genlayer/client.ts : Maintain GenLayer client initialization in `frontend/lib/genlayer/client.ts`

Applied to files:

  • frontend/lib/wagmi/config.ts
  • frontend/lib/genlayer/client.ts
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Follow the development workflow: ensure GenLayer Studio is running, select network with `genlayer network`, deploy contract with `npm run deploy`, update frontend environment variable, and run frontend with `cd frontend && bun dev`

Applied to files:

  • frontend/lib/wagmi/config.ts
  • frontend/README.md
  • frontend/package.json
  • frontend/lib/genlayer/client.ts
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/lib/hooks/use*.{ts,tsx} : Store React hooks for contract interactions in `frontend/lib/hooks/` directory with naming pattern `use<ContractName>.ts`

Applied to files:

  • frontend/lib/hooks/useFootballBets.ts
📚 Learning: 2025-12-10T12:30:13.640Z
Learnt from: CR
Repo: genlayerlabs/genlayer-project-boilerplate PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-10T12:30:13.640Z
Learning: Applies to frontend/lib/contracts/**/*.{ts,tsx} : Store contract interactions code in `frontend/lib/contracts/` directory

Applied to files:

  • frontend/lib/hooks/useFootballBets.ts
🧬 Code graph analysis (4)
frontend/app/providers.tsx (3)
frontend/lib/wagmi/config.ts (1)
  • wagmiConfig (35-43)
frontend/lib/genlayer/WalletProvider.tsx (1)
  • WalletProvider (28-68)
frontend/lib/genlayer/wallet.ts (1)
  • WalletProvider (6-6)
frontend/lib/genlayer/WalletProvider.tsx (3)
frontend/lib/genlayer/wallet.ts (2)
  • WalletState (7-7)
  • WalletProvider (6-6)
frontend/lib/genlayer/client.ts (1)
  • GENLAYER_CHAIN_ID (7-7)
frontend/lib/wagmi/config.ts (1)
  • GENLAYER_CHAIN_ID (46-46)
frontend/lib/wagmi/config.ts (1)
frontend/lib/genlayer/client.ts (1)
  • GENLAYER_CHAIN_ID (7-7)
frontend/components/CreateBetModal.tsx (2)
frontend/lib/genlayer/WalletProvider.tsx (1)
  • useWallet (74-80)
frontend/lib/genlayer/wallet.ts (1)
  • useWallet (6-6)
🪛 markdownlint-cli2 (0.18.1)
frontend/README.md

26-26: Bare URL used

(MD034, no-bare-urls)


27-27: Bare URL used

(MD034, no-bare-urls)

🔇 Additional comments (13)
frontend/.env.example (1)

14-17: LGTM!

The WalletConnect project ID configuration is well-documented with clear instructions on how to obtain it. The NEXT_PUBLIC_ prefix correctly exposes this to the client side, which is required for RainbowKit's WalletConnect integration.

frontend/README.md (1)

70-102: LGTM!

The wallet connection documentation is comprehensive and well-structured. It clearly explains the supported wallets, how to obtain a WalletConnect Project ID, and the features provided by the RainbowKit integration.

frontend/components/CreateBetModal.tsx (2)

14-14: LGTM - Improved wallet connection UX!

The change from showing an error toast to calling connectWallet() provides a better user experience. Instead of displaying an error message when the wallet isn't connected, it now proactively opens the wallet connection modal, aligning well with the RainbowKit integration.

Also applies to: 69-72


82-82: LGTM - Simplified property assignment.

Removing the redundant type annotation is appropriate since predictedWinner is already correctly typed in the component state (line 21).

frontend/components/BetsTable.tsx (1)

14-14: LGTM! Improved wallet connection UX.

The change from showing an error toast to proactively triggering wallet connection provides a better user experience. Users can now connect their wallet directly when attempting to resolve a bet, rather than receiving an error message.

Also applies to: 18-21

frontend/app/providers.tsx (1)

28-61: LGTM! Correct provider composition for RainbowKit integration.

The provider nesting follows the required pattern for Wagmi/RainbowKit:

  • WagmiProvider at the outermost level provides blockchain context
  • QueryClientProvider required for RainbowKit's internal queries
  • RainbowKitProvider provides wallet UI components
  • WalletProvider provides the application's wallet context

The custom theme configuration appropriately applies GenLayer branding with the purple accent color.

frontend/lib/genlayer/WalletProvider.tsx (2)

3-6: LGTM! Clean integration with Wagmi/RainbowKit.

The refactor successfully replaces custom MetaMask-specific wallet management with Wagmi/RainbowKit hooks, resulting in a simpler and more maintainable implementation. The use of wagmi hooks (useAccount, useChainId, useDisconnect) and RainbowKit modals (useConnectModal, useAccountModal) is idiomatic and follows best practices.

Based on coding guidelines, the wallet context provider is correctly maintained in this file.

Also applies to: 29-36


10-10: No breaking changes to address in consumer code.

All usages of useWallet() throughout the codebase are already compliant with the current API design. No instances of the following were found:

  • Awaiting or chaining connectWallet() calls (it's correctly called as a void function)
  • References to removed switchWalletAccount method
  • String-based chainId comparisons

Consumer components (BetsTable.tsx, CreateBetModal.tsx, AccountPanel.tsx) correctly use connectWallet() as a modal trigger and openAccountModal for account interactions.

frontend/components/AccountPanel.tsx (1)

22-134: LGTM! Excellent RainbowKit integration.

The implementation correctly uses ConnectButton.Custom to provide a branded wallet connection experience while leveraging RainbowKit's built-in functionality. The code properly handles all connection states:

  • Not connected: Shows branded "Connect Wallet" button
  • Wrong network: Highlights network mismatch with warning styling
  • Connected: Displays chain selector and account controls with balance

The accessibility handling (aria-hidden during loading) and responsive design (conditional display on smaller screens) demonstrate good attention to detail.

frontend/package.json (1)

17-17: No action required. RainbowKit 2.2.4 is fully compatible with React 19.2.0 (React 19 support was added in v2.2.2).

frontend/lib/wagmi/config.ts (1)

38-46: LGTM - Chain and transport configuration is correct.

The wagmi config properly sets up the GenLayer chain with HTTP transport and SSR support. The re-exports allow centralized chain configuration to be consumed by other modules like client.ts.

frontend/lib/genlayer/client.ts (2)

6-7: Good centralization of chain configuration.

Re-exporting GENLAYER_CHAIN_ID from the wagmi config consolidates the chain identity to a single source of truth. This aligns with the PR's goal of unified wallet configuration.


12-27: Utility functions look good.

getStudioUrl() and getContractAddress() are clean environment variable accessors with sensible defaults.

Comment on lines 83 to 96
export const promise = <T>(
promise: Promise<T>,
promiseArg: Promise<T>,
messages: {
loading: string;
success: string | ((result: T) => string);
error: string | ((error: any) => string);
},
options?: ExternalToast
}
) => {
return sonnerToast.promise(promise, {
return sonnerToast.promise(promiseArg, {
loading: messages.loading,
success: messages.success,
error: messages.error,
}, {
...defaultOptions,
...options,
});
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Breaking change: Removed options parameter and defaultOptions styling.

This change introduces two issues:

  1. Breaking API change: The options parameter was removed from the promise function signature, which will break any existing code passing options to promise toasts.

  2. Styling inconsistency: The promise toast no longer applies defaultOptions (which includes brand styling, duration, and close button), while all other toast methods (success, error, warning, info, loading) do. This creates visual inconsistency.

♻️ Restore options parameter and defaultOptions
 export const promise = <T>(
   promiseArg: Promise<T>,
   messages: {
     loading: string;
     success: string | ((result: T) => string);
     error: string | ((error: any) => string);
-  }
+  },
+  options?: ExternalToast
 ) => {
   return sonnerToast.promise(promiseArg, {
     loading: messages.loading,
     success: messages.success,
     error: messages.error,
-  });
+  }, {
+    ...defaultOptions,
+    ...options,
+  });
 };
🤖 Prompt for AI Agents
In @frontend/lib/utils/toast.ts around lines 83 - 96, Restore the original
promise signature to accept an optional options parameter and ensure
defaultOptions are applied like the other toast helpers: update the export const
promise<T>(promiseArg: Promise<T>, messages: { loading: string; success: string
| ((result: T) => string); error: string | ((error: any) => string); },
options?: ToastOptions) => { ... } so you pass merged options (e.g., {
...defaultOptions, ...options }) into sonnerToast.promise; reference the promise
function and defaultOptions variable to locate where to merge and pass these
options so existing callers and styling remain unchanged.

Comment on lines +31 to +37
// RainbowKit configuration with GenLayer chain
// Note: Get your projectId from https://cloud.walletconnect.com (free)
const WALLETCONNECT_PROJECT_ID = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID || "demo-project-id";

export const wagmiConfig = getDefaultConfig({
appName: "GenLayer Football Betting",
projectId: WALLETCONNECT_PROJECT_ID,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

WalletConnect will fail with placeholder project ID.

The fallback "demo-project-id" is not a valid WalletConnect project ID. WalletConnect-based connections (including many mobile wallets) will fail when this placeholder is used. Consider adding a runtime warning or throwing during development to catch misconfiguration early.

♻️ Suggested improvement
-const WALLETCONNECT_PROJECT_ID = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID || "demo-project-id";
+const WALLETCONNECT_PROJECT_ID = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID;
+
+if (!WALLETCONNECT_PROJECT_ID) {
+  console.warn(
+    "⚠️ NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID is not set. " +
+    "WalletConnect-based wallets will not work. " +
+    "Get a free project ID at https://cloud.walletconnect.com"
+  );
+}

 export const wagmiConfig = getDefaultConfig({
   appName: "GenLayer Football Betting",
-  projectId: WALLETCONNECT_PROJECT_ID,
+  projectId: WALLETCONNECT_PROJECT_ID || "placeholder",
🤖 Prompt for AI Agents
In @frontend/lib/wagmi/config.ts around lines 31 - 37, The fallback
WALLETCONNECT_PROJECT_ID uses an invalid placeholder ("demo-project-id") which
breaks WalletConnect; update the initialization so that when
WALLETCONNECT_PROJECT_ID is missing or equals the placeholder you either log a
clear runtime warning or throw in development; modify the code around the
WALLETCONNECT_PROJECT_ID constant and the getDefaultConfig call (where
wagmiConfig is created) to validate the project id at startup and abort or warn
accordingly so misconfiguration is surfaced early.

Comment on lines +7 to +8
"dev": "next dev --turbopack",
"build": "next build --webpack",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Next.js 16 Turbopack Webpack support compatibility

💡 Result:

Short answer

  • Next.js 16 makes Turbopack the default bundler (dev + build). [1][2]
  • Webpack is still supported but only when you explicitly opt in (use --webpack for dev/build). If Next.js detects a custom webpack config and you run the default Turbopack build it may fail — you must either migrate, run with --webpack, or explicitly build with Turbopack flags. [1][2][3]

Key details and commands

  • Default: next dev / next build use Turbopack. [1][2]
  • Opt-in Webpack (example): next dev --webpack ; next build --webpack. Use these if you rely on custom webpack config or loaders not yet supported by Turbopack. [1][3]
  • If you want Turbopack in both dev and build explicitly: next dev --turbopack (older flag) or just use defaults in v16. [2][1]

Compatibility notes / limitations

  • Some webpack-specific config, loaders or custom webpack() options are not supported by Turbopack; presence of such config can cause builds to fail when using the default Turbopack path. [2][3]
  • Turbopack aims to cover the common cases and offers built-in handling for JS/TS, CSS, ESM/CommonJS, SWC/Babel interplay, plus filesystem caching options — but complex/custom webpack setups may need migration or to keep using Webpack. [1][3]

Sources

  • Next.js 16 announcement / blog. [1]
  • Next.js v16 upgrade guide (opt-out/webpack guidance). [2]
  • Next.js Turbopack API / docs (Webpack interoperability and supported features). [3]

🌐 Web query:

Next.js --turbopack --webpack dev build different bundlers

💡 Result:

Short answer

  • Next.js uses Turbopack as the default dev bundler (fast Rust-based incremental bundler). To opt into Webpack instead run dev with --webpack (e.g. "next dev --webpack") or opt into Turbopack with --turbopack / --turbo. [1][2][3]

Key differences (dev)

  • Speed & memory: Turbopack is much faster and more memory-efficient for large dev projects because it is incremental and lazy. [1][7]
  • Configuration: Turbopack ignores webpack() config in next.config.js; many webpack-specific loaders/plugins or non-serializable options aren’t supported in Turbopack. If you rely on custom webpack config or certain loaders (Babel-based flows, custom Sass functions, some plugins), use Webpack. [1][4]
  • Feature coverage: Turbopack aims to cover most Next.js workflows but some features remain unsupported or experimental (and production builds support arrived later than dev). Check docs for exact unsupported items before switching. [1][7]

How to choose / switch

  • Use Turbopack dev (default): next dev or next dev --turbopack. [1]
  • Force Webpack dev: next dev --webpack (also valid for next build if you need Webpack for production). [1][3]
  • If you have a webpack() config or plugins that require Node-based loaders, keep --webpack. Otherwise prefer Turbopack for dev speed. [2][4]

Notes / caveats

  • Turbopack’s production/build story has been evolving; historically dev was stable earlier than build—verify current Next.js version docs before assuming build parity. If you need Turbopack for build, explicitly run next build --turbopack and confirm support in your Next.js version. [7][3]
  • If a plugin adds a webpack config detection, Next may choose Webpack unless you pass flags to override. [3]

Sources
[1] Next.js Turbopack API / docs.
[2] Next.js blog — Turbopack for development.
[3] Next.js upgrade guide / opting out (use --webpack).


Clarify why dev and build use different bundlers.

The dev script uses --turbopack while the build script uses --webpack. Next.js 16 defaults to Turbopack for both dev and build; using different bundlers between dev and build is inconsistent and may mask issues (e.g., if code works in dev but fails in build, or vice versa).

Either:

  • Use Turbopack for both (Next.js 16 default): "build": "next build" or explicitly "next build --turbopack"
  • Use Webpack for both if you have webpack-specific config or dependencies: "dev": "next dev --webpack"
  • Document why different bundlers are necessary (e.g., webpack dependency not yet supported by Turbopack)
🤖 Prompt for AI Agents
In @frontend/package.json around lines 7 - 8, The dev and build NPM scripts in
package.json use different bundlers ("dev": "next dev --turbopack" vs "build":
"next build --webpack"), which is inconsistent and can hide bundler-specific
bugs; pick one bundler for both or document the reason: either set "build" to
use Turbopack (e.g., change the build script to use next build or next build
--turbopack) or change "dev" to use Webpack (next dev --webpack) if you rely on
Webpack-only features, or add a clear comment in package.json explaining why the
discrepancy is necessary (mention the "dev" and "build" script entries when
making the change).

Comment on lines +59 to +60
- **Next.js 16** - React framework with App Router
- **React 19** - Latest React with concurrent features
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Correct the Next.js version.

Line 59 claims "Next.js 16" but Next.js 16 has not been released. According to the coding guidelines and current Next.js releases, this should be "Next.js 15". Additionally, line 60 should specify "React 19.2" for precision, as that's the actual version in use per the library context.

📝 Proposed version corrections
-- **Next.js 16** - React framework with App Router
-- **React 19** - Latest React with concurrent features
+- **Next.js 15** - React framework with App Router
+- **React 19.2** - Latest React with concurrent features

Based on coding guidelines.

📝 Committable suggestion

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

Suggested change
- **Next.js 16** - React framework with App Router
- **React 19** - Latest React with concurrent features
- **Next.js 15** - React framework with App Router
- **React 19.2** - Latest React with concurrent features
🤖 Prompt for AI Agents
In @frontend/README.md around lines 59 - 60, The README incorrectly lists
"Next.js 16" and imprecisely "React 19"; update the version strings in the
README: change the "Next.js 16" entry to "Next.js 15" and change the "React 19"
entry to "React 19.2" (locate the lines containing the literal strings "Next.js
16" and "React 19" and replace them accordingly).

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.

1 participant