Skip to content

feat: add network switching support for Polygon and testnets (fixes #14)#24

Open
akshitj11 wants to merge 3 commits intophantom:mainfrom
akshitj11:main
Open

feat: add network switching support for Polygon and testnets (fixes #14)#24
akshitj11 wants to merge 3 commits intophantom:mainfrom
akshitj11:main

Conversation

@akshitj11
Copy link
Copy Markdown

@akshitj11 akshitj11 commented Feb 26, 2026

Fixes #14

What this does

Adds a "Switch Network" button to the sandbox that allows users to
switch to Polygon Mainnet using wallet_switchEthereumChain (EIP-3326).

If Polygon hasn't been added to Phantom yet (error code 4902), it
automatically calls wallet_addEthereumChain (EIP-3085) to register
it first, then switches.

Testing

  1. Connect Phantom wallet
  2. Click "Switch Network"
  3. Phantom prompts to switch to Polygon Mainnet

Notes

createLog uses eth_sendTransaction as the method label since
wallet_switchEthereumChain is not a supported log method type
in the current codebase

Summary by CodeRabbit

  • New Features

    • Users can switch networks in-app to Ethereum Mainnet, Polygon Mainnet, Sepolia, or Mumbai. If a network isn't configured in the wallet, the app will add it and then switch automatically.
  • Chores

    • Version control updated to ignore the build/ directory.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Feb 26, 2026

📝 Walkthrough

Walkthrough

Adds multi-network switching (Ethereum, Polygon, Sepolia, Mumbai) with automatic network addition on error 4902, updates UI actions to trigger switches, and updates .gitignore to ignore the build/ directory. Also shortens an on-screen message string.

Changes

Cohort / File(s) Summary
Network Switching / App logic
src/App.tsx
Adds NETWORKS constant (mainnet/testnet entries for Ethereum, Polygon, Sepolia, Mumbai). Implements handleSwitchNetwork to call wallet_switchEthereumChain, on error 4902 call wallet_addEthereumChain with full params then retry. Adds four new "Switch to ..." UI actions to connectedMethods. Includes handleSwitchNetwork in memoization dependencies. Shortens a message constant.
Build ignore
.gitignore
Adds build/ to ignored paths to exclude build output from version control.

Sequence Diagram

sequenceDiagram
    participant User
    participant App
    participant WalletProvider
    participant Network

    User->>App: Click "Switch to <Network>"
    App->>WalletProvider: wallet_switchEthereumChain({chainId})
    alt Provider returns success
        WalletProvider-->>App: switched
        App-->>User: success
    else Error 4902 (chain not found)
        WalletProvider-->>App: error 4902
        App->>WalletProvider: wallet_addEthereumChain({chain params})
        WalletProvider->>Network: register/add chain
        Network-->>WalletProvider: added
        WalletProvider-->>App: add succeeded
        App->>WalletProvider: wallet_switchEthereumChain({chainId}) (retry)
        WalletProvider->>Network: switch to chain
        Network-->>WalletProvider: switched
        WalletProvider-->>App: switched
        App-->>User: success / or log error
    end
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding network switching support for Polygon and testnets, which directly matches the PR's primary objective.
Linked Issues check ✅ Passed All coding requirements from issue #14 are met: network switching via wallet_switchEthereumChain, network addition via wallet_addEthereumChain on error 4902, support for Polygon/Sepolia/Mumbai, and UI actions for switching networks.
Out of Scope Changes check ✅ Passed The .gitignore change (adding build/) is a minor housekeeping modification; the message string shortening is a trivial side-effect. Both are reasonable supporting changes and not unrelated to the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/App.tsx`:
- Around line 218-235: The code is hardcoded to switch/add Polygon Mainnet
(chainId '0x89') and lacks testnet/network selection; change the network switch
logic to accept a selectedNetwork variable (instead of the literal '0x89') and
use a networks map that includes entries for Polygon Mainnet, Polygon Mumbai
(testnet, e.g., '0x13881'), Ethereum Mainnet ('0x1') and any required testnets
(e.g., Sepolia '0xaa36a7'), each with chainId, chainName, nativeCurrency,
rpcUrls and blockExplorerUrls; update the window.ethereum.request calls in the
switch/add block (the code that calls method 'wallet_switchEthereumChain' and
'wallet_addEthereumChain') to use networks[selectedNetwork] and adjust createLog
calls to include the chosen network name and chainId so switching and adding
work for both mainnet and testnets and the UI/action that triggers the switch
uses the selectedNetwork value instead of a hardcoded '0x89'.
- Around line 225-237: When handling the wallet_switchEthereumChain failure for
error.code === 4902 in App.tsx, after calling window.ethereum.request with
method 'wallet_addEthereumChain' include an immediate retry of
window.ethereum.request with method 'wallet_switchEthereumChain' (same params)
to complete the network switch; wrap the add-then-retry sequence in its own
try-catch so any errors from adding the chain or the subsequent switch are
caught and handled (e.g., log or surface to the user) instead of leaving the
user on the old network.
- Line 287: The memoized value connectedMethods captures handleConnect but the
dependency array for the useMemo call only lists handleEthSendTransaction,
handleSignMessage, and handleSwitchNetwork; add handleConnect to that dependency
array so the memo updates when handleConnect changes, ensuring connectedMethods
references the latest callback (update the useMemo that produces
connectedMethods to include handleConnect alongside handleEthSendTransaction,
handleSignMessage, and handleSwitchNetwork).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 46b448d and f4ad6b2.

⛔ Files ignored due to path filters (2)
  • build/static/js/main.40cf3a1c.js.map is excluded by !**/*.map
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (5)
  • build/asset-manifest.json
  • build/index.html
  • build/static/js/main.40cf3a1c.js
  • build/static/js/main.40cf3a1c.js.LICENSE.txt
  • src/App.tsx

Comment thread src/App.tsx Outdated
Comment thread src/App.tsx Outdated
Comment thread src/App.tsx Outdated
Copy link
Copy Markdown

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/App.tsx (1)

284-284: ⚠️ Potential issue | 🟡 Minor

accounts in dependency array is not reactive and should be removed.

accounts is a module-level let variable (line 37), not React state. Including it in the dependency array has no effect—React won't detect changes to it, and it may cause the callback to capture stale references or recreate unnecessarily.

Proposed fix
-  }, [provider, createLog, accounts]);
+  }, [provider, createLog]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` at line 284, The dependency array for the hook currently
includes the module-level variable `accounts`, which is not reactive; remove
`accounts` from the array so it reads `[provider, createLog]` instead, and if
the hook's callback (the function using that dependency) needs the latest
`accounts` value make it read the module variable at call time or convert
`accounts` to React state/Ref; update the hook where you see `}, [provider,
createLog, accounts]);` to `}, [provider, createLog]);` and ensure any usage of
`accounts` inside that effect/callback (the function referencing `provider` and
`createLog`) accesses the up-to-date value appropriately.
🧹 Nitpick comments (2)
src/App.tsx (2)

220-224: Misleading log method name for network switch operations.

Using 'eth_sendTransaction' as the method in createLog for network switching operations is misleading. The PR notes this is because wallet_switchEthereumChain isn't a supported log method type, but this conflates unrelated operations in logs.

Consider adding 'wallet_switchEthereumChain' as a supported log method type, or use a more generic method name like 'networkSwitch' that doesn't misrepresent the action.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` around lines 220 - 224, The log entry for a network switch
currently mislabels the operation as 'eth_sendTransaction' in createLog; update
the call site to use a correct method identifier by either adding
'wallet_switchEthereumChain' as a supported method type in the logging
schema/enum (where createLog validates or documents allowed methods) or change
the method value to a generic, accurate name like 'networkSwitch' in the
createLog invocation (and update any type definitions or tests that assert
allowed method strings) so network switches are not conflated with transaction
sends.

213-264: Inconsistent indentation reduces readability.

The function body has misaligned indentation. The inner try/catch blocks (starting at lines 228 and 249) and the else block (line 256) are not properly indented relative to their parent blocks.

♻️ Proposed fix for consistent indentation
   const handleSwitchNetwork = useCallback(async () => {
-  if (!provider) return;
-  try {
-    await window.ethereum.request({
-      method: 'wallet_switchEthereumChain',
-      params: [{ chainId: '0x89' }], // 0x89 = Polygon Mainnet
-    });
-    createLog({
-      status: 'success',
-      method: 'eth_sendTransaction',
-      message: 'Switched to Polygon Mainnet!',
-    });
-  } catch (error) {
-    // Error code 4902 means chain hasn't been added to Phantom yet
-    if (error.code === 4902) {
-  try {
-    await window.ethereum.request({
-      method: 'wallet_addEthereumChain',
-      params: [{
-        chainId: '0x89',
-        chainName: 'Polygon Mainnet',
-        nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
-        rpcUrls: ['https://polygon-rpc.com'],
-        blockExplorerUrls: ['https://polygonscan.com'],
-      }],
-    });
-    // Retry the switch after adding the chain
-    await window.ethereum.request({
-      method: 'wallet_switchEthereumChain',
-      params: [{ chainId: '0x89' }],
-    });
-    createLog({
-      status: 'success',
-      method: 'eth_sendTransaction',
-      message: 'Polygon Mainnet added and switched successfully!',
-    });
-  } catch (addError: any) {
-    createLog({
-      status: 'error',
-      method: 'eth_sendTransaction',
-      message: addError.message,
-    });
-  }
-} else {
-      createLog({
-        status: 'error',
-        method: 'eth_sendTransaction',
-        message: error.message,
-      });
-    }
-  }
-}, [provider, createLog]);
+    if (!provider) return;
+    try {
+      await window.ethereum.request({
+        method: 'wallet_switchEthereumChain',
+        params: [{ chainId: '0x89' }],
+      });
+      createLog({
+        status: 'success',
+        method: 'eth_sendTransaction',
+        message: 'Switched to Polygon Mainnet!',
+      });
+    } catch (error) {
+      if (error.code === 4902) {
+        try {
+          await window.ethereum.request({
+            method: 'wallet_addEthereumChain',
+            params: [{
+              chainId: '0x89',
+              chainName: 'Polygon Mainnet',
+              nativeCurrency: { name: 'MATIC', symbol: 'MATIC', decimals: 18 },
+              rpcUrls: ['https://polygon-rpc.com'],
+              blockExplorerUrls: ['https://polygonscan.com'],
+            }],
+          });
+          await window.ethereum.request({
+            method: 'wallet_switchEthereumChain',
+            params: [{ chainId: '0x89' }],
+          });
+          createLog({
+            status: 'success',
+            method: 'eth_sendTransaction',
+            message: 'Polygon Mainnet added and switched successfully!',
+          });
+        } catch (addError: any) {
+          createLog({
+            status: 'error',
+            method: 'eth_sendTransaction',
+            message: addError.message,
+          });
+        }
+      } else {
+        createLog({
+          status: 'error',
+          method: 'eth_sendTransaction',
+          message: error.message,
+        });
+      }
+    }
+  }, [provider, createLog]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` around lines 213 - 264, The handleSwitchNetwork function's
nested try/catch/else blocks are misindented; reformat the block beginning at
handleSwitchNetwork so the inner try (the wallet_addEthereumChain call), its
corresponding catch (addError), and the outer else (handling non-4902 errors)
are aligned under the outer catch that checks error.code === 4902, keeping the
structure: outer try -> outer catch (if error.code === 4902) -> inner try ->
inner catch -> (after inner catch) retry switch and createLog, and the outer
catch's else branch aligned with that outer catch; ensure references to
window.ethereum.request, error.code === 4902, addError, and createLog remain
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/App.tsx`:
- Line 284: The dependency array for the hook currently includes the
module-level variable `accounts`, which is not reactive; remove `accounts` from
the array so it reads `[provider, createLog]` instead, and if the hook's
callback (the function using that dependency) needs the latest `accounts` value
make it read the module variable at call time or convert `accounts` to React
state/Ref; update the hook where you see `}, [provider, createLog, accounts]);`
to `}, [provider, createLog]);` and ensure any usage of `accounts` inside that
effect/callback (the function referencing `provider` and `createLog`) accesses
the up-to-date value appropriately.

---

Nitpick comments:
In `@src/App.tsx`:
- Around line 220-224: The log entry for a network switch currently mislabels
the operation as 'eth_sendTransaction' in createLog; update the call site to use
a correct method identifier by either adding 'wallet_switchEthereumChain' as a
supported method type in the logging schema/enum (where createLog validates or
documents allowed methods) or change the method value to a generic, accurate
name like 'networkSwitch' in the createLog invocation (and update any type
definitions or tests that assert allowed method strings) so network switches are
not conflated with transaction sends.
- Around line 213-264: The handleSwitchNetwork function's nested try/catch/else
blocks are misindented; reformat the block beginning at handleSwitchNetwork so
the inner try (the wallet_addEthereumChain call), its corresponding catch
(addError), and the outer else (handling non-4902 errors) are aligned under the
outer catch that checks error.code === 4902, keeping the structure: outer try ->
outer catch (if error.code === 4902) -> inner try -> inner catch -> (after inner
catch) retry switch and createLog, and the outer catch's else branch aligned
with that outer catch; ensure references to window.ethereum.request, error.code
=== 4902, addError, and createLog remain unchanged.

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f4ad6b2 and 950c460.

📒 Files selected for processing (2)
  • .gitignore
  • src/App.tsx

Copy link
Copy Markdown

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

🧹 Nitpick comments (2)
src/App.tsx (2)

251-283: Use wallet-specific method names in switch/add logs.

Line 253 onward logs switch/add events as eth_sendTransaction; that blurs telemetry and troubleshooting. Prefer wallet RPC method labels (wallet_switchEthereumChain / wallet_addEthereumChain) and extend TLog['method'] accordingly.

🧭 Proposed adjustment in this file
-      method: 'eth_sendTransaction',
+      method: 'wallet_switchEthereumChain',
...
-          method: 'eth_sendTransaction',
+          method: 'wallet_addEthereumChain',
...
-          method: 'eth_sendTransaction',
+          method: 'wallet_addEthereumChain',
...
-        method: 'eth_sendTransaction',
+        method: 'wallet_switchEthereumChain',
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` around lines 251 - 283, The logs are using the generic
'eth_sendTransaction' method name for chain switching/adding; update the
createLog calls inside the switch/add catch blocks to use wallet-specific RPC
names ('wallet_switchEthereumChain' and 'wallet_addEthereumChain') so telemetry
reflects the actual operation, and update the TLog['method'] union type (or
wherever method values are declared) to include 'wallet_switchEthereumChain' and
'wallet_addEthereumChain' so the new strings are type-safe; adjust any tests or
usages that assert the old method string if present.

243-246: Constrain networkKey to known keys for type safety and maintainability.

The parameter currently accepts any string. Narrowing to keyof typeof NETWORKS prevents invalid keys and improves IDE autocomplete for callers.

♻️ Proposed fix
+type NetworkKey = keyof typeof NETWORKS;
 
-const handleSwitchNetwork = useCallback(async (networkKey: string) => {
+const handleSwitchNetwork = useCallback(async (networkKey: NetworkKey) => {
   if (!provider) return;
   const network = NETWORKS[networkKey];
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/App.tsx` around lines 243 - 246, The function handleSwitchNetwork accepts
a plain string which allows invalid keys; change its parameter type to a union
of valid network keys by typing networkKey as keyof typeof NETWORKS in the
handleSwitchNetwork declaration so callers get compile-time checking and IDE
autocomplete, update any callers if needed to satisfy the new type, and ensure
imports/reference to NETWORKS remain unchanged (locate the handler named
handleSwitchNetwork and the constant NETWORKS to make this change).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/App.tsx`:
- Around line 251-283: The logs are using the generic 'eth_sendTransaction'
method name for chain switching/adding; update the createLog calls inside the
switch/add catch blocks to use wallet-specific RPC names
('wallet_switchEthereumChain' and 'wallet_addEthereumChain') so telemetry
reflects the actual operation, and update the TLog['method'] union type (or
wherever method values are declared) to include 'wallet_switchEthereumChain' and
'wallet_addEthereumChain' so the new strings are type-safe; adjust any tests or
usages that assert the old method string if present.
- Around line 243-246: The function handleSwitchNetwork accepts a plain string
which allows invalid keys; change its parameter type to a union of valid network
keys by typing networkKey as keyof typeof NETWORKS in the handleSwitchNetwork
declaration so callers get compile-time checking and IDE autocomplete, update
any callers if needed to satisfy the new type, and ensure imports/reference to
NETWORKS remain unchanged (locate the handler named handleSwitchNetwork and the
constant NETWORKS to make this change).

ℹ️ Review info

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 950c460 and 63fa2c5.

📒 Files selected for processing (1)
  • src/App.tsx

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.

How can I connect to the Polygon network or Ethereum & Polygon testnets?

1 participant