Repository: peanutprotocol/peanut-ui
Pull request #844: Prod release fixes
Author: login: jjramirezn
Created: 2025-05-12T17:40:44Z | Merged: 2025-05-12T18:40:56Z

contributes to TASK-11169
contributes to TASK-9923

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Users without a "peanut-wallet" account will now have one created automatically when accessing the Home page.

- **Improvements**
  - Deposit links now use a dynamic base URL, allowing for better environment configuration.
  - Expanded support for public paths in the mobile layout, improving routing flexibility.
  - Centralized base URL configuration across the app for metadata, previews, and sitemap URLs.
  - Improved stability in claim link handling by preventing potential errors with safer data access.

- **Refactor**
  - Toast notifications have been streamlined with a new toast system, and user profile update methods have been removed from the authentication context.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->


Diff:
diff --git a/src/app/(mobile-ui)/claim/page.tsx b/src/app/(mobile-ui)/claim/page.tsx
index 5d44a3367..ef1ebb5c2 100644
--- a/src/app/(mobile-ui)/claim/page.tsx
+++ b/src/app/(mobile-ui)/claim/page.tsx
@@ -2,6 +2,7 @@ import { getLinkDetails } from '@/app/actions/claimLinks'
 import { Claim } from '@/components'
 import { formatAmount } from '@/utils'
 import { Metadata } from 'next'
+import { BASE_URL } from '@/constants'
 
 export const dynamic = 'force-dynamic'
 
@@ -15,7 +16,7 @@ export async function generateMetadata({
     const resolvedSearchParams = await searchParams
 
     let title = 'Claim your tokens!'
-    const host = process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'
+    const host = BASE_URL
 
     let linkDetails = undefined
     if (resolvedSearchParams.i && resolvedSearchParams.c) {
diff --git a/src/app/(mobile-ui)/home/page.tsx b/src/app/(mobile-ui)/home/page.tsx
index 6b8fc70b2..39579c9a3 100644
--- a/src/app/(mobile-ui)/home/page.tsx
+++ b/src/app/(mobile-ui)/home/page.tsx
@@ -18,11 +18,11 @@ import { useWalletStore } from '@/redux/hooks'
 import { formatExtendedNumber, getUserPreferences, printableUsdc, updateUserPreferences } from '@/utils'
 import Image from 'next/image'
 import Link from 'next/link'
-import { useMemo, useState } from 'react'
+import { useMemo, useState, useEffect } from 'react'
 import { twMerge } from 'tailwind-merge'
 
 export default function Home() {
-    const { balance } = useWallet()
+    const { balance, address } = useWallet()
     const { rewardWalletBalance } = useWalletStore()
     const [isRewardsModalOpen, setIsRewardsModalOpen] = useState(false)
 
@@ -31,7 +31,7 @@ export default function Home() {
         return prefs?.balanceHidden ?? false
     })
 
-    const { username, isFetchingUser, user } = useAuth()
+    const { username, isFetchingUser, user, addAccount } = useAuth()
 
     const userFullName = useMemo(() => {
         if (!user) return
@@ -49,6 +49,18 @@ export default function Home() {
 
     const isLoading = isFetchingUser && !username
 
+    useEffect(() => {
+        // We have some users that didn't have the peanut wallet created
+        // correctly, so we need to create it
+        if (address && user && !user.accounts.some((a) => a.account_type === 'peanut-wallet')) {
+            addAccount({
+                accountIdentifier: address,
+                accountType: 'peanut-wallet',
+                userId: user.user.userId,
+            })
+        }
+    }, [user, address])
+
     if (isLoading) {
         return <PeanutLoading coverFullScreen />
     }
diff --git a/src/app/(mobile-ui)/layout.tsx b/src/app/(mobile-ui)/layout.tsx
index ff3322e4c..78f6b3304 100644
--- a/src/app/(mobile-ui)/layout.tsx
+++ b/src/app/(mobile-ui)/layout.tsx
@@ -16,7 +16,7 @@ import { useEffect, useMemo, useState } from 'react'
 import { twMerge } from 'tailwind-merge'
 import '../../styles/globals.css'
 
-const publicPathRegex = /^\/(request\/pay|claim)/
+const publicPathRegex = /^\/(request\/pay|claim|pay\/.+$)/
 
 const Layout = ({ children }: { children: React.ReactNode }) => {
     const pathName = usePathname()
diff --git a/src/app/(mobile-ui)/link-account/page.tsx b/src/app/(mobile-ui)/link-account/page.tsx
index ba7cea5c5..9547344d3 100644
--- a/src/app/(mobile-ui)/link-account/page.tsx
+++ b/src/app/(mobile-ui)/link-account/page.tsx
@@ -1,11 +1,12 @@
 import { LinkAccountComponent } from '@/components'
+import { BASE_URL } from '@/constants'
 
 import { Metadata } from 'next'
 
 export const metadata: Metadata = {
     title: 'Peanut Protocol',
     description: 'Send crypto via link',
-    metadataBase: new URL('https://peanut.me'),
+    metadataBase: new URL(BASE_URL),
 
     icons: {
         icon: '/favicon.ico',
diff --git a/src/app/(mobile-ui)/profile/page.tsx b/src/app/(mobile-ui)/profile/page.tsx
index e366814a9..4c458b005 100644
--- a/src/app/(mobile-ui)/profile/page.tsx
+++ b/src/app/(mobile-ui)/profile/page.tsx
@@ -1,11 +1,12 @@
 import { Profile } from '@/components'
 import PageContainer from '@/components/0_Bruddle/PageContainer'
 import { Metadata } from 'next'
+import { BASE_URL } from '@/constants'
 
 export const metadata: Metadata = {
     title: 'Profile | Peanut Protocol',
     description: 'Manage your Peanut profile',
-    metadataBase: new URL('https://peanut.me'),
+    metadataBase: new URL(BASE_URL),
 
     icons: {
         icon: '/favicon.ico',
diff --git a/src/app/(mobile-ui)/refund/page.tsx b/src/app/(mobile-ui)/refund/page.tsx
index abf5c9832..f87506fa9 100644
--- a/src/app/(mobile-ui)/refund/page.tsx
+++ b/src/app/(mobile-ui)/refund/page.tsx
@@ -1,10 +1,11 @@
 import { Metadata } from 'next'
 import { Refund } from '@/components'
+import { BASE_URL } from '@/constants'
 
 export const metadata: Metadata = {
     title: 'Peanut Protocol',
     description: 'Send to Anyone',
-    metadataBase: new URL('https://peanut.me'),
+    metadataBase: new URL(BASE_URL),
 
     icons: {
         icon: '/favicon.ico',
diff --git a/src/app/[...recipient]/layout.tsx b/src/app/[...recipient]/layout.tsx
index 516ce318c..5550c33a4 100644
--- a/src/app/[...recipient]/layout.tsx
+++ b/src/app/[...recipient]/layout.tsx
@@ -1,6 +1,7 @@
 import PaymentLayoutWrapper from './payment-layout-wrapper'
 import { printableAddress } from '@/utils'
 import { isAddress } from 'viem'
+import { BASE_URL } from '@/constants'
 
 function getPreviewUrl(
     host: string,
@@ -29,7 +30,7 @@ function getPreviewUrl(
 export async function generateMetadata({ params }: any) {
     let title = 'Request Payment | Peanut'
     let previewUrl = '/metadata-img.jpg'
-    const host = process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'
+    const host = BASE_URL
 
     if (!host) {
         console.error('Error: NEXT_PUBLIC_BASE_URL is not defined')
diff --git a/src/app/metadata.ts b/src/app/metadata.ts
index 050dcb2bb..6500a5cc3 100644
--- a/src/app/metadata.ts
+++ b/src/app/metadata.ts
@@ -1,4 +1,5 @@
 import { Metadata } from 'next'
+import { BASE_URL } from '@/constants'
 
 export function generateMetadata({
     title,
@@ -14,14 +15,14 @@ export function generateMetadata({
     return {
         title,
         description,
-        metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'),
+        metadataBase: new URL(BASE_URL),
         icons: { icon: '/favicon.ico' },
         keywords,
         openGraph: {
             type: 'website',
             title,
             description,
-            url: 'https://peanut.me',
+            url: BASE_URL,
             siteName: 'Peanut Protocol',
             images: [{ url: image, width: 1200, height: 630, alt: title }],
         },
diff --git a/src/app/robots.ts b/src/app/robots.ts
index a64378c7c..7de4250ee 100644
--- a/src/app/robots.ts
+++ b/src/app/robots.ts
@@ -1,4 +1,5 @@
 import type { MetadataRoute } from 'next'
+import { BASE_URL } from '@/constants'
 
 export default function robots(): MetadataRoute.Robots {
     return {
@@ -17,6 +18,6 @@ export default function robots(): MetadataRoute.Robots {
                 crawlDelay: 10,
             },
         ],
-        sitemap: `${process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'}/sitemap.xml`,
+        sitemap: `${BASE_URL}/sitemap.xml`,
     }
 }
diff --git a/src/components/AddFunds/index.tsx b/src/components/AddFunds/index.tsx
index 053055cdb..38a021bac 100644
--- a/src/components/AddFunds/index.tsx
+++ b/src/components/AddFunds/index.tsx
@@ -10,7 +10,7 @@ import { Button, NavIcons } from '../0_Bruddle'
 import Icon from '../Global/Icon'
 import Modal from '../Global/Modal'
 import QRCodeWrapper from '../Global/QRCodeWrapper'
-
+import { BASE_URL } from '@/constants'
 type FundingMethod = 'exchange' | 'request_link' | null
 
 type Wallet = { name: string; logo: string }
@@ -211,7 +211,7 @@ const UsingExchange = () => {
 
 const UsingRequestLink = () => {
     const { user } = useUserStore()
-    const depositLink = `https://peanut.me/${user?.user?.username}?action=deposit`
+    const depositLink = `${BASE_URL}/pay/${user?.user?.username}`
 
     const wallets: Wallet[] = useMemo(
         () => [
diff --git a/src/components/Claim/Claim.tsx b/src/components/Claim/Claim.tsx
index b4d6f3d20..cd218d701 100644
--- a/src/components/Claim/Claim.tsx
+++ b/src/components/Claim/Claim.tsx
@@ -126,7 +126,7 @@ export const Claim = ({}) => {
                 }
                 if (0 < price) setTokenPrice(price)
 
-                if (user && user.user.userId === sendLink.sender.userId) {
+                if (user && user.user.userId === sendLink.sender?.userId) {
                     setLinkState(_consts.claimLinkStateType.CLAIM_SENDER)
                 } else {
                     setLinkState(_consts.claimLinkStateType.CLAIM)
diff --git a/src/constants/general.consts.ts b/src/constants/general.consts.ts
index 3b5b43a4f..46d48d8d1 100644
--- a/src/constants/general.consts.ts
+++ b/src/constants/general.consts.ts
@@ -32,6 +32,8 @@ export const PEANUT_API_URL = (
     process.env.NEXT_PUBLIC_PEANUT_API_URL ||
     'https://api.peanut.to'
 ).replace(/\/$/, '') // remove any accidental trailing slash
+
+export const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'
 export const next_proxy_url = '/api/proxy'
 
 export const supportedMobulaChains = <{ name: string; chainId: string }[]>[
diff --git a/src/context/authContext.tsx b/src/context/authContext.tsx
index 4d1bd74aa..9753fa9d2 100644
--- a/src/context/authContext.tsx
+++ b/src/context/authContext.tsx
@@ -4,18 +4,16 @@ import * as interfaces from '@/interfaces'
 import { useAppDispatch, useUserStore } from '@/redux/hooks'
 import { setupActions } from '@/redux/slices/setup-slice'
 import { type GetUserLinksResponse, fetchWithSentry } from '@/utils'
-import { ToastId, useToast } from '@chakra-ui/react' // TODO: use normmal toasts we use throughout the app, not chakra toasts!
 import { useAppKit } from '@reown/appkit/react'
 import { useRouter } from 'next/navigation'
-import { createContext, ReactNode, useContext, useRef, useState } from 'react'
+import { createContext, ReactNode, useContext, useState } from 'react'
+import { useToast } from '@/components/0_Bruddle/Toast'
 
 interface AuthContextType {
     user: interfaces.IUserProfile | null
     userId: string | undefined
     username: string | undefined
     fetchUser: () => Promise<interfaces.IUserProfile | null>
-    updateUserName: (username: string) => Promise<void>
-    submitProfilePhoto: (file: File) => Promise<void>
     updateBridgeCustomerData: (customer: GetUserLinksResponse) => Promise<void>
     addBYOW: () => Promise<void>
     addAccount: ({
@@ -48,6 +46,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
     const { open: web3modalOpen } = useAppKit()
     const dispatch = useAppDispatch()
     const { user: authUser } = useUserStore()
+    const toast = useToast()
 
     const { data: user, isFetching: isFetchingUser, refetch: fetchUser } = useUserQuery(!authUser?.user.userId)
 
@@ -56,69 +55,8 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
         return fetchedUser ?? null
     }
 
-    const toast = useToast({
-        position: 'bottom-right',
-        duration: 5000,
-        isClosable: true,
-        icon: '🥜',
-    })
-
-    const toastIdRef = useRef<ToastId | undefined>(undefined)
     const [isLoggingOut, setIsLoggingOut] = useState(false)
 
-    const updateUserName = async (username: string) => {
-        if (!user) return
-
-        try {
-            if (toastIdRef.current) {
-                toast.close(toastIdRef.current)
-            }
-            toastIdRef.current = toast({
-                status: 'loading',
-                title: 'Updating username...',
-            }) as ToastId
-            const response = await fetchWithSentry('/api/peanut/user/update-user', {
-                method: 'POST',
-                headers: {
-                    'Content-Type': 'application/json',
-                },
-                body: JSON.stringify({
-                    username: username,
-                    userId: user.user.userId,
-                }),
-            })
-
-            if (response.status === 409) {
-                const data = await response.json()
-                toast.close(toastIdRef.current)
-                toastIdRef.current = toast({
-                    status: 'error',
-                    title: data,
-                }) as ToastId
-
-                return
-            }
-
-            if (!response.ok) {
-                throw new Error(response.statusText)
-            }
-            toast.close(toastIdRef.current)
-            toastIdRef.current = toast({
-                status: 'success',
-                title: 'Username updated successfully',
-            }) as ToastId
-        } catch (error) {
-            console.error('Error updating user', error)
-            toast.close(toastIdRef.current ?? '')
-            toastIdRef.current = toast({
-                status: 'error',
-                title: 'Failed to update username',
-                description: 'Please try again later',
-            }) as ToastId
-        } finally {
-            fetchUser()
-        }
-    }
     const updateBridgeCustomerData = async (customer: GetUserLinksResponse) => {
         if (!user) return
 
@@ -148,50 +86,6 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
         }
     }
 
-    const submitProfilePhoto = async (file: File) => {
-        if (!user) return
-
-        try {
-            if (toastIdRef.current) {
-                toast.close(toastIdRef.current)
-            }
-            toastIdRef.current = toast({
-                status: 'loading',
-                title: 'Updating profile photo...',
-            }) as ToastId
-            const formData = new FormData()
-            formData.append('file', file)
-
-            const response = await fetchWithSentry('/api/peanut/user/submit-profile-photo', {
-                method: 'POST',
-                headers: {
-                    Authorization: `Bearer your-auth-token`,
-                    'api-key': 'your-api-key',
-                },
-                body: formData,
-            })
-
-            if (response.ok) {
-                fetchUser()
-            } else {
-                throw new Error(response.statusText)
-            }
-            toast.close(toastIdRef.current)
-            toastIdRef.current = toast({
-                status: 'success',
-                title: 'Profile photo updated successfully',
-            }) as ToastId
-        } catch (error) {
-            console.error('Error submitting profile photo', error)
-            toast.close(toastIdRef.current ?? '')
-            toastIdRef.current = toast({
-                status: 'error',
-                title: 'Failed to update profile photo',
-                description: 'Please try again later',
-            }) as ToastId
-        }
-    }
-
     const addBYOW = async () => {
         // we open the web3modal, so the user can disconnect the previous wallet,
         // connect a new wallet and allow the useEffect(..., [wagmiAddress]) in walletContext take over
@@ -263,28 +157,14 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
                 dispatch(setupActions.resetSetup())
                 router.replace('/setup')
 
-                toast({
-                    status: 'success',
-                    title: 'Logged out successfully',
-                    duration: 3000,
-                })
+                toast.success('Logged out successfully')
             } else {
                 console.error('Failed to log out user')
-                toast({
-                    status: 'error',
-                    title: 'Failed to log out',
-                    description: 'Please try again',
-                    duration: 5000,
-                })
+                toast.error('Failed to log out')
             }
         } catch (error) {
             console.error('Error logging out user', error)
-            toast({
-                status: 'error',
-                title: 'Error logging out',
-                description: 'Please try again',
-                duration: 5000,
-            })
+            toast.error('Error logging out')
         } finally {
             setIsLoggingOut(false)
         }
@@ -300,8 +180,6 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
                 username: user?.user?.username ?? undefined,
                 updateBridgeCustomerData,
                 fetchUser: legacy_fetchUser,
-                updateUserName,
-                submitProfilePhoto,
                 addBYOW,
                 addAccount,
                 isFetchingUser,


Reviews:
user: login: coderabbitai[bot]
body: **Actionable comments posted: 0**

<details>
<summary>🧹 Nitpick comments (3)</summary><blockquote>

<details>
<summary>src/components/AddFunds/index.tsx (1)</summary><blockquote>

`214-214`: **Consider handling potential undefined username.**

The new deposit link uses the centralized BASE_URL which is good, but there's no fallback if `user?.user?.username` is undefined.

```diff
-const depositLink = `${BASE_URL}/pay/${user?.user?.username}`
+const depositLink = user?.user?.username ? `${BASE_URL}/pay/${user.user.username}` : BASE_URL
```

</blockquote></details>
<details>
<summary>src/app/(mobile-ui)/home/page.tsx (1)</summary><blockquote>

`52-62`: **Good implementation of automatic peanut-wallet account creation.**

This useEffect addresses the issue of users not having properly created peanut-wallet accounts. The dependencies array is correctly set to [user, address] to ensure the code runs when either changes.

Consider adding error handling to the account creation process:

```diff
useEffect(() => {
    // We have some users that didn't have the peanut wallet created
    // correctly, so we need to create it
    if (address && user && !user.accounts.some((a) => a.account_type === 'peanut-wallet')) {
+       try {
            addAccount({
                accountIdentifier: address,
                accountType: 'peanut-wallet',
                userId: user.user.userId,
            })
+       } catch (error) {
+           console.error('Failed to create peanut wallet account:', error)
+       }
    }
}, [user, address])
```

</blockquote></details>
<details>
<summary>src/context/authContext.tsx (1)</summary><blockquote>

`95-134`: **Provide user feedback for the “Add account” flow**

`addAccount` performs a network request but gives no visual cue on success or failure (except for thrown errors).  
Consider adding optimistic UI or toast notifications similar to the logout flow so users know their new account was added.

```diff
+ try {
        const response = await fetchWithSentry('/api/peanut/user/add-account', { /* … */ })
        …
-        fetchUser()
+        fetchUser()
+        toast.success?.('Account added')
+ } catch (e) {
+        toast.error?.(e.message ?? 'Could not add account')
+        throw e
+ }
```

</blockquote></details>

</blockquote></details>

<details>
<summary>📜 Review details</summary>

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

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 237b37f9489e3855911888166bdc3b39cf29649a and 35d903b27a3eddf276152dbe1548b3382c1cebe2.

</details>

<details>
<summary>📒 Files selected for processing (5)</summary>

* `src/app/(mobile-ui)/home/page.tsx` (3 hunks)
* `src/app/(mobile-ui)/layout.tsx` (1 hunks)
* `src/components/AddFunds/index.tsx` (2 hunks)
* `src/constants/general.consts.ts` (1 hunks)
* `src/context/authContext.tsx` (3 hunks)

</details>

<details>
<summary>🧰 Additional context used</summary>

<details>
<summary>🧬 Code Graph Analysis (3)</summary>

<details>
<summary>src/components/AddFunds/index.tsx (1)</summary><blockquote>

<details>
<summary>src/constants/general.consts.ts (1)</summary>

* `BASE_URL` (36-36)

</details>

</blockquote></details>
<details>
<summary>src/app/(mobile-ui)/home/page.tsx (2)</summary><blockquote>

<details>
<summary>src/hooks/wallet/useWallet.ts (1)</summary>

* `useWallet` (20-82)

</details>
<details>
<summary>src/context/authContext.tsx (1)</summary>

* `useAuth` (195-201)

</details>

</blockquote></details>
<details>
<summary>src/context/authContext.tsx (1)</summary><blockquote>

<details>
<summary>src/components/0_Bruddle/Toast.tsx (1)</summary>

* `useToast` (111-117)

</details>

</blockquote></details>

</details>

</details>

<details>
<summary>⏰ Context from checks skipped due to timeout of 90000ms (1)</summary>

* GitHub Check: Deploy-Preview

</details>

<details>
<summary>🔇 Additional comments (7)</summary><blockquote>

<details>
<summary>src/constants/general.consts.ts (1)</summary>

`36-36`: **Good addition of a centralized BASE_URL constant.**

The addition of this configurable constant is a clean approach for centralizing URL construction across the application. It appropriately uses the environment variable with a sensible default fallback.

</details>
<details>
<summary>src/components/AddFunds/index.tsx (1)</summary>

`13-13`: **Good import of the BASE_URL constant.**

Properly importing the centralized constant from constants file.

</details>
<details>
<summary>src/app/(mobile-ui)/layout.tsx (1)</summary>

`19-19`: **Good extension of public path regex to support /pay/ URLs.**

The regex now correctly captures the new URL pattern for payment links, aligning with the updated deposit link format being used in the AddFunds component.

</details>
<details>
<summary>src/app/(mobile-ui)/home/page.tsx (2)</summary>

`21-21`: **Good addition of useEffect import.**

Properly importing the required hook for the new account creation functionality.

---

`25-25`: **Good destructuring of required dependencies.**

Correctly extracting the wallet address and the addAccount function needed for the automatic account creation.



Also applies to: 34-34

</details>
<details>
<summary>src/context/authContext.tsx (2)</summary>

`9-10`: **Wrap `AuthProvider` with `ToastProvider` to avoid runtime crashes**

`useToast` now comes from your custom Bruddle implementation which will `throw` if it is used outside of a `ToastProvider` (see `Toast.tsx`, lines 111-117).  
Double-check that every app entry-point where `AuthProvider` is rendered is **already** nested inside `ToastProvider`; otherwise navigation to any route that mounts `AuthProvider` first will raise an exception and take the whole app down.

Example (App Router – `layout.tsx`):

```diff
-<AuthProvider>
-  {children}
-</AuthProvider>
+<ToastProvider>
+  <AuthProvider>
+    {children}
+  </AuthProvider>
+</ToastProvider>
```
  


Also applies to: 49-50

---

`160-168`: **Verify that the custom toast context exposes `success` / `error` helpers**

The new calls

```typescript
toast.success('Logged out successfully')
toast.error('Failed to log out')
toast.error('Error logging out')
```

assume the context object has `success` and `error` methods (previously Chakra’s `useToast` returned a *callable* function).  
If the API surface is different (e.g. `toast({ status: 'success', message: … })`), this will result in a runtime `TypeError`.

Suggestion:

```diff
- toast.success('Logged out successfully')
+ toast?.success?.('Logged out successfully')
```

or, better, adapt to the exact API exported by the `ToastProvider`.

Please run a quick type-check / unit test to confirm these helpers exist.

</details>

</blockquote></details>

</details>

<!-- This is an auto-generated comment by CodeRabbit for review status -->
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T17:43:29Z
user: login: Hugo0
body: one blocker comment pls check; apart from that lgtm, approved
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T17:59:18Z
user: login: Hugo0
body: Two issues:


**(actually not a bug)**
squid route failing handling:
![image](https://github.com/user-attachments/assets/8f3ac2b0-478a-46b6-bd89-64047c489822)

bug: this userid (likely my address is in db relatedto user) 0xB92FCCCc63893856Da2a445d861f0942788D6479
https://peanut.me/claim?c=42161&v=v4.3&i=3761&t=ui#p=ee08BYdmYhcpYzvZ
state: CHANGES_REQUESTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T18:19:07Z
user: login: jjramirezn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T18:22:24Z
user: login: jjramirezn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T18:27:44Z
user: login: jjramirezn
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T18:28:01Z
user: login: Hugo0
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T18:39:17Z

Review comments:
diff_hunk: @@ -49,6 +49,18 @@ export default function Home() {
 
     const isLoading = isFetchingUser && !username
 
+    useEffect(() => {
+        // We have some users that didn't have the peanut wallet created
+        // correctly, so we need to create it
+        if (address && user && !user.accounts.some((a) => a.account_type === 'peanut-wallet')) {
+            addAccount({
+                accountIdentifier: address,
+                accountType: 'peanut-wallet',
+                userId: user.user.userId,
+            })
+        }
+    }, [user, address])
+
path: src/app/(mobile-ui)/home/page.tsx
user: login: Hugo0
body: Q: but they alrdy have a zerodev account? 

Also, this fix seems nice, because even though it doesnt fix the root cause of /setup not creating their account in db (maybe api call failed? idk) it does fix it in /home
created_at: 2025-05-12T17:52:46Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,7 +16,7 @@ import { useEffect, useMemo, useState } from 'react'
 import { twMerge } from 'tailwind-merge'
 import '../../styles/globals.css'
 
-const publicPathRegex = /^\/(request\/pay|claim)/
+const publicPathRegex = /^\/(request\/pay|claim|pay\/.+$)/
 
 const Layout = ({ children }: { children: React.ReactNode }) => {
     const pathName = usePathname()
path: src/app/(mobile-ui)/layout.tsx
user: login: Hugo0
body: nit, potential blocker (but unrelated to PR): we have this code below:
```
    const isHome = pathName === '/home'
    const isHistory = pathName === '/history'
    const isWallet = pathName === '/wallet'
    const isSupport = pathName === '/support'
    const alignStart = isHome || isHistory || isWallet || isSupport
    ```
    
    and then we conditionally render home based on that. But this is wrong (and potentially also the source for peanut.me/jobs not working). we should integrate this list with the PEANUT RESERVED ROUTES list that we created when we decided on username namespace! And have special handling for those routes
created_at: 2025-05-12T17:56:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -211,7 +211,7 @@ const UsingExchange = () => {
 
 const UsingRequestLink = () => {
     const { user } = useUserStore()
-    const depositLink = `https://peanut.me/${user?.user?.username}?action=deposit`
+    const depositLink = `${BASE_URL}/pay/${user?.user?.username}`
path: src/components/AddFunds/index.tsx
user: login: Hugo0
body: finally :pray: 
created_at: 2025-05-12T17:56:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -211,7 +211,7 @@ const UsingExchange = () => {
 
 const UsingRequestLink = () => {
     const { user } = useUserStore()
-    const depositLink = `https://peanut.me/${user?.user?.username}?action=deposit`
+    const depositLink = `${BASE_URL}/pay/${user?.user?.username}`
path: src/components/AddFunds/index.tsx
user: login: Hugo0
body: tbh i'd CTRL+F for any https://peanut.me or https://staging.peanut.me and fix
created_at: 2025-05-12T17:56:59Z
author_association: CONTRIBUTOR
diff_hunk: @@ -32,6 +32,8 @@ export const PEANUT_API_URL = (
     process.env.NEXT_PUBLIC_PEANUT_API_URL ||
     'https://api.peanut.to'
 ).replace(/\/$/, '') // remove any accidental trailing slash
+
+export const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'
path: src/constants/general.consts.ts
user: login: Hugo0
body: didn't we have this alrdy?? I'm like 95% sure we had BASE_URL defined alrdy. pls check that we're not redefining or duplcicating here (maybe it was called NEXT_PUBLIC_BASE_URL)
created_at: 2025-05-12T17:57:39Z
author_association: CONTRIBUTOR
diff_hunk: @@ -48,6 +46,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
     const { open: web3modalOpen } = useAppKit()
     const dispatch = useAppDispatch()
     const { user: authUser } = useUserStore()
+    const toast = useToast()
path: src/context/authContext.tsx
user: login: Hugo0
body: HELL YEAH FINALLY THIS WAS BUGGING ME FOREVER

can we remove chakra entirely from deps now?
created_at: 2025-05-12T17:58:04Z
author_association: CONTRIBUTOR
diff_hunk: @@ -56,69 +55,8 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
         return fetchedUser ?? null
     }
 
-    const toast = useToast({
-        position: 'bottom-right',
-        duration: 5000,
-        isClosable: true,
-        icon: '🥜',
-    })
-
-    const toastIdRef = useRef<ToastId | undefined>(undefined)
     const [isLoggingOut, setIsLoggingOut] = useState(false)
 
-    const updateUserName = async (username: string) => {
path: src/context/authContext.tsx
user: login: Hugo0
body: deleting code <3
created_at: 2025-05-12T17:58:27Z
author_association: CONTRIBUTOR
diff_hunk: @@ -148,50 +86,6 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
         }
     }
 
-    const submitProfilePhoto = async (file: File) => {
path: src/context/authContext.tsx
user: login: Hugo0
body: mhmmmmmm we might wanna keep this code commented, for future updating of pfp. will save a tiny bit of time
created_at: 2025-05-12T17:58:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -16,7 +16,7 @@ import { useEffect, useMemo, useState } from 'react'
 import { twMerge } from 'tailwind-merge'
 import '../../styles/globals.css'
 
-const publicPathRegex = /^\/(request\/pay|claim)/
+const publicPathRegex = /^\/(request\/pay|claim|pay\/.+$)/
 
 const Layout = ({ children }: { children: React.ReactNode }) => {
     const pathName = usePathname()
path: src/app/(mobile-ui)/layout.tsx
user: login: Hugo0
body: @kushagrasarathe 
created_at: 2025-05-12T18:09:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -49,6 +49,18 @@ export default function Home() {
 
     const isLoading = isFetchingUser && !username
 
+    useEffect(() => {
+        // We have some users that didn't have the peanut wallet created
+        // correctly, so we need to create it
+        if (address && user && !user.accounts.some((a) => a.account_type === 'peanut-wallet')) {
+            addAccount({
+                accountIdentifier: address,
+                accountType: 'peanut-wallet',
+                userId: user.user.userId,
+            })
+        }
+    }, [user, address])
+
path: src/app/(mobile-ui)/home/page.tsx
user: login: jjramirezn
body: Yes, the issue here is that add-account failed for some users after they alreaddy had the passkey (and the kernelclient) created. We were not recovering from that and their users were in a broken state
created_at: 2025-05-12T18:22:24Z
author_association: CONTRIBUTOR
diff_hunk: @@ -32,6 +32,8 @@ export const PEANUT_API_URL = (
     process.env.NEXT_PUBLIC_PEANUT_API_URL ||
     'https://api.peanut.to'
 ).replace(/\/$/, '') // remove any accidental trailing slash
+
+export const BASE_URL = process.env.NEXT_PUBLIC_BASE_URL || 'https://peanut.me'
path: src/constants/general.consts.ts
user: login: jjramirezn
body: We had it only recently and in staging. Same file
created_at: 2025-05-12T18:27:44Z
author_association: CONTRIBUTOR
diff_hunk: @@ -48,6 +46,7 @@ export const AuthProvider = ({ children }: { children: ReactNode }) => {
     const { open: web3modalOpen } = useAppKit()
     const dispatch = useAppDispatch()
     const { user: authUser } = useUserStore()
+    const toast = useToast()
path: src/context/authContext.tsx
user: login: jjramirezn
body: There are still some parts using chakra, did not attack right now
created_at: 2025-05-12T18:28:01Z
author_association: CONTRIBUTOR

PR comments:
user: login: notion-workspace[bot]
created_at: 2025-05-12T17:40:48Z
body: <a href="https://www.notion.so/Bug-Link-to-deposit-from-self-custodial-wallet-redirects-to-profile-1f1838117579800b825ad91d46889512?pvs=8&n=github_linkback">🪲 Bug: Link to deposit from self custodial wallet redirects to profile</a>
author_association: NONE
user: login: vercel[bot]
created_at: 2025-05-12T17:40:48Z
body: [vc]: #g9WUBDIDXEe/FhqsNqk6bd8j6J15LzgTOn/Dm8/6P6Q=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJwZWFudXQtdWkiLCJyb290RGlyZWN0b3J5IjpudWxsLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoicGVhbnV0LXVpLWdpdC1maXgtcG9zdC1wcm9kLXJlbGVhc2Utc3F1aXJyZWxsYWJzLnZlcmNlbC5hcHAifSwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3NxdWlycmVsbGFicy9wZWFudXQtdWkvODE5MzZzRG1TU0NYRlluNUxFZktqbmhSSHE5eiIsInByZXZpZXdVcmwiOiJwZWFudXQtdWktZ2l0LWZpeC1wb3N0LXByb2QtcmVsZWFzZS1zcXVpcnJlbGxhYnMudmVyY2VsLmFwcCIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCJ9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **peanut-ui** | ✅ Ready ([Inspect](https://vercel.com/squirrellabs/peanut-ui/81936sDmSSCXFYn5LEfKjnhRHq9z)) | [Visit Preview](https://peanut-ui-git-fix-post-prod-release-squirrellabs.vercel.app) | 💬 [**Add feedback**](https://vercel.live/open-feedback/peanut-ui-git-fix-post-prod-release-squirrellabs.vercel.app?via=pr-comment-feedback-link) | May 12, 2025 6:39pm |


author_association: NONE
user: login: notion-workspace[bot]
created_at: 2025-05-12T17:40:49Z
body: <a href="https://www.notion.so/User-can-create-a-peanut-user-with-peanut-wallet-creation-failing-1c083811757980e69aeecc8db56362e7?pvs=8&n=github_linkback">User can create a peanut user with peanut wallet creation failing</a>
author_association: NONE
user: login: coderabbitai[bot]
created_at: 2025-05-12T17:40:50Z
body: <!-- This is an auto-generated comment: summarize by coderabbit.ai -->
<!-- This is an auto-generated comment: failure by coderabbit.ai -->

> [!CAUTION]
> ## Review failed
> 
> The pull request is closed.

<!-- end of auto-generated comment: failure by coderabbit.ai -->
<!-- walkthrough_start -->

## Walkthrough

The changes introduce automatic creation of a "peanut-wallet" account for users in the Home component, expand public path recognition in the mobile UI layout, update deposit link construction to use a configurable base URL, add a `BASE_URL` constant, refactor the authentication context to remove Chakra UI toasts and obsolete profile update methods, and centralize base URL usage across multiple modules by importing the new `BASE_URL` constant.

## Changes

| File(s)                                                                                              | Change Summary                                                                                                                                                                                                                                 |
|----------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| src/app/(mobile-ui)/home/page.tsx                                                                  | Added a `useEffect` to auto-create a "peanut-wallet" account for users if missing, using `address` from `useWallet` and `addAccount` from `useAuth`.                                                                                           |
| src/app/(mobile-ui)/layout.tsx                                                                     | Updated `publicPathRegex` to recognize `/pay/` paths as public, affecting UI rendering logic for public routes.                                                                                                                             |
| src/components/AddFunds/index.tsx                                                                  | Changed deposit link construction to use a new `BASE_URL` constant instead of a hardcoded domain.                                                                                                                                             |
| src/constants/general.consts.ts                                                                    | Introduced a new `BASE_URL` constant, using an environment variable or defaulting to `'https://peanut.me'`.                                                                                                                                   |
| src/context/authContext.tsx                                                                        | Replaced Chakra UI toasts with a custom toast hook, removed `updateUserName` and `submitProfilePhoto` methods from the context, and simplified logout toast notifications.                                                                   |
| src/app/(mobile-ui)/claim/page.tsx, src/app/(mobile-ui)/link-account/page.tsx, src/app/(mobile-ui)/profile/page.tsx, src/app/(mobile-ui)/refund/page.tsx, src/app/[...recipient]/layout.tsx, src/app/metadata.ts, src/app/robots.ts | Replaced hardcoded or environment variable-based base URL strings with the imported `BASE_URL` constant from the centralized constants module for metadata, preview URLs, and sitemap generation.                                            |
| src/components/Claim/Claim.tsx                                                                     | Changed claim sender userId access to use optional chaining (`sendLink.sender?.userId`) to prevent runtime errors if sender is undefined.                                                                                                    |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant HomeComponent
    participant useWallet
    participant useAuth

    User->>HomeComponent: Loads Home page
    HomeComponent->>useWallet: Get wallet address
    HomeComponent->>useAuth: Get user info
    HomeComponent->>HomeComponent: useEffect checks accounts
    alt "peanut-wallet" account missing
        HomeComponent->>useAuth: addAccount(address, "peanut-wallet", userId)
    end
```

## Poem

> In the warren of code, a wallet appears,  
> Auto-created for users—no more fears!  
> Paths grow public, links get a new base,  
> Toasts now custom, with a streamlined face.  
> The rabbits rejoice, accounts set just right—  
> Hopping through updates, coding delight!  
> 🐇✨

<!-- walkthrough_end -->
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- announcements_start -->

> [!TIP]
> <details>
> <summary>⚡️ Faster reviews with caching</summary>
> 
> - CodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure `Review - Disable Cache` at either the organization or repository level. If you prefer to disable all data retention across your organization, simply turn off the `Data Retention` setting under your Organization Settings.
> 
> Enjoy the performance boost—your workflow just got faster.
> 
> </details>

<!-- announcements_end -->

---

<details>
<summary>📜 Recent review details</summary>

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

<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between 35d903b27a3eddf276152dbe1548b3382c1cebe2 and 8fe9773b37b29314a5da16ef6a37935d80139292.

</details>

<details>
<summary>📒 Files selected for processing (8)</summary>

* `src/app/(mobile-ui)/claim/page.tsx` (2 hunks)
* `src/app/(mobile-ui)/link-account/page.tsx` (1 hunks)
* `src/app/(mobile-ui)/profile/page.tsx` (1 hunks)
* `src/app/(mobile-ui)/refund/page.tsx` (1 hunks)
* `src/app/[...recipient]/layout.tsx` (2 hunks)
* `src/app/metadata.ts` (2 hunks)
* `src/app/robots.ts` (2 hunks)
* `src/components/Claim/Claim.tsx` (1 hunks)

</details>

</details>
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---

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.

<details>
<summary>❤️ Share</summary>

- [X](https://twitter.com/intent/tweet?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A&url=https%3A//coderabbit.ai)
- [Mastodon](https://mastodon.social/share?text=I%20just%20used%20%40coderabbitai%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20the%20proprietary%20code.%20Check%20it%20out%3A%20https%3A%2F%2Fcoderabbit.ai)
- [Reddit](https://www.reddit.com/submit?title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&text=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code.%20Check%20it%20out%3A%20https%3A//coderabbit.ai)
- [LinkedIn](https://www.linkedin.com/sharing/share-offsite/?url=https%3A%2F%2Fcoderabbit.ai&mini=true&title=Great%20tool%20for%20code%20review%20-%20CodeRabbit&summary=I%20just%20used%20CodeRabbit%20for%20my%20code%20review%2C%20and%20it%27s%20fantastic%21%20It%27s%20free%20for%20OSS%20and%20offers%20a%20free%20trial%20for%20proprietary%20code)

</details>

<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=peanutprotocol/peanut-ui&utm_content=844):

- 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.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

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](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

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

### CodeRabbit Configuration File (`.coderabbit.yaml`)

- You can programmatically configure CodeRabbit by adding a `.coderabbit.yaml` file to the root of your repository.
- Please see the [configuration documentation](https://docs.coderabbit.ai/guides/configure-coderabbit) 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](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->
author_association: CONTRIBUTOR