Skip to content

Conversation

jjramirezn
Copy link
Contributor

@jjramirezn jjramirezn commented Dec 3, 2024

Summary by CodeRabbit

  • New Features

    • Enhanced wallet address handling for improved user experience.
    • Selected wallet address now persists across sessions using user preferences.
    • Utility functions for local storage operations are now publicly accessible.
    • Improved initialization of token data based on user preferences.
    • Enhanced error handling for user preferences updates.
  • Bug Fixes

    • Error logging added for balance fetching issues to assist in troubleshooting.

@jjramirezn jjramirezn requested a review from Hugo0 December 3, 2024 12:24
Copy link

vercel bot commented Dec 3, 2024

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

Name Status Preview Comments Updated (UTC)
peanut-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 4, 2024 11:38am

Copy link
Contributor

coderabbitai bot commented Dec 3, 2024

Warning

Rate limit exceeded

@jjramirezn has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 24 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between c88869d and 0221660.

Walkthrough

The changes in this pull request enhance the walletContext.tsx file by improving the management of the selectedAddress state and user preferences. The initialization of selectedAddress now retrieves its value from user preferences, allowing persistence of the last selected wallet address. A new useEffect hook updates user preferences with the selected address upon changes. The logic for checking wallet connectivity remains intact, and the context value provided by the WalletProvider has been updated to reflect these changes.

Changes

File Change Summary
src/context/walletContext/walletContext.tsx - Updated selectedAddress state to initialize from user preferences.
- Added useEffect to update user preferences on selectedAddress change.
- Retained existing logic for wallet connectivity checks.
- Maintained createDefaultDBWallet function.
- Preserved error handling in refetchBalances function.
- Updated context value in WalletProvider for selected wallet management.
src/utils/general.utils.ts - Added export keyword to saveToLocalStorage and getFromLocalStorage functions for public accessibility.
- Introduced UserPreferences type and updated related functions.
- Renamed updatePeanutPreferences to updateUserPreferences and modified its implementation.
src/components/Create/Link/Confirm.view.tsx - Updated function call from updatePeanutPreferences to updateUserPreferences with enhanced parameter handling.
- Preserved overall structure and error handling in handleConfirm function.
src/context/tokenSelector.context.tsx - Renamed tokenAddress to address in initialTokenData.
- Updated logic to retrieve user preferences using getUserPreferences().
- Modified resetTokenContextProvider to utilize user preferences for state resetting.

Possibly related PRs

Suggested labels

Being worked on

Suggested reviewers

  • Hugo0
  • panosfilianos

🐰 In the context of wallets, I hop and play,
With localStorage, I save the day!
Selected addresses, now here to stay,
In sessions remembered, come what may.
A rabbit's delight, in code we trust,
For wallets connected, it's a must! 🌟


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ 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.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

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

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

🧹 Outside diff range and nitpick comments (1)
src/context/walletContext/walletContext.tsx (1)

156-161: Enhance localStorage management

The current implementation could be improved by:

  1. Cleaning up localStorage when address is cleared
  2. Adding error handling for localStorage operations
  3. Considering debouncing for frequent updates

Consider this enhanced implementation:

 useEffect(() => {
-    if (selectedAddress) {
+    try {
+      if (selectedAddress) {
         localStorage.setItem('selectedAddress', selectedAddress)
+      } else {
+        localStorage.removeItem('selectedAddress')
+      }
+    } catch (error) {
+      console.error('Failed to persist selected address:', error)
     }
 }, [selectedAddress])
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between cab3010 and 3ab0390.

📒 Files selected for processing (1)
  • src/context/walletContext/walletContext.tsx (2 hunks)
🔇 Additional comments (1)
src/context/walletContext/walletContext.tsx (1)

Line range hint 54-161: Consider security and testing implications

While the implementation achieves the goal of persisting the selected address, please consider:

  1. Security: Document the security implications of storing wallet addresses in localStorage
  2. Privacy: Add a note in the privacy policy about storing wallet information locally
  3. Testing: Ensure test coverage for:
    • localStorage persistence
    • Address validation
    • SSR compatibility
    • Error scenarios

Let's verify the test coverage:

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

🧹 Outside diff range and nitpick comments (3)
src/utils/general.utils.ts (3)

Line range hint 86-97: Consider enhancing data security and error handling in saveToLocalStorage.

The function could benefit from several security improvements:

  1. Remove or conditionally enable debug logging in production
  2. Add data validation/sanitization
  3. Consider encrypting sensitive data
  4. Add size limits to prevent localStorage quota issues
 export const saveToLocalStorage = (key: string, data: any) => {
     try {
+        if (!key || !data) {
+            throw new Error('Invalid key or data');
+        }
+        // Add size validation
+        const serializedData = JSON.stringify(data);
+        if (serializedData.length > 5242880) { // 5MB limit
+            throw new Error('Data exceeds size limit');
+        }
-        // Convert the data to a string before storing it in localStorage
-        const serializedData = JSON.stringify(data)
         if (typeof localStorage === 'undefined') return
         localStorage.setItem(key, serializedData)
-        console.log(`Saved ${key} to localStorage:`, data)
+        if (process.env.NODE_ENV !== 'production') {
+            console.log(`Saved ${key} to localStorage`);
+        }
     } catch (error) {
         console.error('Error saving to localStorage:', error)
+        throw error; // Re-throw to allow caller to handle
     }
 }

Line range hint 98-112: Enhance error handling and type safety in getFromLocalStorage.

The function needs improvements in error handling and type safety:

  1. Remove or conditionally enable debug logging in production
  2. Add type parameter for better type safety
  3. Improve error handling for JSON parsing
-export const getFromLocalStorage = (key: string) => {
+export const getFromLocalStorage = <T>(key: string): T | null => {
     try {
+        if (!key) {
+            throw new Error('Invalid key');
+        }
         if (typeof localStorage === 'undefined') return null
         const data = localStorage.getItem(key)
         if (data === null) {
-            console.log(`No data found in localStorage for ${key}`)
+            if (process.env.NODE_ENV !== 'production') {
+                console.log(`No data found in localStorage for ${key}`);
+            }
             return null
         }
-        const parsedData = JSON.parse(data)
-        console.log(`Retrieved ${key} from localStorage:`, parsedData)
-        return parsedData
+        try {
+            const parsedData = JSON.parse(data) as T;
+            if (process.env.NODE_ENV !== 'production') {
+                console.log(`Retrieved ${key} from localStorage`);
+            }
+            return parsedData;
+        } catch (parseError) {
+            console.error('Error parsing JSON from localStorage:', parseError);
+            return null;
+        }
     } catch (error) {
         console.error('Error getting data from localStorage:', error)
+        return null;
     }
 }

Line range hint 86-112: Consider implementing a centralized storage service.

Both functions are part of a larger pattern of localStorage usage throughout the file. Consider creating a centralized storage service that:

  1. Provides consistent error handling
  2. Implements encryption for sensitive data
  3. Manages storage quotas
  4. Handles data migration
  5. Provides type safety

Example implementation:

interface StorageService {
  save<T>(key: string, data: T): Promise<void>;
  get<T>(key: string): Promise<T | null>;
  remove(key: string): Promise<void>;
  clear(): Promise<void>;
}

class LocalStorageService implements StorageService {
  private readonly encrypt = (data: string): string => {
    // Implement encryption
    return data;
  };

  private readonly decrypt = (data: string): string => {
    // Implement decryption
    return data;
  };

  async save<T>(key: string, data: T): Promise<void> {
    // Implementation with encryption and validation
  }

  async get<T>(key: string): Promise<T | null> {
    // Implementation with decryption and type safety
  }

  // ... other methods
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3ab0390 and 2a75a4e.

📒 Files selected for processing (2)
  • src/context/walletContext/walletContext.tsx (3 hunks)
  • src/utils/general.utils.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/context/walletContext/walletContext.tsx

Comment on lines 15 to 16
getFromLocalStorage,
saveToLocalStorage,
Copy link
Contributor

Choose a reason for hiding this comment

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

good on using existing functions!

Thought: we should clean up general.utils.ts, we save tons of shit to localStorage in random ways. Need to clean this up - probably same time we redo our tx indexing

Copy link
Contributor

@Hugo0 Hugo0 left a comment

Choose a reason for hiding this comment

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

Issue, blocking: in this PR we set a specific key "selectedAddress" to localStorage. I think this can lead to localStorage key pollution, and it's not clear what the item means, on its own.

Since last selected address wont be the only thing we should store for users for convenience, e.g. they might have a preffered token or chain, or they might want dark or light mode, its preferable to group these all in one. We do have a getPeanutPreferences & updatePeanutPreferences. Right now it's pretty empty and the 3 items it has are badly named, but imo we should make use of a user-preferences type of pattern. Wdyt?

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

🧹 Outside diff range and nitpick comments (3)
src/context/tokenSelector.context.tsx (2)

39-48: LGTM! Consider adding type safety.

The initialization logic correctly handles user preferences while providing sensible defaults.

Consider adding type definitions for the token data structure:

interface TokenData {
  address: string;
  chainId: string;
  decimals: number;
}

const initialTokenData: TokenData = {
  address: '0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85', // USDC
  chainId: '10', // Optimism
  decimals: 6,
}

Line range hint 76-124: Enhance error logging for better debugging.

The error handling in fetchAndSetTokenPrice could be more descriptive to aid in debugging issues.

Consider enhancing the error logging:

 } catch (error) {
-    console.log('error fetching tokenPrice, falling back to tokenDenomination')
+    console.error('Failed to fetch token price:', {
+        tokenAddress,
+        chainId,
+        error: error instanceof Error ? error.message : String(error)
+    })
 }
src/components/Create/Link/Confirm.view.tsx (1)

213-221: LGTM! Consider adding error handling for preferences update.

The user preferences update is well-structured with appropriate null checks. However, the update could fail silently.

Consider adding error handling:

 if (selectedChainID && selectedTokenAddress && selectedTokenDecimals) {
+    try {
         updateUserPreferences({
             lastUsedToken: {
                 chainId: selectedChainID,
                 address: selectedTokenAddress,
                 decimals: selectedTokenDecimals,
             },
         })
+    } catch (error) {
+        console.warn('Failed to update user preferences:', error)
+        // Non-blocking error - don't throw
+    }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 2a75a4e and 258e5ad.

📒 Files selected for processing (4)
  • src/components/Create/Link/Confirm.view.tsx (2 hunks)
  • src/context/tokenSelector.context.tsx (2 hunks)
  • src/context/walletContext/walletContext.tsx (3 hunks)
  • src/utils/general.utils.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/context/walletContext/walletContext.tsx
  • src/utils/general.utils.ts
🧰 Additional context used
📓 Learnings (1)
src/context/tokenSelector.context.tsx (1)
Learnt from: jjramirezn
PR: peanutprotocol/peanut-ui#413
File: src/context/tokenSelector.context.tsx:118-123
Timestamp: 2024-11-12T09:39:20.720Z
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.

@jjramirezn jjramirezn force-pushed the feat/remember-selected-address branch from 258e5ad to c88869d Compare December 4, 2024 11:29
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: 0

🧹 Outside diff range and nitpick comments (1)
src/components/Create/Link/Confirm.view.tsx (1)

213-221: Consider moving preferences update after all operations

While the code correctly updates user preferences with proper null checks, consider moving this update after refetchBalances to ensure all operations complete successfully before persisting the preferences.

-            if (selectedChainID && selectedTokenAddress && selectedTokenDecimals) {
-                updateUserPreferences({
-                    lastUsedToken: {
-                        chainId: selectedChainID,
-                        address: selectedTokenAddress,
-                        decimals: selectedTokenDecimals,
-                    },
-                })
-            }
-
             onNext()
-            refetchBalances(address ?? '')
+            await refetchBalances(address ?? '')
+            
+            if (selectedChainID && selectedTokenAddress && selectedTokenDecimals) {
+                updateUserPreferences({
+                    lastUsedToken: {
+                        chainId: selectedChainID,
+                        address: selectedTokenAddress,
+                        decimals: selectedTokenDecimals,
+                    },
+                })
+            }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 258e5ad and c88869d.

📒 Files selected for processing (4)
  • src/components/Create/Link/Confirm.view.tsx (2 hunks)
  • src/context/tokenSelector.context.tsx (2 hunks)
  • src/context/walletContext/walletContext.tsx (3 hunks)
  • src/utils/general.utils.ts (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/utils/general.utils.ts
  • src/context/walletContext/walletContext.tsx
  • src/context/tokenSelector.context.tsx
🔇 Additional comments (1)
src/components/Create/Link/Confirm.view.tsx (1)

13-13: LGTM: Import change aligns with preference management refactoring

The rename from updatePeanutPreferences to updateUserPreferences is consistent with the broader refactoring of the preferences management system.

Copy link
Contributor

@Hugo0 Hugo0 left a comment

Choose a reason for hiding this comment

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

I think this is great!

@Hugo0 Hugo0 merged commit 679d3a0 into peanut-wallet Dec 4, 2024
4 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Mar 21, 2025
@Hugo0 Hugo0 deleted the feat/remember-selected-address branch July 3, 2025 18:22
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.

2 participants