Skip to content

[TASK-12124] Prod Release Sprint 95#911

Merged
jjramirezn merged 42 commits intopeanut-walletfrom
peanut-wallet-dev
Jun 13, 2025
Merged

[TASK-12124] Prod Release Sprint 95#911
jjramirezn merged 42 commits intopeanut-walletfrom
peanut-wallet-dev

Conversation

@jjramirezn
Copy link
Contributor

No description provided.

FacuBozzi and others added 30 commits June 4, 2025 17:31
- Add get-origin utility to reliably determine protocol and host
- Update og route and layout to use dynamic origin for image URLs
- Simplify metadata generation by using centralized origin handling
- Update error message for missing site URL to be more descriptive
- Add host header validation to prevent injection attacks
- Improve font loading error handling in OG image generation
- Validate type parameter in OG route
- Update alt text for logo image to be more specific
fix: block direct requests on ens and addresses
Update recipient input validation to reject Peanut usernames for withdrawals and adjust placeholder text accordingly. This change ensures users can only enter valid addresses (banks) or ENS names when withdrawing funds.
add tailwind-colors utility for color management
update GeneralRecipientInput label
iconFillColor prop to AvatarWithBadge and related components
feat: setup flow minor ui changes
@notion-workspace
Copy link

Prod release sprint 95

@vercel
Copy link

vercel bot commented Jun 13, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
peanut-ui (peanut-wallet-staging) ✅ Ready (Inspect) Visit Preview 💬 Add feedback Jun 13, 2025 1:19pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 13, 2025

Walkthrough

This update introduces dynamic Open Graph image generation and metadata for payment links, adds new types and interfaces for payment links, and updates several UI components for improved validation, error handling, and event-specific messaging. It also enhances setup and withdrawal flows, adjusts Tailwind color palettes, and refines redirect and manifest configurations.

Changes

File(s) Change Summary
src/app/api/og/route.tsx, src/components/og/PaymentCardOG.tsx, src/lib/og/build-og-metadata.ts, src/interfaces/interfaces.ts, src/lib/hosting/get-origin.ts, src/app/[...recipient]/layout.tsx Added dynamic Open Graph image API, new PaymentCardOG component, supporting metadata builder, new types/interfaces for payment links, and dynamic origin resolution for metadata/image URLs.
src/components/Global/GeneralRecipientInput/index.tsx, src/components/Withdraw/views/Initial.withdraw.view.tsx Added isWithdrawal prop to input, updated validation to disallow usernames for withdrawals, and updated placeholder/label text.
src/components/Global/ValidatedInput/index.tsx, src/components/Setup/Views/Signup.tsx Added isSetupFlow and isInputChanging props, updated icon rendering and class merging using twMerge, and improved border color logic in setup flow.
src/components/Global/WalletNavigation/index.tsx Replaced fragment wrappers with keyed <div> elements in navigation mapping.
src/components/Claim/Claim.tsx, src/components/TransactionDetails/transactionTransformer.ts Exported REWARD_TOKENS and included reward data in transaction drawer details.
src/components/Claim/Link/Initial.view.tsx Extended chain/token checks to include Pinta wallet, updated related logic and dependencies.
src/components/Global/PeanutActionDetailsCard/index.tsx Updated avatar color logic for withdrawals to usernames and improved token symbol display for "Beer(s)".
src/components/Global/RewardsModal/index.tsx Changed reward asset type, modal visibility logic, and event-specific content/messages.
src/components/Global/Icons/check-circle.tsx Changed SVG fill from black to currentColor for theming.
src/components/Global/Modal/index.tsx Improved modal focus management using refs and default focus logic.
src/components/Request/direct-request/views/Initial.direct.request.view.tsx Added explicit loading and validation error states, improved user fetch handling and error display.
src/components/Setup/Views/InstallPWA.tsx Refactored PWA installation state detection, improved error handling and prompt invocation.
src/components/Setup/Views/SetupPasskey.tsx Enhanced passkey registration error handling and UI, added documentation link.
src/components/Setup/Setup.consts.tsx, src/components/Setup/components/SetupWrapper.tsx Updated flex alignment and height units for setup steps/layouts.
src/app/manifest.ts Made manifest's related app URL dynamic using environment variable.
redirects.json Changed "/pints" and "/events" redirects from external to internal non-permanent paths.
tailwind.config.js Added new color shade to secondary palette.
package.json Added @simplewebauthn/browser dependency.

Possibly related PRs

  • peanutprotocol/peanut-ui#901: Adds the isWithdrawal prop and disables username support in GeneralRecipientInput, directly overlapping with withdrawal validation changes.
  • peanutprotocol/peanut-ui#903: Also adds isSetupFlow and isInputChanging props to ValidatedInput, updating icon logic—matching the same component changes here.
  • peanutprotocol/peanut-ui#897: Modifies dynamic Open Graph image generation and payment link metadata, overlapping files and logic with this PR.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate Unit Tests
  • Create PR with Unit Tests
  • Commit Unit Tests in branch peanut-wallet-dev
  • Post Copyable Unit Tests in Comment

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • 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 explain this code block.
    • @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 explain its main purpose.
    • @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 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 for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai auto-generate unit tests to generate unit tests for 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 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 for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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: 12

🔭 Outside diff range comments (5)
src/components/Withdraw/views/Initial.withdraw.view.tsx (1)

83-90: ⚠️ Potential issue

Inconsistent recipient type vs. new validation logic

PeanutActionDetailsCard is still hard-coded with recipientType="USERNAME" (line 85) even though the surrounding UI now forbids usernames by:

  1. Updating the placeholder to “Enter an address or ENS”.
  2. Passing the new isWithdrawal flag to GeneralRecipientInput, which rejects usernames.

This creates a logical mismatch – the card says “USERNAME” while the form rejects them. Down-stream analytics/helpers that rely on recipientType may also be mis-informed.

-    recipientType="USERNAME"
+    recipientType="ADDRESS"

(or a more precise enum value used elsewhere).

Please align the constant (and any follow-on business logic) with the new withdrawal-only address/ENS rule.

Also applies to: 94-108

src/components/Global/PeanutActionDetailsCard/index.tsx (1)

70-75: 🛠️ Refactor suggestion

useCallback missing deps → stale closures
getAvatarIcon references viewType, recipientType, and transactionType but the dependency array is empty. On rerenders with different props (e.g. after optimistic UI update) the memoised fn returns an outdated icon.

-    }, [])
+    }, [transactionType, recipientType, viewType])
src/components/Global/GeneralRecipientInput/index.tsx (1)

45-85: ⚠️ Potential issue

isWithdrawal missing from useCallback deps – validation may use stale flag
If isWithdrawal prop changes after mount, checkAddress will still reference the old value, potentially allowing/disallowing usernames incorrectly.

-    const checkAddress = useCallback(async (recipient: string): Promise<boolean> => {
+    const checkAddress = useCallback(async (recipient: string): Promise<boolean> => {
         ...
-    }, [])
+    }, [isWithdrawal])
src/components/Request/direct-request/views/Initial.direct.request.view.tsx (1)

86-92: ⚠️ Potential issue

user! non-null assertion may throw

user can be null when this callback runs (e.g. race condition after username change).
Guard before dereferencing to prevent a runtime crash.

-if (!user) {
-  setErrorState({ showError: true, errorMessage: 'Recipient not loaded yet' })
-  return
-}
-await usersApi.requestByUsername({ username: user.username, … })
+if (!user) {
+  setErrorState({ showError: true, errorMessage: 'Recipient not loaded yet' })
+  return
+}
+await usersApi.requestByUsername({ username: user.username, … })
src/components/Global/RewardsModal/index.tsx (1)

159-167: ⚠️ Potential issue

Guard non-null assertions

user! and activeReward! may be undefined if the modal opens before data arrives.
Add early returns or disable the button until both are defined to avoid crashes.

if (!user || !activeReward) return null
🧹 Nitpick comments (22)
src/components/Setup/components/SetupWrapper.tsx (1)

39-41: Use dynamic viewport height units
Switched container height from vh to dvh for improved mobile browser compatibility. Consider adding a fallback to vh or a CSS variable for browsers that don’t support dvh.

src/components/Global/WalletNavigation/index.tsx (1)

34-55: Avoid unnecessary extra DOM wrapper – keep the key on a fragment instead

React has allowed key on <> fragments since 16.2 (<></> can be replaced with <React.Fragment key="">).
Switching to a <div> introduces an extra node that:

  1. May break flex/grid styling of parent containers.
  2. Slightly bloats the DOM for every nav item.

Refactor to:

-        {paths.map(({ name, href, icon, size }, index) => (
-            <div key={`${name}-${index}`}>
-                <Link ...>
+        {paths.map(({ name, href, icon, size }) => (
+            <React.Fragment key={name}>
+                <Link ...>

Keeps keys correct without altering layout.

src/components/Setup/Views/SetupPasskey.tsx (1)

61-83: Minor UX polish – clear stale error & always unset loading in finally

Current flow:

  1. Clicking twice after an error retains the previous error message.
  2. dispatch(setLoading(false)) is called in every catch branch, but not after a successful handleRegister, leaving the button in loading state until the separate useEffect fires.

Quick fix:

onClick={async () => {
+    setError(null)       // clear old error
     dispatch(setupActions.setLoading(true))
     try {
         await handleRegister(username)
-    } catch (e) {
+    } catch (e) {
         ...
-        dispatch(setupActions.setLoading(false))
+    } finally {
+        // Always reset local loading in case address never resolves
+        dispatch(setupActions.setLoading(false))
     }
}}
src/components/Withdraw/views/Initial.withdraw.view.tsx (1)

107-108: Explicit boolean prop – readability

Using the prop key alone implies true, but explicitness helps future readers:

-                    isWithdrawal
+                    isWithdrawal={true}

Optional, feel free to ignore.

src/components/Global/Modal/index.tsx (1)

3-4: Ref typing – tighten for better IntelliSense

dialogRef is currently MutableRefObject<null>, which loses type information and disables helpful hints on Dialog methods.

-    let dialogRef = useRef(null)
+    const dialogRef = useRef<HTMLDivElement | null>(null)

No runtime change, but improves static analysis & DX.

Also applies to: 41-48

src/lib/og/build-og-metadata.ts (1)

26-30: Possible double ‘//’ in OG image URL
new URL(${siteUrl}/api/og) produces https://example.com//api/og when siteUrl already ends with /. Browsers tolerate this but CDN-level proxy rules sometimes do not.

-const ogUrl = new URL(`${siteUrl}/api/og`)
+const ogUrl = new URL('/api/og', siteUrl.endsWith('/') ? siteUrl : siteUrl + '/')
src/components/Global/PeanutActionDetailsCard/index.tsx (2)

89-103: Condition now impossible after withdrawal username ban
Username recipients are explicitly blocked in the new withdrawal flow (GeneralRecipientInput). These additional avatar-color branches will never be hit, adding complexity without value.

Consider removing the username-specific WITHDRAW paths or adding a comment explaining why you kept them.


113-115: Pluralisation logic leaks UI-text concerns into a presentational component
Embedding English plural rules (“Beer(s)”) here couples token-symbol semantics to the card. Prefer moving this to an i18n/util helper so UI copy is centralised and translatable.

src/components/Global/GeneralRecipientInput/index.tsx (2)

64-68: User-visible error string is duplicated in multiple files
Hard-coded "Peanut usernames are not supported for withdrawals." appears here and in Initial.withdraw.view.tsx. Extract to a shared constants file to avoid divergence.


133-134: Label now hard-coded to “Wallet address” for all usages
The component is reused outside withdrawals (e.g. direct requests). The previous wording was neutral; now the label is misleading when the recipient can be ENS or IBAN. Consider passing label as a prop instead.

src/components/Global/ValidatedInput/index.tsx (1)

205-213: Icons lack accessible labels
The new success / error icons are purely visual. Without aria-hidden/role="img"/title assistive tech users receive no feedback.

-<Icon size={20} className="text-secondary-2" name="error" />
+<Icon
+  size={20}
+  className="text-secondary-2"
+  name="error"
+  aria-label="invalid input"
/>

Apply similarly for the success icon.

src/app/[...recipient]/layout.tsx (1)

7-29: Dead helper getPreviewUrl() can be safely removed

After the migration to the new /api/og endpoint the helper is no longer referenced anywhere in this file (or in the repo, according to a quick rg scan). Keeping it around adds cognitive noise.

- function getPreviewUrl( … ) {
-
- }
src/components/Setup/Views/InstallPWA.tsx (1)

110-113: Serialising the entire deferredPrompt object may crash the toast

BeforeInstallPromptEvent contains circular references → JSON.stringify() throws.
Log a safe subset instead.

-captureException(error)
-toast.error(JSON.stringify(deferredPrompt))
+captureException(error)
+toast.error('Installation prompt failed – see console for details')
+// optional: console.debug('Prompt:', { platforms: deferredPrompt?.platforms })
src/app/api/og/route.tsx (1)

47-48: Number(searchParams.get('amount')) can yield NaN

When the query param is absent or invalid your OG card breaks (see PaymentCard comment).
Guard the conversion:

-const amount = Number(searchParams.get('amount') ?? 0)
+const amountParam = searchParams.get('amount')
+const amount = amountParam && !isNaN(Number(amountParam)) ? Number(amountParam) : 0
src/components/Request/direct-request/views/Initial.direct.request.view.tsx (5)

38-39: Avoid duplicate context reads

loadingStateContext is consumed twice (lines 38-39 and 76-77).
Reading the same context twice triggers two renders and is unnecessary.

-const { setLoadingState, loadingState } = useContext(loadingStateContext)
-
-const isButtonLoading = useContext(loadingStateContext).isLoading
+const { setLoadingState, loadingState, isLoading: isButtonLoading } =
+  useContext(loadingStateContext)

Also applies to: 76-77


69-73: Redundant double-negation

!!authUser?.user.userId is already truthy/falsy; the cast is noise and flagged by Biome.

-const isIdentityLogicMissing = !!authUser?.user.userId ? !address : !recipient.address
+const isIdentityLogicMissing =
+  authUser?.user.userId ? !address : !recipient.address
🧰 Tools
🪛 Biome (1.9.4)

[error] 72-72: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)


79-83: Generic error message hides real cause

The disabled-button path always throws “Username or amount is missing”, even when the real blocker is a missing wallet/recipient address.
Build the message from the actual failing predicate to help the user correct it.


153-162: Minor readability: optional chaining & early return

-if (response && response.username) {
+if (response?.username) {

Same check in the catch could share an abortController to cancel the request on unmount and avoid setting state on an unmounted component.
Not urgent, but worth considering.

Also applies to: 171-176

🧰 Tools
🪛 Biome (1.9.4)

[error] 158-158: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


301-316: Button state race

disabled={isButtonDisabled || isButtonLoading} and loading={isButtonLoading} is fine, but combining both flags means the button is permanently disabled during the API call even if isButtonDisabled becomes false (e.g. user edits amount). Usually loading implies disabled; you can rely on it and drop the logical-OR.

src/components/Global/RewardsModal/index.tsx (3)

58-60: Single-asset lookup silently ignores other rewards

getActiveReward hard-codes PNT. If the backend later sends USDC-only rewards, the modal will never appear.
If that’s intentional for the event it’s fine; otherwise keep the previous fallback.

-return rewardLinks.find((r) => r.assetCode === REWARD_ASSET_TYPE.PNT)
+return (
+  rewardLinks.find((r) => r.assetCode === REWARD_ASSET_TYPE.PNT) ??
+  rewardLinks.find((r) => r.assetCode === REWARD_ASSET_TYPE.USDC)
+)

118-124: Derive showModal instead of mutating state

showModal can be computed directly from rewardLinks.length && activeReward—keeping it in state adds an extra render path and risks desync.

-const [showModal, setShowModal] = useState(false)
+const showModal = rewardLinks.length > 0 && !!activeReward

Then remove the effect that toggles it.
Simpler and easier to reason about.


76-84: Memoise modal copy

getModalContent() is pure; wrapping it in useMemo prevents re-allocation on every render and clarifies dependencies.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 8cee3aa and 36390e4.

⛔ Files ignored due to path filters (10)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
  • public/arrows/bottom-left-arrow.svg is excluded by !**/*.svg
  • public/arrows/bottom-right-arrow.svg is excluded by !**/*.svg
  • public/arrows/top-left-arrows.svg is excluded by !**/*.svg
  • public/arrows/top-right-arrow.svg is excluded by !**/*.svg
  • public/icons/peanut-icon.svg is excluded by !**/*.svg
  • public/logos/peanut-logo.svg is excluded by !**/*.svg
  • public/scribble.svg is excluded by !**/*.svg
  • src/assets/fonts/montserrat-medium.ttf is excluded by !**/*.ttf
  • src/assets/fonts/montserrat-semibold.ttf is excluded by !**/*.ttf
📒 Files selected for processing (27)
  • package.json (1 hunks)
  • redirects.json (1 hunks)
  • src/app/[...recipient]/layout.tsx (4 hunks)
  • src/app/api/og/route.tsx (1 hunks)
  • src/app/manifest.ts (1 hunks)
  • src/components/Claim/Claim.tsx (3 hunks)
  • src/components/Claim/Link/Initial.view.tsx (6 hunks)
  • src/components/Global/GeneralRecipientInput/index.tsx (5 hunks)
  • src/components/Global/Icons/check-circle.tsx (1 hunks)
  • src/components/Global/Modal/index.tsx (2 hunks)
  • src/components/Global/PeanutActionDetailsCard/index.tsx (3 hunks)
  • src/components/Global/RewardsModal/index.tsx (4 hunks)
  • src/components/Global/ValidatedInput/index.tsx (4 hunks)
  • src/components/Global/WalletNavigation/index.tsx (2 hunks)
  • src/components/Request/direct-request/views/Initial.direct.request.view.tsx (9 hunks)
  • src/components/Setup/Setup.consts.tsx (2 hunks)
  • src/components/Setup/Views/InstallPWA.tsx (5 hunks)
  • src/components/Setup/Views/SetupPasskey.tsx (2 hunks)
  • src/components/Setup/Views/Signup.tsx (3 hunks)
  • src/components/Setup/components/SetupWrapper.tsx (1 hunks)
  • src/components/TransactionDetails/transactionTransformer.ts (1 hunks)
  • src/components/Withdraw/views/Initial.withdraw.view.tsx (2 hunks)
  • src/components/og/PaymentCardOG.tsx (1 hunks)
  • src/interfaces/interfaces.ts (1 hunks)
  • src/lib/hosting/get-origin.ts (1 hunks)
  • src/lib/og/build-og-metadata.ts (1 hunks)
  • tailwind.config.js (1 hunks)
🧰 Additional context used
🧠 Learnings (2)
src/components/Withdraw/views/Initial.withdraw.view.tsx (1)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#873
File: src/components/Withdraw/views/Initial.withdraw.view.tsx:95-95
Timestamp: 2025-05-23T19:26:58.220Z
Learning: The GeneralRecipientInput component supports username validation and resolution through the validateAndResolveRecipient function in src/lib/validation/recipient.ts. The function automatically detects usernames (inputs that don't contain '.' for ENS and don't start with '0x' for addresses), validates them via API HEAD request, fetches user data, and resolves them to Ethereum addresses from the user's PEANUT_WALLET account.
src/components/Global/GeneralRecipientInput/index.tsx (1)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#873
File: src/components/Withdraw/views/Initial.withdraw.view.tsx:95-95
Timestamp: 2025-05-23T19:26:58.220Z
Learning: The GeneralRecipientInput component supports username validation and resolution through the validateAndResolveRecipient function in src/lib/validation/recipient.ts. The function automatically detects usernames (inputs that don't contain '.' for ENS and don't start with '0x' for addresses), validates them via API HEAD request, fetches user data, and resolves them to Ethereum addresses from the user's PEANUT_WALLET account.
🧬 Code Graph Analysis (8)
src/components/Claim/Claim.tsx (1)
src/components/TransactionDetails/transactionTransformer.ts (1)
  • REWARD_TOKENS (18-25)
src/components/Setup/Views/SetupPasskey.tsx (2)
src/components/0_Bruddle/Button.tsx (1)
  • Button (69-130)
src/redux/slices/setup-slice.ts (1)
  • setupActions (50-50)
src/components/og/PaymentCardOG.tsx (1)
src/interfaces/interfaces.ts (1)
  • PaymentLink (293-298)
src/app/[...recipient]/layout.tsx (1)
src/lib/hosting/get-origin.ts (1)
  • getOrigin (3-16)
src/components/Global/PeanutActionDetailsCard/index.tsx (1)
src/constants/zerodev.consts.ts (1)
  • PEANUT_WALLET_TOKEN_SYMBOL (21-21)
src/components/Global/ValidatedInput/index.tsx (1)
src/components/Global/Icons/Icon.tsx (1)
  • Icon (155-164)
src/components/Setup/Views/InstallPWA.tsx (1)
src/context/authContext.tsx (1)
  • useAuth (202-208)
src/components/Global/RewardsModal/index.tsx (2)
src/services/services.types.ts (1)
  • RewardLink (262-269)
src/context/authContext.tsx (1)
  • useAuth (202-208)
🪛 Biome (1.9.4)
src/components/Request/direct-request/views/Initial.direct.request.view.tsx

[error] 72-72: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)


[error] 158-158: Change to an optional chain.

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)


[error] 206-206: Avoid redundant double-negation.

It is not necessary to use double-negation when a value will already be coerced to a boolean.
Unsafe fix: Remove redundant double-negation

(lint/complexity/noExtraBooleanCast)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Deploy-Preview
🔇 Additional comments (15)
redirects.json (2)

39-42: Verify /pints redirect
Destination changed to /setup. Ensure the /setup route is correctly implemented and doesn’t introduce infinite loops or broken flows.


43-47: Verify /events redirect
Destination changed to /setup. Confirm this aligns with the intended event flow and that no legacy consumers expect the previous external URL.

package.json (1)

42-42: Validate new WebAuthn dependency
Added @simplewebauthn/browser@^8.3.7. Confirm that this package provides TypeScript definitions (or add @types/... if needed) and that this version is compatible with the existing setup/passkey implementation.

src/components/Global/Icons/check-circle.tsx (1)

7-7: Inherit current text color
Changing fill="currentColor" is a solid improvement—this lets the icon adapt to its parent’s text color for consistent theming.

src/components/Setup/Setup.consts.tsx (2)

63-63: Center content in signup step
Replaced justify-between with justify-center for the signup screen. This aligns the layout with the revised UX design.


74-74: Center content in passkey-permission step
Adjusted from justify-between to justify-center to maintain consistency with the signup step’s centered layout.

src/lib/hosting/get-origin.ts (1)

12-15: Handle multi-value x-forwarded-proto header

CDN / proxy setups sometimes send "https, http".
Safer parsing:

-const protocol = forwardedProto || (process.env.NODE_ENV === 'production' ? 'https' : 'http')
+const protocol =
+    (forwardedProto?.split(',')[0].trim()) ||
+    (process.env.NODE_ENV === 'production' ? 'https' : 'http')
src/interfaces/interfaces.ts (1)

291-298: Great addition of explicit PaymentLink types

Typed status enum and link payload will tighten runtime checks across the new OG-image flow.
No issues spotted.

tailwind.config.js (1)

28-30: Color palette extension looks consistent

secondary.8 fits the existing naming convention and doesn’t clash with other keys.

src/components/Withdraw/views/Initial.withdraw.view.tsx (1)

95-96: Nice UX tweak

The updated placeholder accurately reflects the new restriction.

src/components/Claim/Claim.tsx (1)

115-116: 👍 Reward data plumbed through

Connecting rewardData into extraDataForDrawer looks correct and non-breaking.

src/app/manifest.ts (1)

64-67: Missing fallback when NEXT_PUBLIC_BASE_URL is undefined

In non-prod environments the env var might not be set, producing
url: "undefined/manifest.webmanifest" – an invalid manifest that fails PWA install.

Consider a safe default:

-                url: `${process.env.NEXT_PUBLIC_BASE_URL}/manifest.webmanifest`,
+                url: `${process.env.NEXT_PUBLIC_BASE_URL ?? ''}/manifest.webmanifest`,

or throw at build-time if the variable is absent to avoid shipping a bad manifest.

src/components/Global/Modal/index.tsx (1)

46-48: Good default-focus fallback

Using the dialog itself when no initialFocus is provided is a solid accessibility improvement.

src/components/TransactionDetails/transactionTransformer.ts (1)

18-25: Export looks fine

Re-exporting REWARD_TOKENS for reuse is straightforward and low-risk.

src/components/Global/ValidatedInput/index.tsx (1)

154-158: Border classes duplicated & may be overridden by parent
ValidatedInput always starts with border-n-1; parents (e.g. Signup) also pass border-error/border-secondary-*. twMerge keeps the last duplicate, so internal error highlighting may be silently overridden. Document this precedence or expose an hasError prop instead of double class merging.

@jjramirezn jjramirezn merged commit 5217f95 into peanut-wallet Jun 13, 2025
5 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Oct 3, 2025
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.

4 participants