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: Reorganize Wallet PopUp #945

Merged
merged 2 commits into from
Nov 13, 2024

Conversation

Villarley
Copy link
Contributor

@Villarley Villarley commented Nov 11, 2024

Added the function sortConnectors and applied logic to display available connectors first, followed by unavailable ones.

Pull Request type

  • Feature

Resolves: #932

Summary of Changes

  • Added the sortConnectors function to sort connectors based on availability, moving unavailable connectors (e.g., Okx Wallet, Bitget Wallet if not installed) to the end of the list.
  • Updated the Navbar component to utilize the sorted connectors for a more intuitive wallet selection experience.
  • Verified compatibility between @starknet-react/core and starknetkit.

feature
testnet

Summary by CodeRabbit

  • New Features

    • Introduced sorting functionality for connectors in the Navbar, enhancing the user experience by prioritizing available connectors.
  • Bug Fixes

    • Improved the handling of connector availability, ensuring a more intuitive display order.
  • Tests

    • Added a comprehensive test suite for the new sorting functionality to ensure reliability and correct behavior.

Added the function sortConnectors and applied logic to display available connectors first, followed by unavailable ones.
Copy link

vercel bot commented Nov 11, 2024

@Villarley is attempting to deploy a commit to the LFG Labs Team on Vercel.

A member of the Team first needs to authorize it.

Copy link
Contributor

coderabbitai bot commented Nov 11, 2024

Walkthrough

The pull request introduces a new utility function, sortConnectors, in the utils/connectors.ts file, which sorts an array of connector objects based on their availability. The Navbar component is modified to use this new function, replacing the original availableConnectors with the sorted array, sortedConnectors. Additionally, a test suite for sortConnectors is added in tests/utils/connectors.test.js to validate its functionality across various scenarios.

Changes

File Change Summary
components/UI/navbar.tsx Modified to use sortConnectors for sorting connectors before passing to useStarknetkitConnectModal.
utils/connectors.ts Added new function sortConnectors to sort connectors based on availability and predefined order.
tests/utils/connectors.test.js Introduced a test suite for sortConnectors with multiple test cases covering various sorting scenarios.

Assessment against linked issues

Objective Addressed Explanation
Reorganized wallet pop-up to show uninstalled wallets last (#932)

Possibly related PRs

  • update provider.tsx #944: The changes in app/provider.tsx involve modifications to the availableConnectors array, which is directly related to the sortConnectors function's purpose of processing connectors in the main PR.

Suggested reviewers

  • fricoben

Warning

There were issues while running some tools. Please review the errors and either fix the tool’s configuration or disable the tool if it’s a critical failure.

🔧 eslint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/UI/navbar.tsx

Oops! Something went wrong! :(

ESLint: 9.14.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.


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

🧹 Outside diff range and nitpick comments (1)
utils/sorts.ts (1)

3-6: Add input validation for robustness

While the function signature is well-typed, it would be more robust with input validation.

Consider adding validation:

 export const sortConnectors = (connectors: Connector[]): Connector[] => {
+  if (!connectors?.length) {
+    return [];
+  }
   const available: Connector[] = [];
   const notAvailable: Connector[] = [];
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between b7f9491 and ba9c3d9.

📒 Files selected for processing (2)
  • components/UI/navbar.tsx (3 hunks)
  • utils/sorts.ts (1 hunks)
🔇 Additional comments (5)
utils/sorts.ts (2)

1-2: LGTM: Clean import statement

The import is correctly typed and aligns with the starknetkit integration mentioned in the PR objectives.


1-24: Verify integration with Navbar component

The implementation aligns well with the PR objectives. Let's verify its integration with the Navbar component.

✅ Verification successful

Let me gather more context about the integration by checking the complete implementation of the navbar component.


Let me check the source of availableConnectors to complete the verification.


Integration verified successfully

The sortConnectors function is properly integrated in the Navbar component:

  • It's correctly imported and used to sort the availableConnectors from the provider
  • The sorted connectors are passed to useStarknetkitConnectModal hook
  • The implementation maintains the wallet connection functionality while adding the desired sorting behavior
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify the integration of sortConnectors in the Navbar component

# Search for usage of sortConnectors in the codebase
echo "Checking usage of sortConnectors:"
rg -l "sortConnectors"

# Look for Navbar component implementation
echo "\nChecking Navbar implementation:"
rg -A 5 "useStarknetkitConnectModal" "components/"

Length of output: 1109


Script:

#!/bin/bash
# Get the complete implementation of navbar.tsx to verify sortConnectors integration
echo "Complete navbar implementation:"
cat components/UI/navbar.tsx

# Check if sortedConnectors is properly initialized
echo "\nChecking sortedConnectors initialization:"
rg -B 5 -A 2 "sortedConnectors" components/UI/navbar.tsx

Length of output: 12490


Script:

#!/bin/bash
# Check the implementation of availableConnectors
echo "Checking availableConnectors source:"
rg -B 2 -A 2 "availableConnectors" "app/"

# Check if there are any other files importing availableConnectors
echo "\nChecking availableConnectors imports:"
rg -l "availableConnectors"

Length of output: 1454

components/UI/navbar.tsx (3)

29-29: LGTM: Clean import statement

The import of sortConnectors from @utils/sorts is properly placed with other utility imports.


57-60: Verify connector sorting behavior

The sorting logic needs verification to ensure it properly handles all connector states and edge cases.

Let's verify the connector sorting implementation:

✅ Verification successful

Let me check the implementation of the sorting function to verify its behavior.


Sorting implementation is robust with proper handling of connector states

The sortConnectors implementation is well-structured and handles the key scenarios:

  • Separates available and unavailable connectors
  • Places all available connectors first
  • Sorts unavailable connectors in a specific order (okxwallet, bitkeep)
  • Handles edge cases by using array methods that work with empty arrays
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Find and analyze the sortConnectors implementation
ast-grep --pattern 'export function sortConnectors($$$)'

# Check for any existing tests of the sorting logic
fd -e test.ts -e spec.ts -e test.tsx -e spec.tsx | xargs rg "sortConnectors"

Length of output: 385


Script:

#!/bin/bash
# Get the implementation of sortConnectors
cat utils/sorts.ts

Length of output: 647


57-60: 🛠️ Refactor suggestion

Verify type safety of connector casting

The implementation looks functionally correct, but there are two concerns:

  1. The type casting as any suggests potential type safety issues that should be addressed.
  2. The sorting is performed on component render which could be optimized.

Consider these improvements:

- const sortedConnectors = sortConnectors(availableConnectors);
+ const sortedConnectors = useMemo(
+   () => sortConnectors(availableConnectors),
+   [availableConnectors]
+ );

  const { starknetkitConnectModal } = useStarknetkitConnectModal({
-   connectors: sortedConnectors as any,
+   connectors: sortedConnectors,
  });

Let's verify the connector types:

✅ Verification successful

Let me gather more information about the connector types and their usage.


Let me try a different approach to gather information about the types and implementations.


Let me try one final time without specifying the file type.


Based on the gathered information, I can now provide the final response:

Type casting is necessary, performance optimization is valid

The as any type casting in useStarknetkitConnectModal is actually necessary because:

  1. The sortConnectors function correctly returns Connector[] from starknetkit
  2. The hook appears to have slightly different type expectations from the starknet-react/core Connector type

The performance optimization suggestion using useMemo is valid since sortConnectors performs array operations on every render.

  • utils/sorts.ts: Implements sortConnectors with proper typing
  • Multiple files show consistent use of type casting between connector types
  • The type casting pattern is used consistently across the codebase in similar scenarios
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check the Connector type definitions in the codebase
rg -A 3 "type.*Connector.*=|interface.*Connector.*{" 

# Check usage of type casting in connector-related code
rg "as any.*Connector|as Connector"

Length of output: 688


Script:

#!/bin/bash
# Check type definitions with fixed regex
rg -A 3 "type.*Connector|interface.*Connector"

# Check sortConnectors implementation
ast-grep --pattern 'function sortConnectors'

# Check starknetkitConnectModal hook type
rg -A 3 "useStarknetkitConnectModal.*="

Length of output: 137


Script:

#!/bin/bash
# Search for connector-related imports and type definitions
rg -A 2 "import.*Connector|type.*Connector" --type typescript

# Find sortConnectors implementation with different pattern
rg -A 5 "sortConnectors.*=" --type typescript

# Look for starknetkitConnectModal related code
rg -A 3 "starknetkitConnectModal" --type typescript

Length of output: 268


Script:

#!/bin/bash
# Search for connector-related imports and type definitions
rg -A 2 "import.*Connector|type.*Connector"

# Find sortConnectors implementation
rg -A 5 "const sortConnectors|function sortConnectors"

# Look for starknetkitConnectModal related code and types
rg -A 3 "starknetkitConnectModal|useStarknetkitConnectModal"

# Check the specific file content
cat components/UI/navbar.tsx

Length of output: 15977

utils/sorts.ts Outdated Show resolved Hide resolved
utils/sorts.ts Outdated
Comment on lines 16 to 24
return [
...available,
// Reorganized not available connectors
...notAvailable.sort((a, b) => {
const order = ["okxwallet", "bitkeep"]; // desired order
return order.indexOf(a.id) - order.indexOf(b.id);
}),
];
};
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

Improve sorting configuration and handle unknown connectors

The current implementation has two potential issues:

  1. The order array is hardcoded and not configurable
  2. Connectors not in the order array will be sorted incorrectly (both will return -1 from indexOf)

Consider this improved implementation:

+const DEFAULT_ORDER = ["okxwallet", "bitkeep"];
+
 export const sortConnectors = (connectors: Connector[]): Connector[] => {
   const available: Connector[] = [];
   const notAvailable: Connector[] = [];
+  const order = DEFAULT_ORDER;

   // Rest of the code...

   return [
     ...available,
     ...notAvailable.sort((a, b) => {
-      const order = ["okxwallet", "bitkeep"]; // desired order
-      return order.indexOf(a.id) - order.indexOf(b.id);
+      const indexA = order.indexOf(a.id);
+      const indexB = order.indexOf(b.id);
+      // If neither connector is in the order array, maintain their relative position
+      if (indexA === -1 && indexB === -1) return 0;
+      // If only one connector is in the order array, prioritize it
+      if (indexA === -1) return 1;
+      if (indexB === -1) return -1;
+      // Both connectors are in the order array, sort by their index
+      return indexA - indexB;
     }),
   ];
 };
📝 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
return [
...available,
// Reorganized not available connectors
...notAvailable.sort((a, b) => {
const order = ["okxwallet", "bitkeep"]; // desired order
return order.indexOf(a.id) - order.indexOf(b.id);
}),
];
};
const DEFAULT_ORDER = ["okxwallet", "bitkeep"];
return [
...available,
...notAvailable.sort((a, b) => {
const indexA = order.indexOf(a.id);
const indexB = order.indexOf(b.id);
// If neither connector is in the order array, maintain their relative position
if (indexA === -1 && indexB === -1) return 0;
// If only one connector is in the order array, prioritize it
if (indexA === -1) return 1;
if (indexB === -1) return -1;
// Both connectors are in the order array, sort by their index
return indexA - indexB;
}),
];
};

Copy link
Contributor

@fricoben fricoben left a comment

Choose a reason for hiding this comment

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

Test your function :)

utils/sorts.ts Outdated
@@ -0,0 +1,24 @@
import { Connector } from "starknetkit";
Copy link
Contributor

Choose a reason for hiding this comment

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

rename the file connectors.ts, we'll reuse it later for connectors utils

utils/sorts.ts Outdated
return order.indexOf(a.id) - order.indexOf(b.id);
}),
];
};
Copy link
Contributor

Choose a reason for hiding this comment

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

you need to create a connector.test.js function to test your util and make sur it covers all hedge cases here :)

@fricoben fricoben added the ❌ Change request Change requested from reviewer label Nov 12, 2024
@Villarley Villarley marked this pull request as draft November 12, 2024 13:09
- Updated function import at the navbar file.
- Created connectors.test.js for testing the util function.
- Renamed the file to "connectors.ts"
@Villarley Villarley marked this pull request as ready for review November 12, 2024 13:45
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)
utils/connectors.ts (2)

3-6: Add JSDoc documentation for better maintainability

Consider adding JSDoc documentation to describe the function's purpose, parameters, and return value.

+/**
+ * Sorts wallet connectors by availability, placing available connectors first,
+ * followed by unavailable ones in a specific order.
+ * @param connectors - Array of wallet connectors to sort
+ * @returns Sorted array of connectors with available ones first
+ */
 export const sortConnectors = (connectors: Connector[]): Connector[] => {

7-14: Consider using filter for more functional approach and add input validation

The current implementation could be improved for robustness and maintainability.

-  // Sort connectors 
-  connectors.forEach((connector) => {
-    if (connector.available()) {
-      available.push(connector);
-    } else {
-      notAvailable.push(connector);
-    }
-  });
+  if (!Array.isArray(connectors)) {
+    throw new Error('Input must be an array of connectors');
+  }
+
+  // Sort connectors into available and unavailable
+  const available = connectors.filter(connector => connector.available());
+  const notAvailable = connectors.filter(connector => !connector.available());
tests/utils/connectors.test.js (1)

13-58: Consider adding tests for edge cases

While the current test coverage is good, consider adding the following test cases to improve robustness:

  1. Verify that the original array remains unmodified (pure function)
  2. Handle null/undefined input
  3. Validate connector object structure
  4. Test order preservation within same-availability groups

Here's a suggested implementation:

it("should not modify the original array", () => {
  const connectors = [
    new MockConnector("okx", "Okx Wallet", false),
    new MockConnector("braavos", "Braavos", true),
  ];
  const originalConnectors = [...connectors];
  
  sortConnectors(connectors);
  
  expect(connectors).toEqual(originalConnectors);
});

it("should handle invalid input gracefully", () => {
  expect(sortConnectors(null)).toEqual([]);
  expect(sortConnectors(undefined)).toEqual([]);
});

it("should validate connector structure", () => {
  const invalidConnectors = [
    { id: "test", name: "Test" }, // missing available method
  ];
  
  expect(() => sortConnectors(invalidConnectors)).toThrow();
});

it("should preserve order within same-availability group", () => {
  const connectors = [
    new MockConnector("wallet1", "Wallet 1", true),
    new MockConnector("wallet2", "Wallet 2", true),
  ];
  const sortedConnectors = sortConnectors([...connectors]);
  
  expect(sortedConnectors[0].id).toBe(connectors[0].id);
  expect(sortedConnectors[1].id).toBe(connectors[1].id);
});
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ba9c3d9 and 479ad68.

📒 Files selected for processing (3)
  • components/UI/navbar.tsx (3 hunks)
  • tests/utils/connectors.test.js (1 hunks)
  • utils/connectors.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/UI/navbar.tsx
🔇 Additional comments (4)
utils/connectors.ts (2)

1-24: Verify integration with Navbar and test coverage

Since this is a critical feature affecting wallet connectivity, let's verify:

  1. Integration with Navbar component
  2. Test coverage for all scenarios
#!/bin/bash
# Check Navbar integration
echo "Checking Navbar integration:"
rg --type tsx "sortConnectors.*availableConnectors" -A 5

# Check test coverage
echo -e "\nChecking test coverage:"
fd -e test.ts -e test.tsx -e spec.ts -e spec.tsx . | grep -i "connector"

1-1: Verify starknetkit version compatibility

The PR objectives mention verification of compatibility between @starknet-react/core and starknetkit. Let's ensure we're using a compatible version.

tests/utils/connectors.test.js (2)

1-11: LGTM! Clean mock implementation

The MockConnector class effectively simulates the connector interface with the necessary properties and methods.


13-28: LGTM! Well-structured test cases

The test suite provides good coverage of the main sorting functionality with clear test descriptions and realistic test data.

Comment on lines +16 to +24
return [
...available,
// Reorganized not available connectors
...notAvailable.sort((a, b) => {
const order = ["okxwallet", "bitkeep"]; // desired order
return order.indexOf(a.id) - order.indexOf(b.id);
}),
];
};
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

Improve robustness of connector ordering logic

The current implementation has several potential issues:

  1. The order array is hardcoded and should be configurable
  2. The sorting logic doesn't handle connectors that aren't in the order array
  3. No type safety for connector IDs

Consider this improved implementation:

+const WALLET_ORDER = ["okxwallet", "bitkeep"] as const;
+type KnownWalletId = typeof WALLET_ORDER[number];
+
 export const sortConnectors = (connectors: Connector[]): Connector[] => {
   // ... previous code ...

   return [
     ...available,
-    // Reorganized not available connectors
     ...notAvailable.sort((a, b) => {
-      const order = ["okxwallet", "bitkeep"]; // desired order
-      return order.indexOf(a.id) - order.indexOf(b.id);
+      const aIndex = WALLET_ORDER.indexOf(a.id as KnownWalletId);
+      const bIndex = WALLET_ORDER.indexOf(b.id as KnownWalletId);
+      
+      // If neither wallet is in the order array, maintain their relative position
+      if (aIndex === -1 && bIndex === -1) return 0;
+      // If only one wallet is in the order array, it should come first
+      if (aIndex === -1) return 1;
+      if (bIndex === -1) return -1;
+      // Both wallets are in the order array, sort by their index
+      return aIndex - bIndex;
     }),
   ];
 };
📝 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
return [
...available,
// Reorganized not available connectors
...notAvailable.sort((a, b) => {
const order = ["okxwallet", "bitkeep"]; // desired order
return order.indexOf(a.id) - order.indexOf(b.id);
}),
];
};
const WALLET_ORDER = ["okxwallet", "bitkeep"] as const;
type KnownWalletId = typeof WALLET_ORDER[number];
return [
...available,
...notAvailable.sort((a, b) => {
const aIndex = WALLET_ORDER.indexOf(a.id as KnownWalletId);
const bIndex = WALLET_ORDER.indexOf(b.id as KnownWalletId);
// If neither wallet is in the order array, maintain their relative position
if (aIndex === -1 && bIndex === -1) return 0;
// If only one wallet is in the order array, it should come first
if (aIndex === -1) return 1;
if (bIndex === -1) return -1;
// Both wallets are in the order array, sort by their index
return aIndex - bIndex;
}),
];
};

@Villarley Villarley requested a review from fricoben November 12, 2024 18:33
Copy link

vercel bot commented Nov 13, 2024

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

Name Status Preview Comments Updated (UTC)
starknet-quest ✅ Ready (Inspect) Visit Preview 💬 Add feedback Nov 13, 2024 8:42am

Copy link
Contributor

@fricoben fricoben left a comment

Choose a reason for hiding this comment

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

lgtm

@fricoben fricoben merged commit d41593e into lfglabs-dev:testnet Nov 13, 2024
3 of 4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
❌ Change request Change requested from reviewer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Reorganized wallet pop-up to show uninstalled wallets last
2 participants