Skip to content

Support and beta changes to staging#977

Closed
jjramirezn wants to merge 4 commits intopeanut-wallet-devfrom
peanut-wallet
Closed

Support and beta changes to staging#977
jjramirezn wants to merge 4 commits intopeanut-wallet-devfrom
peanut-wallet

Conversation

@jjramirezn
Copy link
Contributor

No description provided.

jjramirezn and others added 4 commits July 7, 2025 17:12
* fix: update desktop navigation

* fix: support page
* feat: beta changes

- Banner that redirects to support page
- Funds warning modal

* refactor(banner): remove from landing and add hand thumbs up
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jul 11, 2025

Walkthrough

This update introduces a new balance warning modal and supporting environment variable, refactors wallet balance fetching to use a new Mobula API-based function, removes legacy balance fetching code, and enhances UI components including banners, navigation, and button interactions. Several components receive styling and logic updates, and test assertions are adjusted for payment rail naming.

Changes

Files/Paths Change Summary
.env.example Added NEXT_PUBLIC_BALANCE_WARNING_THRESHOLD environment variable.
src/app/(mobile-ui)/home/page.tsx, src/components/Global/BalanceWarningModal/index.tsx Added BalanceWarningModal and logic to trigger it based on wallet balance and session state.
src/app/actions/tokens.ts, src/components/Global/TokenSelector/TokenSelector.tsx Introduced new Mobula-based fetchWalletBalances function and types; updated imports.
src/utils/balance.utils.ts, src/app/api/walletconnect/fetch-wallet-balance/route.ts Removed legacy wallet balance fetching logic and related API route.
src/components/Global/Banner/index.tsx, src/app/(mobile-ui)/layout.tsx Refactored banner logic: replaced GenericBanner with FeedbackBanner and conditional rendering.
src/components/0_Bruddle/Button.tsx Enhanced Button to support configurable long press actions with progress bar feedback.
src/components/Global/WalletNavigation/index.tsx Split "Cashout" into "Add" and "Withdraw" entries; adjusted divider rendering.
src/app/(mobile-ui)/support/page.tsx Updated iframe styling for responsive layouts on larger screens.
src/components/CrispChat.tsx Simplified CrispButton to always navigate to /support, removing Crisp chat API logic.
src/assets/illustrations/index.ts, src/components/LandingPage/imageAssets.tsx Removed HandToken asset export and related commented-out image usage.
src/utils/__tests__/bridge.utils.test.ts Updated test assertions for US offramp payment rail from 'ach_pull' to 'ach'.

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • kushagrasarathe
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch peanut-wallet

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.

@jjramirezn jjramirezn requested a review from Hugo0 July 11, 2025 15:03
@vercel
Copy link

vercel bot commented Jul 11, 2025

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

Name Status Preview Comments Updated (UTC)
peanut-wallet 🔄 Building (Inspect) Visit Preview 💬 Add feedback Jul 11, 2025 3:03pm

@coderabbitai coderabbitai bot added the enhancement New feature or request label Jul 11, 2025
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: 2

🧹 Nitpick comments (2)
src/components/0_Bruddle/Button.tsx (2)

244-246: Prevent default touch behavior

Touch events should prevent default behavior to avoid conflicts with scrolling or other touch gestures.

-onTouchStart={longPress ? handlePressStart : undefined}
+onTouchStart={longPress ? (e) => {
+    e.preventDefault()
+    handlePressStart()
+} : undefined}

124-133: Consider using requestAnimationFrame for smoother animations

The progress animation uses setInterval with 16ms updates. Using requestAnimationFrame would provide smoother animations and better performance.

Replace the setInterval approach with requestAnimationFrame for better performance and smoother animations, especially on devices with different refresh rates.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 1c8db75 and fb19d90.

⛔ Files ignored due to path filters (1)
  • src/assets/illustrations/hand-token.svg is excluded by !**/*.svg
📒 Files selected for processing (16)
  • .env.example (1 hunks)
  • src/app/(mobile-ui)/home/page.tsx (5 hunks)
  • src/app/(mobile-ui)/layout.tsx (3 hunks)
  • src/app/(mobile-ui)/support/page.tsx (1 hunks)
  • src/app/actions/tokens.ts (3 hunks)
  • src/app/api/walletconnect/fetch-wallet-balance/route.ts (0 hunks)
  • src/assets/illustrations/index.ts (0 hunks)
  • src/components/0_Bruddle/Button.tsx (4 hunks)
  • src/components/CrispChat.tsx (1 hunks)
  • src/components/Global/BalanceWarningModal/index.tsx (1 hunks)
  • src/components/Global/Banner/index.tsx (1 hunks)
  • src/components/Global/TokenSelector/TokenSelector.tsx (2 hunks)
  • src/components/Global/WalletNavigation/index.tsx (2 hunks)
  • src/components/LandingPage/imageAssets.tsx (0 hunks)
  • src/utils/__tests__/bridge.utils.test.ts (3 hunks)
  • src/utils/balance.utils.ts (0 hunks)
💤 Files with no reviewable changes (4)
  • src/components/LandingPage/imageAssets.tsx
  • src/assets/illustrations/index.ts
  • src/app/api/walletconnect/fetch-wallet-balance/route.ts
  • src/utils/balance.utils.ts
🧰 Additional context used
🧠 Learnings (12)
📓 Common learnings
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#956
File: src/app/actions/tokens.ts:220-227
Timestamp: 2025-07-07T19:55:14.380Z
Learning: In the Mobula API integration within `src/app/actions/tokens.ts`, the `asset.asset.blockchains` array and `asset.contracts_balances` array are synchronized, meaning for every blockchain in the blockchains array, there will be a corresponding entry in the contracts_balances array with matching address. This makes the non-null assertion operator safe to use when accessing `contractInfo!.decimals` in the `fetchWalletBalances` function.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/context/walletContext/walletContext.tsx:87-88
Timestamp: 2024-12-02T17:21:45.515Z
Learning: When converting `totalBalance` (in USD) to a `BigInt` balance in `src/context/walletContext/walletContext.tsx`, multiplying by `1e6` is intentional to maintain compatibility with USDC's 6 decimal places. The application displays only 2 decimal places, so this level of precision is sufficient.
.env.example (3)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/Link/Input.view.tsx:244-248
Timestamp: 2024-10-29T12:20:47.207Z
Learning: In the `TokenAmountInput` component within `src/components/Global/TokenAmountInput/index.tsx`, when `balance` is undefined, the `maxValue` prop should be set to an empty string `''`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/context/walletContext/walletContext.tsx:87-88
Timestamp: 2024-12-02T17:21:45.515Z
Learning: When converting `totalBalance` (in USD) to a `BigInt` balance in `src/context/walletContext/walletContext.tsx`, multiplying by `1e6` is intentional to maintain compatibility with USDC's 6 decimal places. The application displays only 2 decimal places, so this level of precision is sufficient.
src/components/Global/TokenSelector/TokenSelector.tsx (16)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `TokenContextProvider` component within `src/context/tokenSelector.context.tsx`, in the TypeScript React application, when data changes and before calling `fetchAndSetTokenPrice`, it is necessary to reset `selectedTokenData`, `selectedTokenPrice`, `selectedTokenDecimals`, and `inputDenomination` to discard stale data.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#424
File: src/components/Global/TokenSelector/TokenSelector.tsx:197-211
Timestamp: 2024-10-11T01:14:15.489Z
Learning: In `src/components/Global/TokenSelector/TokenSelector.tsx`, when the calculation within functions like `byChainAndText` is not computationally expensive, it's acceptable to avoid using `useCallback` for memoization.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#404
File: src/context/tokenSelector.context.tsx:121-121
Timestamp: 2024-10-03T09:57:43.885Z
Learning: In `TokenContextProvider` within `tokenSelector.context.tsx`, when token data is loaded from preferences, it's acceptable to set `isTokenPriceFetchingComplete` to `true` because the token data is already available.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#631
File: src/components/Create/Create.tsx:108-112
Timestamp: 2025-01-16T13:14:40.363Z
Learning: In the Peanut UI codebase, the `resetTokenContextProvider` function from `tokenSelectorContext` is a stable function reference that doesn't change, so it doesn't need to be included in useEffect dependencies.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/Link/Input.view.tsx:244-248
Timestamp: 2024-10-29T12:20:47.207Z
Learning: In the `TokenAmountInput` component within `src/components/Global/TokenAmountInput/index.tsx`, when `balance` is undefined, the `maxValue` prop should be set to an empty string `''`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#478
File: src/components/Dashboard/useDashboard.tsx:134-134
Timestamp: 2024-10-24T12:36:40.508Z
Learning: In the file `src/components/Dashboard/useDashboard.tsx`, memoization of the `getTokenSymbol` function is not necessary because it is lightweight and does not involve complex computations or network calls.
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.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#956
File: src/app/actions/tokens.ts:220-227
Timestamp: 2025-07-07T19:55:14.380Z
Learning: In the Mobula API integration within `src/app/actions/tokens.ts`, the `asset.asset.blockchains` array and `asset.contracts_balances` array are synchronized, meaning for every blockchain in the blockchains array, there will be a corresponding entry in the contracts_balances array with matching address. This makes the non-null assertion operator safe to use when accessing `contractInfo!.decimals` in the `fetchWalletBalances` function.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-04T13:10:49.199Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.tsx:103-111
Timestamp: 2024-10-08T20:13:42.967Z
Learning: When the token price cannot be fetched in `src/components/Request/Pay/Pay.tsx` within the `PayRequestLink` component, set `tokenPriceData.price` to 0 to ensure the UI remains functional. Since Squid uses their own price engine for x-chain fulfillment transactions, this approach will not affect the transaction computation.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.tsx:103-111
Timestamp: 2024-10-07T13:42:00.443Z
Learning: When the token price cannot be fetched in `src/components/Request/Pay/Pay.tsx` within the `PayRequestLink` component, set `tokenPriceData.price` to 0 to ensure the UI remains functional. Since Squid uses their own price engine for x-chain fulfillment transactions, this approach will not affect the transaction computation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#478
File: src/components/Request/Create/Views/Initial.view.tsx:81-89
Timestamp: 2024-10-24T12:38:32.793Z
Learning: In `src/components/Request/Create/Views/Initial.view.tsx`, the function `getTokenDetails` is a simple function that does not fetch from the network or perform asynchronous operations.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#919
File: src/components/Withdraw/views/Initial.withdraw.view.tsx:87-87
Timestamp: 2025-06-18T19:56:55.443Z
Learning: In withdraw flows for Peanut Wallet, the PeanutActionDetailsCard should always display "USDC" as the token symbol because it shows the amount being withdrawn from the Peanut Wallet (which holds USDC), regardless of the destination token/chain selected by the user. The TokenSelector is used for choosing the withdrawal destination, not the source display.
src/components/CrispChat.tsx (5)
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:141-141
Timestamp: 2024-10-18T01:51:35.247Z
Learning: The `handleConfirm` function in `src/components/Create/Link/Confirm.view.tsx` is separate from the one in `src/components/Offramp/Confirm.view.tsx` and does not need to be renamed when refactoring `handleConfirm` in `src/components/Offramp/Confirm.view.tsx`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:96-96
Timestamp: 2024-10-18T08:54:22.142Z
Learning: In the `src/components/Offramp/Confirm.view.tsx` file, it's acceptable to include crass or informal language in code comments.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#478
File: src/components/Dashboard/useDashboard.tsx:134-134
Timestamp: 2024-10-24T12:36:40.508Z
Learning: In the file `src/components/Dashboard/useDashboard.tsx`, memoization of the `getTokenSymbol` function is not necessary because it is lightweight and does not involve complex computations or network calls.
src/components/Global/WalletNavigation/index.tsx (9)
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#484
File: src/components/Cashout/Components/Initial.view.tsx:273-274
Timestamp: 2024-10-25T11:33:46.776Z
Learning: In the `InitialCashoutView` component (`src/components/Cashout/Components/Initial.view.tsx`), linked bank accounts should not generate error states, and the `ValidatedInput` component will clear any error messages if needed. Therefore, it's unnecessary to manually clear the error state when selecting or clearing linked bank accounts.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#420
File: src/components/Offramp/Offramp.consts.ts:27-28
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Offramp/Offramp.consts.ts`, the `MIN_CASHOUT_LIMIT` is set to $10 because smaller amounts are impractical due to approximately $1 fee per cashout.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:25:45.170Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(...)` return strings, ensuring that `calculatedFee` consistently returns a string without the need for additional type conversion.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:28:25.280Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(estimatedGasCost, 3)` return strings, ensuring consistent return types for `calculatedFee`.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:141-141
Timestamp: 2024-10-18T01:51:35.247Z
Learning: The `handleConfirm` function in `src/components/Create/Link/Confirm.view.tsx` is separate from the one in `src/components/Offramp/Confirm.view.tsx` and does not need to be renamed when refactoring `handleConfirm` in `src/components/Offramp/Confirm.view.tsx`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:04.446Z
Learning: Within `src/app/request/pay/page.tsx`, extracting the `getBaseUrl` function does not add significant readability, and the host URL construction code is expected to change soon.
src/utils/__tests__/bridge.utils.test.ts (1)
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#420
File: src/components/Offramp/Offramp.consts.ts:27-28
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Offramp/Offramp.consts.ts`, the `MIN_CASHOUT_LIMIT` is set to $10 because smaller amounts are impractical due to approximately $1 fee per cashout.
src/app/(mobile-ui)/layout.tsx (6)
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:96-96
Timestamp: 2024-10-18T08:54:22.142Z
Learning: In the `src/components/Offramp/Confirm.view.tsx` file, it's acceptable to include crass or informal language in code comments.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:27.670Z
Learning: In `src/app/request/pay/page.tsx`, if `linkRes` is not OK in the `generateMetadata` function, the desired behavior is to use the standard title and preview image without throwing an error.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#828
File: src/app/(mobile-ui)/request/[...username]/page.tsx:17-17
Timestamp: 2025-05-02T19:14:25.010Z
Learning: In Next.js App Router, catch-all routes (like `/request/[...username]`) will only match URLs with at least one parameter segment, ensuring that the page component only renders when there is at least one value in the params array.
src/components/Global/BalanceWarningModal/index.tsx (13)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/Link/Input.view.tsx:244-248
Timestamp: 2024-10-29T12:20:47.207Z
Learning: In the `TokenAmountInput` component within `src/components/Global/TokenAmountInput/index.tsx`, when `balance` is undefined, the `maxValue` prop should be set to an empty string `''`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#484
File: src/components/Cashout/Components/Initial.view.tsx:273-274
Timestamp: 2024-10-25T11:33:46.776Z
Learning: In the `InitialCashoutView` component (`src/components/Cashout/Components/Initial.view.tsx`), linked bank accounts should not generate error states, and the `ValidatedInput` component will clear any error messages if needed. Therefore, it's unnecessary to manually clear the error state when selecting or clearing linked bank accounts.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#535
File: src/components/Claim/Claim.tsx:142-146
Timestamp: 2024-11-18T21:36:11.486Z
Learning: In `src/components/Claim/Claim.tsx`, external calls like token price fetching and cross-chain details retrieval are already encapsulated within existing `try...catch` blocks, so additional error handling may be unnecessary.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-07T15:50:29.173Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `TokenContextProvider` component within `src/context/tokenSelector.context.tsx`, in the TypeScript React application, when data changes and before calling `fetchAndSetTokenPrice`, it is necessary to reset `selectedTokenData`, `selectedTokenPrice`, `selectedTokenDecimals`, and `inputDenomination` to discard stale data.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-04T13:10:49.199Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#413
File: src/components/Request/Pay/Views/Initial.view.tsx:71-72
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, it's acceptable to use the `!` operator in TypeScript to assert that `selectedTokenData` is not `null` or `undefined`, and potential runtime errors from accessing its properties without checks can be disregarded.
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.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:96-96
Timestamp: 2024-10-18T08:54:22.142Z
Learning: In the `src/components/Offramp/Confirm.view.tsx` file, it's acceptable to include crass or informal language in code comments.
src/components/0_Bruddle/Button.tsx (5)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#424
File: src/components/Global/TokenSelector/TokenSelector.tsx:197-211
Timestamp: 2024-10-11T01:14:15.489Z
Learning: In `src/components/Global/TokenSelector/TokenSelector.tsx`, when the calculation within functions like `byChainAndText` is not computationally expensive, it's acceptable to avoid using `useCallback` for memoization.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#0
File: :0-0
Timestamp: 2025-07-05T16:58:25.340Z
Learning: Hugo0 successfully refactored sessionStorage usage to React Context in the onramp flow, demonstrating preference for centralized state management over browser storage for component-shared state in React applications.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#631
File: src/components/Create/Create.tsx:108-112
Timestamp: 2025-01-16T13:14:40.363Z
Learning: In the Peanut UI codebase, the `resetTokenContextProvider` function from `tokenSelectorContext` is a stable function reference that doesn't change, so it doesn't need to be included in useEffect dependencies.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#478
File: src/components/Request/Create/Views/Initial.view.tsx:48-128
Timestamp: 2024-10-24T12:40:15.006Z
Learning: When `handleOnNext` is deliberately refactored to avoid dependencies that change, it's acceptable to have an empty dependency array in `useCallback`.
src/app/(mobile-ui)/home/page.tsx (14)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/Link/Input.view.tsx:244-248
Timestamp: 2024-10-29T12:20:47.207Z
Learning: In the `TokenAmountInput` component within `src/components/Global/TokenAmountInput/index.tsx`, when `balance` is undefined, the `maxValue` prop should be set to an empty string `''`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#484
File: src/components/Cashout/Components/Initial.view.tsx:273-274
Timestamp: 2024-10-25T11:33:46.776Z
Learning: In the `InitialCashoutView` component (`src/components/Cashout/Components/Initial.view.tsx`), linked bank accounts should not generate error states, and the `ValidatedInput` component will clear any error messages if needed. Therefore, it's unnecessary to manually clear the error state when selecting or clearing linked bank accounts.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-07T15:50:29.173Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#535
File: src/components/Claim/Claim.tsx:142-146
Timestamp: 2024-11-18T21:36:11.486Z
Learning: In `src/components/Claim/Claim.tsx`, external calls like token price fetching and cross-chain details retrieval are already encapsulated within existing `try...catch` blocks, so additional error handling may be unnecessary.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Global/TokenAmountInput/index.tsx:23-30
Timestamp: 2024-10-29T12:19:41.968Z
Learning: In the `TokenAmountInput` component (`src/components/Global/TokenAmountInput/index.tsx`), when the 'Max' button is clicked, we intentionally set the input denomination to 'TOKEN' because we are setting the value as token.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#956
File: src/app/actions/tokens.ts:220-227
Timestamp: 2025-07-07T19:55:14.380Z
Learning: In the Mobula API integration within `src/app/actions/tokens.ts`, the `asset.asset.blockchains` array and `asset.contracts_balances` array are synchronized, meaning for every blockchain in the blockchains array, there will be a corresponding entry in the contracts_balances array with matching address. This makes the non-null assertion operator safe to use when accessing `contractInfo!.decimals` in the `fetchWalletBalances` function.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/context/walletContext/walletContext.tsx:87-88
Timestamp: 2024-12-02T17:21:45.515Z
Learning: When converting `totalBalance` (in USD) to a `BigInt` balance in `src/context/walletContext/walletContext.tsx`, multiplying by `1e6` is intentional to maintain compatibility with USDC's 6 decimal places. The application displays only 2 decimal places, so this level of precision is sufficient.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `TokenContextProvider` component within `src/context/tokenSelector.context.tsx`, in the TypeScript React application, when data changes and before calling `fetchAndSetTokenPrice`, it is necessary to reset `selectedTokenData`, `selectedTokenPrice`, `selectedTokenDecimals`, and `inputDenomination` to discard stale data.
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.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#631
File: src/components/Create/Create.tsx:108-112
Timestamp: 2025-01-16T13:14:40.363Z
Learning: In the Peanut UI codebase, the `resetTokenContextProvider` function from `tokenSelectorContext` is a stable function reference that doesn't change, so it doesn't need to be included in useEffect dependencies.
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
Learnt from: kushagrasarathe
PR: peanutprotocol/peanut-ui#869
File: src/app/(mobile-ui)/withdraw/page.tsx:82-88
Timestamp: 2025-05-22T15:38:48.586Z
Learning: The country-specific withdrawal route exists at src/app/(mobile-ui)/withdraw/[...country]/page.tsx and renders the AddWithdrawCountriesList component with flow="withdraw".
src/components/Global/Banner/index.tsx (5)
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:141-141
Timestamp: 2024-10-18T01:51:35.247Z
Learning: The `handleConfirm` function in `src/components/Create/Link/Confirm.view.tsx` is separate from the one in `src/components/Offramp/Confirm.view.tsx` and does not need to be renamed when refactoring `handleConfirm` in `src/components/Offramp/Confirm.view.tsx`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#564
File: src/components/Request/Pay/Views/Initial.view.tsx:430-430
Timestamp: 2024-12-11T10:13:22.806Z
Learning: In the React TypeScript file `src/components/Request/Pay/Views/Initial.view.tsx`, when reviewing the `InitialView` component, do not flag potential issues with using non-null assertion `!` on the `slippagePercentage` variable, as handling undefined values in this context is considered out of scope.
Learnt from: Hugo0
PR: peanutprotocol/peanut-ui#458
File: src/components/Offramp/Confirm.view.tsx:96-96
Timestamp: 2024-10-18T08:54:22.142Z
Learning: In the `src/components/Offramp/Confirm.view.tsx` file, it's acceptable to include crass or informal language in code comments.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#495
File: src/components/Create/useCreateLink.tsx:647-657
Timestamp: 2024-10-29T16:06:38.812Z
Learning: In the React code for `useCreateLink` in `src/components/Create/useCreateLink.tsx`, the `switchNetwork` function used within `useCallback` hooks is stable and does not need to be included in the dependency arrays.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#469
File: src/app/request/pay/page.tsx:32-64
Timestamp: 2024-10-23T09:38:27.670Z
Learning: In `src/app/request/pay/page.tsx`, if `linkRes` is not OK in the `generateMetadata` function, the desired behavior is to use the standard title and preview image without throwing an error.
src/app/actions/tokens.ts (10)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#956
File: src/app/actions/tokens.ts:220-227
Timestamp: 2025-07-07T19:55:14.380Z
Learning: In the Mobula API integration within `src/app/actions/tokens.ts`, the `asset.asset.blockchains` array and `asset.contracts_balances` array are synchronized, meaning for every blockchain in the blockchains array, there will be a corresponding entry in the contracts_balances array with matching address. This makes the non-null assertion operator safe to use when accessing `contractInfo!.decimals` in the `fetchWalletBalances` function.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#958
File: src/app/actions/tokens.ts:266-266
Timestamp: 2025-07-07T20:22:11.092Z
Learning: In `src/app/actions/tokens.ts`, within the `fetchWalletBalances` function, using the non-null assertion operator `!` on `process.env.MOBULA_API_KEY!` is intentional and correct, and should not be flagged for replacement with explicit validation.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In the `TokenContextProvider` component within `src/context/tokenSelector.context.tsx`, in the TypeScript React application, when data changes and before calling `fetchAndSetTokenPrice`, it is necessary to reset `selectedTokenData`, `selectedTokenPrice`, `selectedTokenDecimals`, and `inputDenomination` to discard stale data.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#551
File: src/context/walletContext/walletContext.tsx:87-88
Timestamp: 2024-12-02T17:21:45.515Z
Learning: When converting `totalBalance` (in USD) to a `BigInt` balance in `src/context/walletContext/walletContext.tsx`, multiplying by `1e6` is intentional to maintain compatibility with USDC's 6 decimal places. The application displays only 2 decimal places, so this level of precision is sufficient.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:28:25.280Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(estimatedGasCost, 3)` return strings, ensuring consistent return types for `calculatedFee`.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#535
File: src/components/Claim/Claim.tsx:142-146
Timestamp: 2024-11-18T21:36:11.486Z
Learning: In `src/components/Claim/Claim.tsx`, external calls like token price fetching and cross-chain details retrieval are already encapsulated within existing `try...catch` blocks, so additional error handling may be unnecessary.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Views/Initial.view.tsx:76-78
Timestamp: 2024-10-07T15:25:45.170Z
Learning: In `src/components/Request/Pay/Views/Initial.view.tsx`, both `txFee` and `utils.formatTokenAmount(...)` return strings, ensuring that `calculatedFee` consistently returns a string without the need for additional type conversion.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#404
File: src/context/tokenSelector.context.tsx:121-121
Timestamp: 2024-10-03T09:57:43.885Z
Learning: In `TokenContextProvider` within `tokenSelector.context.tsx`, when token data is loaded from preferences, it's acceptable to set `isTokenPriceFetchingComplete` to `true` because the token data is already available.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-08T20:13:42.967Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#422
File: src/components/Request/Pay/Pay.consts.ts:34-34
Timestamp: 2024-10-07T15:50:29.173Z
Learning: In `src/components/Request/Pay` components, the `tokenPrice` property in the `IPayScreenProps` interface is only relevant to these views. Other components using `IPayScreenProps` do not need to handle `tokenPriceData` when it's updated in these components.
🧬 Code Graph Analysis (6)
src/app/(mobile-ui)/layout.tsx (1)
src/components/Global/MarqueeWrapper/index.tsx (1)
  • MarqueeWrapper (16-33)
src/components/Global/BalanceWarningModal/index.tsx (2)
src/components/Global/Icons/Icon.tsx (1)
  • Icon (165-174)
src/components/0_Bruddle/Button.tsx (1)
  • Button (75-268)
src/components/0_Bruddle/Button.tsx (1)
src/app/[...recipient]/loading.tsx (1)
  • Loading (3-5)
src/app/(mobile-ui)/home/page.tsx (2)
src/constants/zerodev.consts.ts (1)
  • PEANUT_WALLET_TOKEN_DECIMALS (19-19)
src/components/Global/BalanceWarningModal/index.tsx (1)
  • BalanceWarningModal (72-132)
src/components/Global/Banner/index.tsx (3)
src/middleware.ts (1)
  • config (48-50)
src/components/Global/Banner/MaintenanceBanner.tsx (1)
  • MaintenanceBanner (8-16)
src/components/Global/MarqueeWrapper/index.tsx (1)
  • MarqueeWrapper (16-33)
src/app/actions/tokens.ts (4)
src/utils/__mocks__/next-cache.ts (1)
  • unstable_cache (1-1)
src/interfaces/interfaces.ts (1)
  • IUserBalance (19-30)
src/utils/sentry.utils.ts (1)
  • fetchWithSentry (11-89)
src/utils/general.utils.ts (3)
  • isStableCoin (1108-1110)
  • estimateIfIsStableCoinFromPrice (748-755)
  • areEvmAddressesEqual (420-427)
⏰ 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: Analyze (javascript-typescript)
🔇 Additional comments (23)
src/components/Global/TokenSelector/TokenSelector.tsx (1)

14-14: LGTM!

The import refactor correctly moves fetchWalletBalances to its new location in the actions module.

Also applies to: 29-29

.env.example (1)

36-36: LGTM!

The new environment variable follows the existing naming convention and provides a sensible default value for the balance warning threshold.

src/app/(mobile-ui)/support/page.tsx (1)

7-7: LGTM!

The responsive styling improves the layout on larger screens while maintaining full width on mobile devices.

src/utils/__tests__/bridge.utils.test.ts (1)

23-23: LGTM!

The test assertions have been consistently updated to reflect the payment rail naming change from 'ach_pull' to 'ach' for US offramp operations.

Also applies to: 99-99, 201-201

src/components/CrispChat.tsx (1)

10-10: LGTM! Simplified support routing.

The change consolidates support access by always routing to /support, which aligns with the broader changes in this PR to centralize user support interactions.

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

21-22: LGTM! Improved navigation granularity.

Splitting the single "Cashout" entry into separate "Add" and "Withdraw" actions provides better user experience with more specific navigation options. The icon choices (arrow-down for Add, arrow-up for Withdraw) are intuitive.


54-54: LGTM! Correctly adjusted divider placement.

The divider placement update from index 3 to index 4 correctly accounts for the additional navigation item, maintaining proper visual separation in the menu structure.

src/app/(mobile-ui)/layout.tsx (2)

3-6: LGTM! Proper imports and router setup.

The new imports and router initialization are correctly implemented to support the interactive banner functionality.

Also applies to: 28-28


106-116: LGTM! Well-implemented interactive feedback banner.

The conditional banner implementation is excellent:

  • Only shows on non-landing pages (pathName !== '/')
  • Uses MarqueeWrapper component correctly with proper props
  • Includes intuitive click-to-support navigation
  • Maintains consistent styling with the thumbs-up icon

This aligns well with the PR's goal of consolidating support access points.

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

8-37: LGTM! Comprehensive platform configuration.

The platform enum and info mapping provides excellent coverage of major platforms with appropriate support documentation links for each platform's passkey implementation.


44-70: LGTM! Robust platform detection logic.

The platform detection function handles various edge cases well:

  • Properly detects iPad on iOS 13+ using the touch points fallback
  • Correctly distinguishes between macOS and iOS devices
  • Includes comprehensive user agent pattern matching
  • Gracefully handles server-side rendering with the window check

72-132: LGTM! Well-designed modal implementation.

The modal component follows React best practices:

  • Uses useMemo for performance optimization of platform detection
  • Implements proper modal behavior with preventClose and hideOverlay
  • Requires user acknowledgment through a 2-second long press
  • Provides clear, educational content about self-custodial risks
  • Includes platform-specific passkey security links

The long press requirement ensures users actually read the warning before proceeding.

src/app/actions/tokens.ts (3)

8-9: LGTM! Appropriate utility imports.

The new imports provide the necessary utilities for the enhanced wallet balance fetching functionality.


54-96: LGTM! Comprehensive TypeScript type definitions.

The type definitions accurately represent the Mobula API response structure:

  • Clear distinction between contract balances and cross-chain balances
  • Proper typing for nested objects and arrays
  • Descriptive comments for complex fields like chainId format
  • Well-structured hierarchy from portfolio down to individual asset data

194-250: LGTM! Robust wallet balance fetching implementation.

The fetchWalletBalances function is well-implemented with several strong points:

  • Proper error handling for API failures
  • Effective filtering of invalid assets (missing price or balance)
  • Correct handling of cross-chain balances by iterating through blockchains
  • Appropriate stable coin price normalization
  • Efficient caching with 5-second revalidation
  • Proper TypeScript typing throughout

The non-null assertion on contractInfo!.decimals is safe given the synchronized nature of the Mobula API arrays as noted in the retrieved learnings.

src/app/(mobile-ui)/home/page.tsx (5)

27-32: LGTM! Clean imports and environment variable handling.

The new imports are appropriate for the balance warning functionality. The BALANCE_WARNING_THRESHOLD constant properly handles the environment variable with a sensible default value of 500.


51-51: LGTM! Proper state initialization.

The showBalanceWarningModal state is correctly initialized as false, following the existing pattern for other modal states.


106-126: LGTM! Well-implemented balance warning logic.

The balance warning useEffect is well-structured with proper conditions:

  • Checks for server-side rendering safety
  • Prevents showing during balance fetching
  • Uses session storage to avoid repeat warnings
  • Correctly converts balance using formatUnits and PEANUT_WALLET_TOKEN_DECIMALS
  • Ensures no modal conflicts by checking other modal states

The logic aligns with the retrieved learnings about USDC decimals and balance formatting.


140-150: LGTM! Proper modal coordination logic.

The add money prompt useEffect correctly includes the balance warning modal in its conditions to prevent modal conflicts. The dependency array appropriately includes showBalanceWarningModal to ensure the effect responds to changes in the balance warning modal state.


212-216: LGTM! Proper modal rendering.

The BalanceWarningModal is correctly rendered with the appropriate props. The onCloseAction prop properly handles closing the modal by setting the state to false.

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

1-6: LGTM! Clean imports for the refactored functionality.

The new imports are appropriate for the banner refactor:

  • useRouter for navigation
  • MarqueeWrapper for the scrolling effect
  • config for maintenance routes
  • HandThumbsUp asset and Image component for the feedback banner

8-23: LGTM! Well-structured banner logic.

The refactored Banner function has clean, readable logic:

  • Proper early return for landing page
  • Clear maintenance check with appropriate component rendering
  • Fallback to feedback banner for all other routes

The logic flow is intuitive and maintainable.


25-42: LGTM! Well-implemented feedback banner.

The FeedbackBanner component is properly implemented:

  • Uses useRouter for navigation instead of direct window manipulation
  • Properly structured button element with click handler
  • Appropriate use of MarqueeWrapper with correct props
  • Clear, engaging feedback message with visual icon
  • Proper accessibility with alt text for the image

Comment on lines +241 to +246
onMouseDown={longPress ? handlePressStart : undefined}
onMouseUp={longPress ? handlePressEnd : undefined}
onMouseLeave={longPress ? handlePressCancel : undefined}
onTouchStart={longPress ? handlePressStart : undefined}
onTouchEnd={longPress ? handlePressEnd : undefined}
onTouchCancel={longPress ? handlePressCancel : undefined}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add keyboard accessibility for long press

The long press functionality is only accessible via mouse and touch events, excluding keyboard users.

Consider adding keyboard support:

 onMouseDown={longPress ? handlePressStart : undefined}
 onMouseUp={longPress ? handlePressEnd : undefined}
 onMouseLeave={longPress ? handlePressCancel : undefined}
 onTouchStart={longPress ? handlePressStart : undefined}
 onTouchEnd={longPress ? handlePressEnd : undefined}
 onTouchCancel={longPress ? handlePressCancel : undefined}
+onKeyDown={longPress ? (e) => {
+    if (e.key === ' ' || e.key === 'Enter') {
+        e.preventDefault()
+        handlePressStart()
+    }
+} : undefined}
+onKeyUp={longPress ? (e) => {
+    if (e.key === ' ' || e.key === 'Enter') {
+        e.preventDefault()
+        handlePressEnd()
+    }
+} : undefined}
📝 Committable suggestion

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

Suggested change
onMouseDown={longPress ? handlePressStart : undefined}
onMouseUp={longPress ? handlePressEnd : undefined}
onMouseLeave={longPress ? handlePressCancel : undefined}
onTouchStart={longPress ? handlePressStart : undefined}
onTouchEnd={longPress ? handlePressEnd : undefined}
onTouchCancel={longPress ? handlePressCancel : undefined}
onMouseDown={longPress ? handlePressStart : undefined}
onMouseUp={longPress ? handlePressEnd : undefined}
onMouseLeave={longPress ? handlePressCancel : undefined}
onTouchStart={longPress ? handlePressStart : undefined}
onTouchEnd={longPress ? handlePressEnd : undefined}
onTouchCancel={longPress ? handlePressCancel : undefined}
onKeyDown={longPress ? (e) => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault()
handlePressStart()
}
} : undefined}
onKeyUp={longPress ? (e) => {
if (e.key === ' ' || e.key === 'Enter') {
e.preventDefault()
handlePressEnd()
}
} : undefined}
🤖 Prompt for AI Agents
In src/components/0_Bruddle/Button.tsx around lines 241 to 246, the long press
handlers are only attached to mouse and touch events, excluding keyboard users.
To fix this, add keyboard event handlers such as onKeyDown and onKeyUp to
support long press functionality via keyboard inputs like the spacebar or enter
key. Implement logic to start, end, and cancel the long press based on these
keyboard events to ensure accessibility for all users.

Comment on lines +197 to 207
return () => {
if (pressTimer) {
clearTimeout(pressTimer)
}
if (progressInterval) {
clearInterval(progressInterval)
}
}
}, [pressTimer, progressInterval])

const buttonClasses = twMerge(
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix cleanup effect to prevent memory leaks

The cleanup effect has dependencies that change during the component lifecycle. This could cause the cleanup to miss some timers if the component unmounts while handlers are updating these values.

Move the cleanup logic to a separate effect without dependencies:

-// Cleanup timers on unmount
-useEffect(() => {
-    return () => {
-        if (pressTimer) {
-            clearTimeout(pressTimer)
-        }
-        if (progressInterval) {
-            clearInterval(progressInterval)
-        }
-    }
-}, [pressTimer, progressInterval])
+// Cleanup timers on unmount
+useEffect(() => {
+    return () => {
+        setPressTimer((timer) => {
+            if (timer) clearTimeout(timer)
+            return null
+        })
+        setProgressInterval((interval) => {
+            if (interval) clearInterval(interval)
+            return null
+        })
+    }
+}, [])

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/components/0_Bruddle/Button.tsx around lines 197 to 207, the cleanup
effect depends on pressTimer and progressInterval, which can change and cause
missed timer cleanup on unmount. To fix this, remove these dependencies and move
the cleanup logic into a separate useEffect with an empty dependency array so it
only runs on unmount, ensuring all timers are properly cleared.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants