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

Automatically switch wallet network #275

Merged
merged 1 commit into from
Oct 28, 2024
Merged

Conversation

joshklop
Copy link
Collaborator

@joshklop joshklop commented Oct 27, 2024

Summary by CodeRabbit

  • New Features

    • Enhanced MetaMask integration for a more streamlined connection process.
    • Improved error handling for a better user experience when connecting to Ethereum chains.
  • Bug Fixes

    • Removed the button for adding the L1 chain to MetaMask, which may affect previous user interactions.
  • Refactor

    • Introduced a constant for chainId to improve code maintainability and consistency.
    • Updated connection process to be initiated automatically on page load.
    • Added a new instruction to reload the page after configuring the Monomer L1 Devnet wallet.

Copy link
Contributor

coderabbitai bot commented Oct 27, 2024

Walkthrough

The changes in this pull request involve modifications to the integration of MetaMask within the Monomer wallet application. The HTML structure of index.html has been updated by removing a button intended for adding the L1 chain to MetaMask. In the JavaScript file metamask-integration.js, enhancements have been made to the connection process, including the introduction of a chainId constant, improved error handling, and the removal of the event listener for the MetaMask button, which now allows for automatic connection on page load.

Changes

File Path Change Summary
cmd/monogen/testapp/wallet/index.html Removed button: <button id="enable-metamask">Add L1 Chain to MetaMask</button>
cmd/monogen/testapp/wallet/metamask-integration.js Introduced const chainId = "0x384"; initialized let optimismPortalContract = undefined; updated connectMetamask to call addL1ChainToMetaMask and switchToMonomerDevnet; refined error handling; removed event listener for enableMetamaskButton.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant WebPage
    participant MetaMask

    User->>WebPage: Load page
    WebPage->>MetaMask: Check for MetaMask
    MetaMask-->>WebPage: MetaMask installed
    WebPage->>MetaMask: Connect to MetaMask
    MetaMask-->>WebPage: Connection successful
    WebPage->>MetaMask: Switch to L1 Chain
    MetaMask-->>WebPage: Chain switched
Loading

🐰 "In the wallet where bunnies hop,
The MetaMask button took a drop.
With chains now linked, oh what a sight,
Connecting with ease, all feels just right!
A new path forged, so clear and bright,
Hopping along, we dance with delight!" 🐇

Possibly related PRs

  • Add keplr integration for L2 devnet chain #246: The changes in this PR involve enhancements to the MetaMask integration, which is directly related to the modifications made in the main PR regarding the MetaMask wallet integration instructions.
  • Move l1 address info to interact.md #265: This PR updates the interact.md documentation to include instructions for configuring L1 and L2 wallets, which aligns with the main PR's focus on the MetaMask integration and the removal of the button for adding the L1 chain to MetaMask.

Suggested reviewers

  • natebeauregard

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.

@joshklop joshklop marked this pull request as ready for review October 27, 2024 23:00
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 (2)
cmd/monogen/testapp/wallet/metamask-integration.js (2)

33-40: Consider more granular error handling.

The connection flow looks good, but consider handling errors from addL1ChainToMetaMask and switchToMonomerDevnet separately to provide more specific error messages to users.

 async function connectMetamask() {
   try {
     await window.ethereum.request({ method: 'eth_requestAccounts' });
     let provider = new ethers.providers.Web3Provider(window.ethereum);
     let signer = provider.getSigner();
     accountSpan.innerText = await signer.getAddress();

     optimismPortalContract = new ethers.Contract(
       optimismPortalAddress,
       optimismPortalAbi,
       signer
     );

-    await addL1ChainToMetaMask();
-    await switchToMonomerDevnet();
+    try {
+      await addL1ChainToMetaMask();
+    } catch (error) {
+      console.error("Error adding L1 chain:", error);
+      throw new Error("Failed to add L1 chain to MetaMask");
+    }
+
+    try {
+      await switchToMonomerDevnet();
+    } catch (error) {
+      console.error("Error switching to Monomer Devnet:", error);
+      throw new Error("Failed to switch to Monomer Devnet");
+    }

     console.log("Connected to MetaMask and contract instantiated.");
   } catch (error) {
     console.error("Error connecting to MetaMask:", error);
   }
 }

Line range hint 143-145: Consider user consent before auto-connecting.

While automatic connection improves UX, it's generally recommended to wait for explicit user interaction before connecting to their wallet. This approach:

  1. Follows web3 best practices
  2. Respects user privacy
  3. Prevents unexpected wallet popups

Consider implementing a connection button that's automatically clicked only if the user has previously connected (using localStorage to remember their preference).

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 63bbf2c and 8a70bf0.

📒 Files selected for processing (2)
  • cmd/monogen/testapp/wallet/index.html (0 hunks)
  • cmd/monogen/testapp/wallet/metamask-integration.js (2 hunks)
💤 Files with no reviewable changes (1)
  • cmd/monogen/testapp/wallet/index.html
🔇 Additional comments (2)
cmd/monogen/testapp/wallet/metamask-integration.js (2)

62-62: Consider security implications of hardcoded RPC URL.

The chainId update looks good, but the hardcoded localhost RPC URL might cause issues in production environments.

Let's check for other RPC URL references:

#!/bin/bash
# Search for RPC URL patterns
rg "rpcUrls|127\.0\.0\.1:9001|localhost:9001" --type js

12-14: LGTM! Verify chain ID for Monomer Devnet.

The initialization looks good. The chain ID is properly formatted as a hex string.

Let's verify if this chain ID is consistently used across the codebase:

✅ Verification successful

Chain ID 0x384 is correctly used for Monomer Devnet

The verification confirms that:

  • The chain ID 0x384 is consistently used in metamask-integration.js
  • It's properly identified as 'Ethereum (Monomer Devnet)' in the network configuration
  • This is separate from the L2 chain configuration in Keplr integration which uses a different chain ID as expected
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for any other chain ID references
rg -i "0x384|900" --type js

Length of output: 160


Script:

#!/bin/bash
# Let's search for chain configurations or network definitions
rg -i "chainid|network.*id|chain.*id" --type js -A 3

Length of output: 2419

Comment on lines +42 to +54
async function switchToMonomerDevnet() {
try {
await window.ethereum.request({
method: "wallet_switchEthereumChain",
params: [
{
chainId: chainId,
},
],
});
} catch (error) {
console.error("Error switching Ethereum chain: ", error);
}
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

Enhance error handling for chain switching.

The function should handle specific error codes, particularly 4902 (unrecognized chain), and provide user feedback through the status paragraph.

 async function switchToMonomerDevnet() {
   try {
     await window.ethereum.request({
       method: "wallet_switchEthereumChain",
       params: [{ chainId: chainId }],
     });
+    statusParagraph.innerText = 'Successfully switched to Monomer Devnet';
   } catch (error) {
-    console.error("Error switching Ethereum chain: ", error);
+    if (error.code === 4902) {
+      console.error("Unrecognized chain. Adding chain first...");
+      statusParagraph.innerText = 'Adding Monomer Devnet...';
+      await addL1ChainToMetaMask();
+      return switchToMonomerDevnet();
+    }
+    console.error("Error switching Ethereum chain:", error);
+    statusParagraph.innerText = `Failed to switch chain: ${error.message}`;
+    throw error;
   }
 }

Committable suggestion was skipped due to low confidence.

@joshklop joshklop force-pushed the joshklop.auto-switch-network branch from fd1ac47 to 8923c99 Compare October 28, 2024 20:06
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 (4)
cmd/monogen/testapp/wallet/index.html (2)

114-114: Consider clarifying the page reload instruction.

While adding the reload instruction is helpful, it would be more informative to explain why reloading is necessary (e.g., "Finally, reload the page to ensure proper wallet connection").

-                        chain. Finally, reload the page.
+                        chain. Finally, reload the page to ensure proper wallet connection and state reset.

Line range hint 89-116: Add clarity about automatic network switching.

Since the MetaMask integration now handles network switching automatically (as indicated by the removal of the manual button), consider adding a note about this behavior in the instructions to set proper user expectations.

Add this line after the existing instructions:

                        chain. Finally, reload the page.
+                    </li>
+                    <li>
+                        Note: The network will be configured automatically when you interact with the wallet. No manual network addition is required.
cmd/monogen/testapp/wallet/metamask-integration.js (2)

14-14: Remove unnecessary undefined initialization.

In JavaScript, variables declared without initialization are automatically undefined.

-let optimismPortalContract = undefined;
+let optimismPortalContract;

Based on the results, I can now generate the final response:

Consider abstracting wallet-specific implementation for better L1 wallet compatibility

While the code uses the standard EIP-1193 window.ethereum interface, the implementation is tightly coupled to MetaMask with specific function names and error messages. Consider:

  • cmd/monogen/testapp/wallet/metamask-integration.js:
    • Functions like connectMetamask() and addL1ChainToMetaMask() are MetaMask-specific
    • Error messages explicitly mention MetaMask: "Please install Metamask"
    • Direct calls to MetaMask-specific RPC methods like wallet_switchEthereumChain and wallet_addEthereumChain

To improve compatibility, consider:

  • Creating a wallet interface abstraction
  • Using provider-agnostic function names and messages
  • Moving MetaMask-specific logic into a separate implementation
🔗 Analysis chain

Line range hint 1-1: Verify compatibility with other L1 wallets.

The implementation follows EIP-1193 standard and should work with other L1 wallets. Let's verify the presence of alternative wallet providers.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for references to specific wallet providers
# Expected: Only standard EIP-1193 interfaces are used

echo "Checking for wallet-specific implementations..."
rg -i "metamask|coinbase|wallet" --type js

echo "Verifying EIP-1193 standard usage..."
rg "window\.ethereum" --type js

Length of output: 2155

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 8a70bf0 and 8923c99.

⛔ Files ignored due to path filters (1)
  • cmd/monogen/testapp.zip is excluded by !**/*.zip
📒 Files selected for processing (2)
  • cmd/monogen/testapp/wallet/index.html (1 hunks)
  • cmd/monogen/testapp/wallet/metamask-integration.js (2 hunks)
🔇 Additional comments (2)
cmd/monogen/testapp/wallet/metamask-integration.js (2)

12-12: Add decimal value comment for chainId.

For better readability, add a comment with the decimal representation of the chain ID.

-const chainId = "0x384"; // 900
+const chainId = "0x384"; // 900 (decimal)

42-54: Previous review comment about enhanced error handling for chain switching is still valid.

Comment on lines +33 to +40
await addL1ChainToMetaMask();
await switchToMonomerDevnet();

console.log("Connected to MetaMask and contract instantiated.");
} catch (error) {
console.error("Error connecting to MetaMask:", error);
}
}
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

Enhance error handling in connectMetamask.

The error handling should provide user feedback through the status paragraph and handle specific error codes.

 await addL1ChainToMetaMask();
 await switchToMonomerDevnet();

 console.log("Connected to MetaMask and contract instantiated.");
+statusParagraph.innerText = "Successfully connected to MetaMask on Monomer Devnet";
} catch (error) {
-  console.error("Error connecting to MetaMask:", error);
+  console.error("Error connecting to MetaMask:", error);
+  if (error.code === 4001) {
+    statusParagraph.innerText = "Connection rejected by user";
+  } else {
+    statusParagraph.innerText = `Failed to connect: ${error.message}`;
+  }
+  throw error;
}

Committable suggestion was skipped due to low confidence.

}

async function addL1ChainToMetaMask() {
try {
await window.ethereum.request({
method: 'wallet_addEthereumChain',
params: [{
chainId: '0x384', // 900
chainId: chainId,
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

Consider making RPC URL configurable.

The RPC URL is currently hardcoded to 'http://127.0.0.1:9001'. Consider making it configurable to support different environments (development, staging, production).

+const MONOMER_RPC_URL = process.env.MONOMER_RPC_URL || 'http://127.0.0.1:9001';

 async function addL1ChainToMetaMask() {
     try {
         await window.ethereum.request({
             method: 'wallet_addEthereumChain',
             params: [{
                 chainId: chainId,
                 chainName: 'Ethereum (Monomer Devnet)',
                 nativeCurrency: {
                     name: 'ETH',
                     symbol: 'ETH',
                     decimals: 18
                 },
-                rpcUrls: ['http://127.0.0.1:9001'],
+                rpcUrls: [MONOMER_RPC_URL],
                 blockExplorerUrls: []
             }]
         });
📝 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
chainId: chainId,
chainId: chainId,
chainName: 'Ethereum (Monomer Devnet)',
nativeCurrency: {
name: 'ETH',
symbol: 'ETH',
decimals: 18
},
rpcUrls: [MONOMER_RPC_URL],
blockExplorerUrls: []

@joshklop joshklop merged commit 7055b06 into main Oct 28, 2024
16 checks passed
@joshklop joshklop deleted the joshklop.auto-switch-network branch October 28, 2024 22:25
@coderabbitai coderabbitai bot mentioned this pull request Oct 30, 2024
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