Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/delete custom tokens #560

Merged
merged 4 commits into from
Nov 26, 2024
Merged

Feat/delete custom tokens #560

merged 4 commits into from
Nov 26, 2024

Conversation

gamalielhere
Copy link
Contributor

@gamalielhere gamalielhere commented Nov 19, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a method to remove custom ERC20 tokens from the network.
    • Enhanced asset detail view to allow deletion of custom tokens with a warning.
    • Improved token symbol display with tooltips for long symbols.
    • Added functionality to fetch and manage custom tokens based on the selected network.
  • Bug Fixes

    • Adjusted filtering logic for custom tokens to ensure accurate display and management.
  • Improvements

    • Streamlined logic for handling asset balances and market data.
    • Enhanced user interface for better adaptability and readability.

Copy link

coderabbitai bot commented Nov 19, 2024

Walkthrough

The changes in this pull request introduce several enhancements across multiple components related to token management in a blockchain application. A new method removeErc20Token is added for removing custom ERC20 tokens, while the EvmNetwork class sees improvements in token handling and formatting. The asset-detail-view component gains conditional rendering for custom tokens, and the network-assets-item component is updated to support fetching and managing custom tokens. The updates aim to improve the user interface and maintainability of the code.

Changes

File Path Change Summary
packages/extension/src/libs/tokens-state/index.ts Added method async removeErc20Token(chainName: NetworkNames, address: string): Promise<boolean> to TokensState class for removing custom ERC20 tokens. Minor formatting changes to addErc20Token method.
packages/extension/src/providers/ethereum/types/evm-network.ts Updated EvmNetwork class and EvmNetworkOptions interface. Enhanced getAllTokenInfo method for better asset handling and formatting. Adjusted customTokens filtering logic for clarity.
packages/extension/src/ui/action/views/asset-detail-view/index.vue Introduced conditional rendering for custom tokens, added props isCustomToken and removeToken, and updated template structure to include delete action for custom tokens.
packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue Enhanced display logic for token symbols with conditional rendering and tooltip for long symbols. Adjusted CSS for layout improvements.
packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue Added prop network, computed property isCustomToken, and methods removeToken and fetchCustomTokens. Updated template to bind new properties for better token management.
packages/extension/src/ui/action/views/network-assets/index.vue Added prop :network to network-assets-item component and an event listener @update:tokens. Updated addCustomAsset method to refresh asset list after adding a custom asset.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AssetDetailView
    participant TokensState
    participant NetworkAssetsItem

    User->>AssetDetailView: Request to delete custom token
    AssetDetailView->>TokensState: removeErc20Token(chainName, address)
    TokensState-->>AssetDetailView: Promise<boolean>
    AssetDetailView->>NetworkAssetsItem: Emit update:tokens
    NetworkAssetsItem->>NetworkAssetsItem: Fetch updated tokens
Loading

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.

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

github-actions bot commented Nov 19, 2024

💼 Build Files
chrome: enkrypt-chrome-7e6b3b09.zip
firefox: enkrypt-firefox-7e6b3b09.zip

💉 Virus total analysis
chrome: 7e6b3b09
firefox: 7e6b3b09

Copy link

@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: 6

🧹 Outside diff range and nitpick comments (7)
packages/extension/src/libs/tokens-state/index.ts (1)

63-66: Consider adding input validation for the address parameter.

The method could benefit from validating the address format before processing.

Consider adding validation:

 async removeErc20Token(
   chainName: NetworkNames,
   address: string,
 ): Promise<boolean> {
+  if (!address || !/^0x[a-fA-F0-9]{40}$/.test(address)) {
+    return false;
+  }
   const state: IState | null = await this.storage.get(StorageKeys.customTokens);
packages/extension/src/ui/action/views/network-assets/index.vue (1)

Line range hint 1-224: Consider architectural improvements for better maintainability.

While the current implementation works, consider these future improvements:

  1. Extract token management logic into a composable
  2. Add error handling for token operations
  3. Add loading states for async token operations
  4. Consider using Vuex/Pinia for state management if token state is used across multiple components

This would improve maintainability and make the component more focused on UI rendering.

packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue (1)

144-146: Consider adding loading state management.

The async operation could benefit from a loading state to improve UX and prevent potential UI flickers.

+const isLoading = ref(false);
 onMounted(async () => {
+  isLoading.value = true;
   await fetchCustomTokens();
+  isLoading.value = false;
 });
packages/extension/src/ui/action/views/asset-detail-view/index.vue (1)

329-333: Enhance warning label visibility and fix layout

The warning label styling could be more prominent given its importance, and the negative margins might cause layout issues.

Consider these style improvements:

 &__action {
-  margin: 0 0 -12px -12px;
-  width: calc(~'100% + 24px');
+  margin: 0 0 12px 0;
+  padding: 0 12px;
   text-align: center;

   .label {
     color: @secondaryLabel;
+    display: block;
+    margin-top: 8px;
+    padding: 8px;
+    background-color: fade(@warning, 10%);
+    border-radius: 4px;
+    font-weight: 500;
   }
 }
packages/extension/src/providers/ethereum/types/evm-network.ts (1)

213-213: Consider using a more robust address comparison method.

While the current case-insensitive comparison works, consider using the network's isAddress method and checksum addresses for a more robust comparison. This would align with Ethereum's address handling best practices.

Here's a suggested improvement:

-a.contract.toLowerCase() === (token as CustomErc20Token).address.toLowerCase()
+this.isAddress(a.contract) && this.isAddress((token as CustomErc20Token).address) &&
+toChecksumAddress(a.contract) === toChecksumAddress((token as CustomErc20Token).address)
packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue (2)

50-57: LGTM! Consider extracting the truncation logic.

The conditional rendering and truncation of long token symbols with tooltip is well implemented. However, since similar truncation logic is used for both token name and symbol, consider extracting it into a reusable computed property or method.

+ const truncateText = (text: string, limit = 16) => ({
+   shouldTruncate: text.length > limit,
+   truncated: `${text.slice(0, 12)}...`,
+   original: text
+ });

Line range hint 1-1: Consider adding token deletion capability

Given that this PR is about deleting custom tokens (Feat/delete custom tokens), consider adding token deletion functionality to this component, possibly through a delete button in the token info section when viewing existing tokens.

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b6e5f6d and fd6b474.

📒 Files selected for processing (6)
  • packages/extension/src/libs/tokens-state/index.ts (2 hunks)
  • packages/extension/src/providers/ethereum/types/evm-network.ts (2 hunks)
  • packages/extension/src/ui/action/views/asset-detail-view/index.vue (3 hunks)
  • packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue (3 hunks)
  • packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue (4 hunks)
  • packages/extension/src/ui/action/views/network-assets/index.vue (2 hunks)
🧰 Additional context used
🪛 Biome
packages/extension/src/libs/tokens-state/index.ts

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (11)
packages/extension/src/libs/tokens-state/index.ts (2)

38-38: LGTM!

The formatting change improves readability while maintaining the same functionality.


57-93: Well-implemented token removal functionality!

The implementation is thorough, handling edge cases like empty token arrays and cleaning up empty networks.

🧰 Tools
🪛 Biome

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

packages/extension/src/ui/action/views/network-assets/index.vue (1)

21-22: LGTM! Well-structured component communication.

The addition of the network prop and update:tokens event handler follows Vue.js best practices for parent-child component communication, enabling proper token management functionality.

packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue (3)

54-56: LGTM: Template changes properly integrate custom token management.

The new props are correctly bound to the asset-detail-view component, enabling custom token management functionality.


62-64: LGTM: Imports are properly structured.

The necessary imports for types and functionality are correctly added.

Also applies to: 74-74


84-87: Consider handling undefined network properties.

While the prop type is correctly defined, the empty object default value might lead to runtime errors if code assumes network properties exist without validation.

packages/extension/src/ui/action/views/asset-detail-view/index.vue (1)

72-72: Verify component integration

Let's verify the integration with network-assets-item.vue and other related components.

Also applies to: 88-95

✅ Verification successful

Component integration is properly implemented

The integration between components is correctly implemented with proper prop passing and event handling:

  • BaseButton is properly imported and used within asset-detail-view for the delete action
  • network-assets-item correctly imports and uses asset-detail-view with all required props:
    • token
    • isCustomToken
    • removeToken
    • close event handling
  • The custom token deletion UI is conditionally rendered based on isCustomToken prop
  • Props are properly typed and have appropriate defaults
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check component integration and event handling

# Check for removeToken event handlers
echo "Checking for removeToken event handlers..."
rg -l "removeToken" --type vue

# Check for isCustomToken usage
echo "Checking for isCustomToken usage..."
rg -l "isCustomToken" --type vue

# Check for related components and their interactions
echo "Checking for related component imports..."
rg -l "asset-detail-view" --type vue

Length of output: 453


Script:

#!/bin/bash
# Let's try a different approach without file type filtering

# Check for removeToken event handlers
echo "Checking for removeToken event handlers..."
rg -l "removeToken"

# Check for isCustomToken usage
echo "Checking for isCustomToken usage..."
rg -l "isCustomToken"

# Check for related component imports and usage
echo "Checking for related component imports..."
rg -l "asset-detail-view"

# Check for BaseButton usage in the component
echo "Checking BaseButton usage in the component..."
rg -C 3 "BaseButton" "packages/extension/src/ui/action/views/asset-detail-view/index.vue"

# Check for network-assets-item references
echo "Checking network-assets-item references..."
rg -l "network-assets-item"

Length of output: 1503


Script:

#!/bin/bash
# Let's examine the actual integration between these components

# Check how BaseButton is used in asset-detail-view
echo "Checking BaseButton usage context..."
rg -C 10 "BaseButton" packages/extension/src/ui/action/views/asset-detail-view/index.vue

# Check the interaction between asset-detail-view and network-assets-item
echo "Checking removeToken implementation in asset-detail-view..."
rg -C 10 "removeToken" packages/extension/src/ui/action/views/asset-detail-view/index.vue

# Check how network-assets-item uses asset-detail-view
echo "Checking asset-detail-view usage in network-assets-item..."
rg -C 10 "asset-detail-view" packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue

# Check isCustomToken implementation
echo "Checking isCustomToken implementation..."
rg -C 5 "isCustomToken" packages/extension/src/ui/action/views/asset-detail-view/index.vue

Length of output: 4637

packages/extension/src/providers/ethereum/types/evm-network.ts (2)

160-160: LGTM!

The indentation change improves code readability while maintaining the same functionality.


Line range hint 1-284: Verify integration with token deletion functionality.

Given that this file handles custom token management and the PR's objective is to implement token deletion, let's verify the integration between this file and the token deletion functionality.

✅ Verification successful

Token deletion functionality is properly integrated

The verification shows a complete and well-integrated token deletion implementation:

  1. TokensState class provides the core removeErc20Token method that handles token deletion from storage
  2. UI components properly integrate this functionality:
    • network-assets-item.vue implements the deletion trigger and updates the token list
    • asset-detail-view.vue provides the deletion UI with appropriate user warning

The file under review correctly uses TokensState for managing custom tokens and properly integrates with the deletion functionality through the getAllTokenInfo method, which filters out deleted tokens from the displayed list.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for token deletion related code and its integration

# Look for token deletion related methods
echo "Searching for token deletion related methods..."
rg -l "removeToken|deleteToken|removeErc20Token"

# Look for files that import TokensState and use deletion methods
echo "Checking TokensState usage..."
ast-grep --pattern 'import { TokensState } from "@/libs/tokens-state"'

# Look for UI components that might trigger token deletion
echo "Checking UI components..."
fd -e vue -e ts -x rg -l "removeToken|deleteToken|removeErc20Token" {}

Length of output: 851


Script:

#!/bin/bash
# Let's examine the token deletion implementation and its integration

# Check the implementation in tokens-state
echo "Checking TokensState implementation..."
rg -A 10 "removeToken|deleteToken" packages/extension/src/libs/tokens-state/index.ts

# Check UI components that trigger deletion
echo "Checking network-assets-item.vue implementation..."
rg -A 10 "removeToken|deleteToken" packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue

echo "Checking asset-detail-view implementation..."
rg -A 10 "removeToken|deleteToken" packages/extension/src/ui/action/views/asset-detail-view/index.vue

# Check if TokensState is properly imported in the UI components
echo "Checking TokensState imports in UI..."
ast-grep --pattern 'import { TokensState } from "@/libs/tokens-state"' packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue packages/extension/src/ui/action/views/asset-detail-view/index.vue

Length of output: 2122


Script:

#!/bin/bash
# Let's check the TokensState implementation since it wasn't shown in previous results

echo "Examining TokensState class implementation..."
cat packages/extension/src/libs/tokens-state/index.ts

# Also check for any tests related to token deletion
echo "Checking for related tests..."
fd -e spec.ts -e test.ts -x rg -l "removeToken|deleteToken" {}

Length of output: 3087

packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue (2)

432-436: LGTM! Style changes improve layout.

The switch to flex display and consistent font sizing enhances the token info layout and maintains visual harmony.


289-289: Verify content fits after height reduction

The container height has been reduced significantly from 568px to 385px. Please ensure that all content (including error states and warnings) fits properly within the reduced height without overflow or scrollbars.

✅ Verification successful

Let me generate additional scripts to verify the content structure and potential overflow issues.


Height reduction is appropriate and content fits properly

After analyzing the template structure and styles, the height reduction from 568px to 385px is appropriate because:

  • The layout has a fixed structure with predictable content heights:
    • Header (68px - padding + content)
    • Contract input (64px)
    • Token info/error section (~100px)
    • Warning message (~80px)
    • Bottom buttons section (~57px)
  • All content sections have proper spacing and no scrollable areas
  • Error and warning states are accommodated within the new height
  • The component uses absolute positioning for buttons at the bottom
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other height-related styles or potential overflow issues
rg -g '*.vue' -g '*.less' 'height:|overflow:|max-height:' packages/extension/src/ui/action/views/network-assets/

Length of output: 3924


Script:

#!/bin/bash
# Check the template structure and content elements in custom-evm-token.vue
cat packages/extension/src/ui/action/views/network-assets/components/custom-evm-token.vue

Length of output: 12804

Copy link

@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 (2)
packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue (2)

84-87: Consider a more type-safe default value for the network prop

The empty object default value might not satisfy the BaseNetwork type requirements. Consider either making the prop required or providing a proper default value that matches the BaseNetwork interface.

   network: {
     type: Object as PropType<BaseNetwork>,
-    default: () => ({}),
+    required: true,
   },

133-150: Consider using provide/inject for TokensState

The TokensState instance could be provided at a higher level component and injected here, following Vue's dependency injection pattern. This would:

  1. Prevent multiple instances of TokensState
  2. Make it easier to mock for testing
  3. Follow the single responsibility principle

Also, consider handling component unmount during fetch.

-const tokenState = new TokensState();
+const tokenState = inject('tokenState') as TokensState;
+if (!tokenState) throw new Error('TokensState not provided');

 const fetchCustomTokens = async () => {
+  const controller = new AbortController();
   try {
-    return await tokenState.getTokensByNetwork(props.network.name).then(res => {
+    return await tokenState.getTokensByNetwork(props.network.name, { signal: controller.signal }).then(res => {
       customTokens.value = res.filter(
         (token): token is CustomErc20Token => 'address' in token,
       );
     });
   } catch {
     customTokens.value = [];
   }
+  return () => controller.abort();
 };

 onMounted(async () => {
-  await fetchCustomTokens();
+  const cleanup = await fetchCustomTokens();
+  onUnmounted(cleanup);
 });
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between fd6b474 and a030dc6.

📒 Files selected for processing (2)
  • packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue (4 hunks)
  • packages/extension/src/ui/action/views/network-assets/index.vue (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/extension/src/ui/action/views/network-assets/index.vue
🔇 Additional comments (3)
packages/extension/src/ui/action/views/network-assets/components/network-assets-item.vue (3)

54-56: LGTM: Template props are correctly bound

The new props are properly bound to the asset-detail-view component using the correct Vue syntax.


152-158: LGTM: Robust implementation of isCustomToken

The computed property correctly:

  • Guards against undefined contract
  • Performs case-insensitive address comparison
  • Uses proper type narrowing with the some() predicate

164-173: **** The past review comment about error handling in the removeToken method is still valid and applicable.

@NickKelly1 NickKelly1 self-requested a review November 26, 2024 19:23
Copy link

@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)
packages/extension/src/libs/tokens-state/index.ts (1)

63-93: Consider improving null safety and defensive programming

While the implementation is solid, there are a few improvements that could make it more robust:

  1. Use optional chaining for safer null handling
  2. Add defensive checks for the tokens array

Here's a suggested improvement:

  async removeErc20Token(
    chainName: NetworkNames,
    address: string,
  ): Promise<boolean> {
    const state: IState | null = await this.storage.get(StorageKeys.customTokens);
-    if (state && state[chainName]) {
-      const tokens = state[chainName];
+    const tokens = state?.[chainName];
+    if (tokens?.length) {
-      for (let i = 0; i < tokens!.length; i++) {
-        const token = tokens![i];
+      for (let i = 0; i < tokens.length; i++) {
+        const token = tokens[i];

        if (
          token.type === TokenType.ERC20 &&
          (token as CustomErc20Token).address.toLowerCase() ===
          address.toLowerCase()
        ) {
-          tokens!.splice(i, 1);
+          tokens.splice(i, 1);

-          if (tokens!.length === 0) {
+          if (tokens.length === 0 && state) {
            delete state[chainName];
          }

          await this.storage.set(StorageKeys.customTokens, state);
          return true;
        }
      }
    }

    return false;
  }
🧰 Tools
🪛 Biome (1.9.4)

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a030dc6 and 7e6b3b0.

📒 Files selected for processing (1)
  • packages/extension/src/libs/tokens-state/index.ts (2 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/extension/src/libs/tokens-state/index.ts

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

Unsafe fix: Change to an optional chain.

(lint/complexity/useOptionalChain)

🔇 Additional comments (2)
packages/extension/src/libs/tokens-state/index.ts (2)

38-38: LGTM!

The formatting change in the address comparison maintains the same functionality while improving code readability.


86-86: Missing await keyword

The storage operation should be awaited.

@gamalielhere gamalielhere merged commit 89fb017 into develop Nov 26, 2024
3 of 4 checks passed
@gamalielhere gamalielhere deleted the feat/delete-custom-tokens branch November 26, 2024 21:29
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.

3 participants