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
}
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
- updateUserName: (username: string) => Promise
- submitProfilePhoto: (file: File) => Promise
updateBridgeCustomerData: (customer: GetUserLinksResponse) => Promise
addBYOW: () => Promise
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(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,