[TASK-13586] fix: don't try to create account twice on setup#1160
[TASK-13586] fix: don't try to create account twice on setup#1160jjramirezn merged 1 commit intopeanut-wallet-devfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughIntroduces device-type awareness via a hook in Home, replaces userAgent iOS checks with DeviceType-based logic, and updates effect dependencies. Adds isFetchingUser guards in SetupPasskey and Home to prevent duplicate actions during user fetch, adjusts button states, and extends effect dependency arrays accordingly. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Suggested reviewers
✨ Finishing Touches
🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
src/components/Setup/Views/SetupPasskey.tsx (1)
26-62: Fix: loading can get stuck and no redirect when account already existsIf the account already exists, the effect returns early so setLoading(false) never runs and no redirect occurs after a successful register. Clear loading and navigate when the wallet already exists.
useEffect(() => { - // Dont try to double add the account - if (isFetchingUser || user?.accounts.some((a) => a.type === AccountType.PEANUT_WALLET)) return + // Don't try to double-add the account + if (isFetchingUser) return + + // Already has Peanut Wallet: clear loading and redirect + if (user?.accounts.some((a) => a.type === AccountType.PEANUT_WALLET)) { + dispatch(setupActions.setLoading(false)) + const localStorageRedirect = getFromLocalStorage('redirect') + if (localStorageRedirect) { + const matchedAction = POST_SIGNUP_ACTIONS.find((action) => + action.pathPattern.test(localStorageRedirect) + ) + if (matchedAction) { + router.push('/home') + } else { + localStorage.removeItem('redirect') + router.push(localStorageRedirect) + } + } else { + router.push('/home') + } + return + } if (address && user) { addAccount({ accountIdentifier: address, accountType: WalletProviderType.PEANUT, userId: user?.user.userId as string, telegramHandle: telegramHandle.length > 0 ? telegramHandle : undefined, }) .then(() => { const localStorageRedirect = getFromLocalStorage('redirect') // redirect based on post signup action config if (localStorageRedirect) { const matchedAction = POST_SIGNUP_ACTIONS.find((action) => action.pathPattern.test(localStorageRedirect) ) if (matchedAction) { router.push('/home') } else { localStorage.removeItem('redirect') router.push(localStorageRedirect) } } else { router.push('/home') } }) .catch((e) => { Sentry.captureException(e) console.error('Error adding account', e) setError('Error adding account') }) .finally(() => { dispatch(setupActions.setLoading(false)) }) } }, [address, user, isFetchingUser])src/app/(mobile-ui)/home/page.tsx (1)
98-103: Align accountType and add error handlingUse the same enum as SetupPasskey and handle rejection to avoid unhandled promise rejections.
- addAccount({ - accountIdentifier: address, - accountType: 'peanut-wallet', - userId: user.user.userId, - }) + addAccount({ + accountIdentifier: address, + accountType: WalletProviderType.PEANUT, + userId: user.user.userId, + }).catch((e) => { + Sentry.captureException(e) + console.error('Error adding account in Home()', e) + })Additional diff (imports at top):
- import { AccountType } from '@/interfaces' + import { AccountType, WalletProviderType } from '@/interfaces' + import * as Sentry from '@sentry/nextjs'
🧹 Nitpick comments (2)
src/components/Setup/Views/SetupPasskey.tsx (1)
21-22: Avoid double useAuth() callsDestructure all needed fields from a single useAuth() call to prevent redundant subscriptions.
- const { user, isFetchingUser } = useAuth() - const { addAccount } = useAuth() + const { user, isFetchingUser, addAccount } = useAuth()src/app/(mobile-ui)/home/page.tsx (1)
116-136: Future-proof useDeviceType for SSR safety (hook change, not in this file)useGetDeviceType currently reads navigator.userAgent outside an effect. It’s fine here in a client page, but the hook itself can break if reused in a Server Component. Move UA detection inside useEffect and guard navigator.
--- a/src/hooks/useGetDeviceType.ts +++ b/src/hooks/useGetDeviceType.ts @@ export const useDeviceType = () => { const [deviceType, setDeviceType] = useState<DeviceType | null>(null) - - const isIos = /iPad|iPhone|iPod/.test(navigator.userAgent) - const isAndroid = /android/i.test(navigator.userAgent) - - // check if the user is on ios or android - useEffect(() => { - if (isIos) { - setDeviceType(DeviceType.IOS) - } else if (isAndroid) { - setDeviceType(DeviceType.ANDROID) - } else { - setDeviceType(DeviceType.WEB) - } - }, []) + useEffect(() => { + if (typeof navigator === 'undefined') { + setDeviceType(DeviceType.WEB) + return + } + const ua = navigator.userAgent || '' + const isIos = /iPad|iPhone|iPod/.test(ua) + const isAndroid = /android/i.test(ua) + if (isIos) setDeviceType(DeviceType.IOS) + else if (isAndroid) setDeviceType(DeviceType.ANDROID) + else setDeviceType(DeviceType.WEB) + }, []) return { deviceType } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
📒 Files selected for processing (2)
src/app/(mobile-ui)/home/page.tsx(6 hunks)src/components/Setup/Views/SetupPasskey.tsx(3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-20T09:08:19.266Z
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#1112
File: src/components/Claim/Link/views/BankFlowManager.view.tsx:336-343
Timestamp: 2025-08-20T09:08:19.266Z
Learning: In the KYC flow implementation, `setJustCompletedKyc` must be called after `await fetchUser()` in the `handleKycSuccess` callback. Setting `justCompletedKyc` before fetching the user would cause a re-fetching loop because `handleKycSuccess` is set in a useEffect inside the KYC hook, which would cause the UI flow to get stuck in one view.
Applied to files:
src/app/(mobile-ui)/home/page.tsx
📚 Learning: 2024-12-02T17:19:18.532Z
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/components/Request/Create/Views/Initial.view.tsx:151-156
Timestamp: 2024-12-02T17:19:18.532Z
Learning: In the `InitialView` component at `src/components/Request/Create/Views/Initial.view.tsx`, when setting the default chain and token in the `useEffect` triggered by `isPeanutWallet`, it's acceptable to omit the setters from the dependency array and not include additional error handling for invalid defaults.
Applied to files:
src/components/Setup/Views/SetupPasskey.tsx
🧬 Code graph analysis (2)
src/app/(mobile-ui)/home/page.tsx (2)
src/hooks/useGetDeviceType.ts (1)
useDeviceType(14-32)src/utils/general.utils.ts (1)
isIOS(1270-1275)
src/components/Setup/Views/SetupPasskey.tsx (2)
src/context/authContext.tsx (1)
useAuth(182-188)src/components/0_Bruddle/Button.tsx (1)
Button(76-267)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Deploy-Preview
🔇 Additional comments (5)
src/components/Setup/Views/SetupPasskey.tsx (2)
69-71: LGTM: button state includes isFetchingUserDisabling and showing loading while the user is fetching prevents duplicate actions.
30-35: Ignore accountType consistency concern
WalletProviderType.PEANUT resolves to the string 'peanut-wallet', matching the literal used in Home(); no changes required.Likely an incorrect or invalid review comment.
src/app/(mobile-ui)/home/page.tsx (3)
93-105: LGTM: guarded wallet creationEarly return on isFetchingUser avoids premature addAccount and double-creation.
116-136: LGTM: deviceType-based iOS check and depsSwitching to deviceType and adding it to the dependency array is cleaner and avoids UA checks here.
98-103: Guard in-flight addAccount calls
If addAccount isn’t guaranteed idempotent server-side, track and block in-flight requests (e.g. disable while pending) to prevent duplicate API calls on rapid re-renders.
Dont merge if approved, we are in code freeze