Skip to content

chore: refactor chain select modals#2131

Merged
Nick-1979 merged 9 commits into
mainfrom
refactoChainSelect
Apr 3, 2026
Merged

chore: refactor chain select modals#2131
Nick-1979 merged 9 commits into
mainfrom
refactoChainSelect

Conversation

@Nick-1979
Copy link
Copy Markdown
Member

@Nick-1979 Nick-1979 commented Apr 3, 2026

Summary by CodeRabbit

  • New Features

    • Unified, searchable network picker with clear selection, double‑click support and empty‑state messaging.
  • Refactor

    • Replaced multiple local pickers with a shared network picker for consistent behavior and visuals.
    • Network logos now use network names for more reliable display.
    • Breadcrumb for send/account flow updated to be navigable.
  • Documentation

    • UI label changed from "Chains" to "Networks" (translations updated).

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 3, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Replaces local chain-selection UIs with a shared ChainPickerList, refactors useGenesisHashOptions to accept { isEthereum?, withRelay? } with module-level metadata caching and request dedupe, updates call sites to the new hook signature, and switches several Logo usages to pass chainName.

Changes

Cohort / File(s) Summary
New Component
packages/extension-polkagate/src/fullscreen/components/ChainPickerList.tsx
Add reusable searchable/scrollable chain list component with filtering, selection/double-click handlers, selected-check UI, dividers, and "Network Not Found" messaging.
Hook API & Caching
packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts
Change signature to ({ isEthereum?, withRelay? }); add module-level metadata caches and in-flight dedupe; add getMetadataChains; split relay/non-relay handling, Asset Hub prioritization, and updated sorting/reordering logic.
Chain List Integration
packages/extension-polkagate/src/fullscreen/components/ChainListModal.tsx, packages/extension-polkagate/src/fullscreen/accountDetails/rightColumn/Receive.tsx
Remove local search/list UI and selection plumbing; render ChainPickerList; normalize option value to String(...); change selection callbacks to accept full DropdownOption.
Call Site Updates (useGenesisHashOptions)
packages/extension-polkagate/src/hooks/useChainSelectionSettings.ts, packages/extension-polkagate/src/hooks/useNotifications.ts, packages/extension-ui/src/Popup/contexts/GenesisHashOptionsProvider.tsx, packages/extension-polkagate/src/popup/receive/Receive.tsx
Update calls to object-form API (e.g., useGenesisHashOptions({}), useGenesisHashOptions({ isEthereum, withRelay: false })); simplify search/filter logic where applicable.
Logo Prop Changes
packages/extension-polkagate/src/fullscreen/components/AccountChainSelect.tsx, packages/extension-polkagate/src/fullscreen/stake/stakingPositions/PositionItem.tsx, packages/extension-polkagate/src/popup/staking/StakingPositions.tsx, packages/extension-polkagate/src/popup/staking/EarningOptions.tsx
Switch Logo inputs from genesisHash to chainName obtained via useChainInfo(genesisHash, true).
UI Text & Localization
packages/extension-polkagate/src/fullscreen/notification/NotificationSettingsFS.tsx, packages/extension/public/locales/*/translation.json
Replace "Select Chains" with "Select Networks" across UI and add localized translations; adjust trailing commas/newlines in JSON files.
Minor / Breadcrumb & Cosmetic
packages/extension-polkagate/src/fullscreen/components/layout/Bread.tsx, packages/extension-polkagate/src/fullscreen/stake/stakingPositions/index.tsx
Make '/send' breadcrumb navigable and swap icon/label to Account; reorder a type prop assignment in PositionItem calls (no behavioral change).

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant ReceiveModal as Receive Modal
  participant Hook as useGenesisHashOptions
  participant Cache as metadataCacheByType
  participant ChainPicker as ChainPickerList

  User->>ReceiveModal: open chain selector
  ReceiveModal->>Hook: request options ({ isEthereum, withRelay })
  Hook->>Cache: load or reuse metadataChains for chainType
  Cache-->>Hook: metadataChains
  Hook-->>ReceiveModal: return DropdownOption[] (sorted/reordered)
  ReceiveModal->>ChainPicker: render(options)
  User->>ChainPicker: search / select option
  ChainPicker-->>ReceiveModal: onSelect(option)
  ReceiveModal-->>User: show receive/QR/share for selected chain
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • PR #2032 — Direct changes to useGenesisHashOptions hook API and implementation.
  • PR #2058 — Similar replacement of local selector logic in Receive.tsx with shared chain options.
  • PR #1871 — Related refactor of ChainListModal chain-list construction and selection plumbing.

Suggested labels

enhancement

Suggested reviewers

  • AMIRKHANEF

Poem

🐰 Hop hop — a picker for every net,
I sort the relays and never forget.
Chain names for logos, no genesis in sight,
Search and select — the list feels light.
Carrot cheers — code hops into the night!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'chore: refactor chain select modals' accurately reflects the main objective of this pull request, which refactors chain/network selection components across multiple files by extracting common UI logic into a new shared ChainPickerList component and updating the useGenesisHashOptions hook API.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactoChainSelect

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.

@Nick-1979 Nick-1979 changed the title chore : refactor chain select modals chore: refactor chain select modals Apr 3, 2026
Copy link
Copy Markdown
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

🧹 Nitpick comments (1)
packages/extension-polkagate/src/fullscreen/components/ChainPickerList.tsx (1)

86-115: Consider using chain.value as the key instead of index.

Using index as a React key can cause issues when items are reordered or filtered, potentially leading to incorrect state retention or rendering artifacts. Since chain.value (genesisHash) should be unique, it would be a more stable key.

♻️ Suggested change
-            <React.Fragment key={index}>
+            <React.Fragment key={chain.value}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/extension-polkagate/src/fullscreen/components/ChainPickerList.tsx`
around lines 86 - 115, The list is using index as the React key which can break
identity when items reorder; update the Fragment key to use the stable unique
identifier chain.value (genesisHash) instead of index in the ChainPickerList
rendering (the React.Fragment that currently has key={index}); ensure any
sibling elements like GradientDivider don't also rely on index for identity so
the list items keep correct state when filtered or reordered.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/extension-polkagate/src/fullscreen/components/ChainListModal.tsx`:
- Around line 85-90: In the map that builds options (the return of _options.map
inside ChainListModal.tsx), avoid mutating the original DropdownOption objects
by returning a new object instead of assigning to o.value; replace the in-place
mutation with creating a shallow copy (e.g., spread the original option and set
value: String(o.value)) so callers of allChains/externalOptions are not affected
and React references remain stable.

In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts`:
- Around line 88-93: The map transformation for assetHubFirstChains can leave a
trailing space when removing ASSET_HUB (e.g., "Polkadot Asset Hub" -> "Polkadot
"), so update the mapping in useGenesisHashOptions.ts to trim the replaced
string; in the map callback that builds the text (the code using
assetHubFirstChains.map and ASSET_HUB) ensure you call trim() on the result of
replace (or trim the final text value) so any leftover whitespace is removed.

---

Nitpick comments:
In `@packages/extension-polkagate/src/fullscreen/components/ChainPickerList.tsx`:
- Around line 86-115: The list is using index as the React key which can break
identity when items reorder; update the Fragment key to use the stable unique
identifier chain.value (genesisHash) instead of index in the ChainPickerList
rendering (the React.Fragment that currently has key={index}); ensure any
sibling elements like GradientDivider don't also rely on index for identity so
the list items keep correct state when filtered or reordered.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d6fad7ec-b73b-440f-9c27-0409fd2fca41

📥 Commits

Reviewing files that changed from the base of the PR and between 9e4fae2 and 38fcd0b.

📒 Files selected for processing (15)
  • packages/extension-polkagate/src/fullscreen/accountDetails/rightColumn/Receive.tsx
  • packages/extension-polkagate/src/fullscreen/components/AccountChainSelect.tsx
  • packages/extension-polkagate/src/fullscreen/components/ChainListModal.tsx
  • packages/extension-polkagate/src/fullscreen/components/ChainPickerList.tsx
  • packages/extension-polkagate/src/fullscreen/notification/NotificationSettingsFS.tsx
  • packages/extension-polkagate/src/fullscreen/stake/stakingPositions/PositionItem.tsx
  • packages/extension-polkagate/src/fullscreen/stake/stakingPositions/index.tsx
  • packages/extension-polkagate/src/hooks/useChainSelectionSettings.ts
  • packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts
  • packages/extension-polkagate/src/hooks/useNotifications.ts
  • packages/extension-polkagate/src/popup/receive/Receive.tsx
  • packages/extension-polkagate/src/popup/staking/EarningOptions.tsx
  • packages/extension-polkagate/src/popup/staking/StakingPositions.tsx
  • packages/extension-ui/src/Popup/contexts/GenesisHashOptionsProvider.tsx
  • packages/extension/public/locales/en/translation.json

Comment thread packages/extension-polkagate/src/fullscreen/components/ChainListModal.tsx Outdated
Comment thread packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts
Copy link
Copy Markdown
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

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

Inline comments:
In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts`:
- Around line 22-41: The getMetadataChains function currently stores a rejected
promise in metadataRequestByType when getAllMetadata() fails, preventing
retries; update the logic where metadataRequestByType[chainType] is assigned
(the branch that calls getAllMetadata()) to attach a .catch (or try/catch around
an async/await) that clears metadataRequestByType[chainType] on error (and
optionally set metadataCacheByType[chainType] = []), then rethrow or propagate
the error so callers can handle it; reference metadataRequestByType,
metadataCacheByType, getAllMetadata, and getMetadataChains when making the
change.
- Around line 60-66: protocolFilteredChains is not applying the same protocol
filter as metadataChains when isEthereum is false, causing Ethereum static
chains to mix with substrate-only metadata; update the protocolFilteredChains
calculation (which uses isEthereum and testnetFilteredChains) so that when
isEthereum is false it filters testnetFilteredChains by !chain.isEthereum
(matching metadataChains filtering), ensuring protocol consistency between
static chains (chains/testnetFilteredChains) and metadata-only chains
(metadataChains/metadataOnlyChains).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82879eb6-55e3-40cc-a8ec-de794f0c89ac

📥 Commits

Reviewing files that changed from the base of the PR and between 38fcd0b and bc9232a.

📒 Files selected for processing (2)
  • packages/extension-polkagate/src/fullscreen/components/ChainListModal.tsx
  • packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/extension-polkagate/src/fullscreen/components/ChainListModal.tsx

Comment thread packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts
Comment thread packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts
Copy link
Copy Markdown
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.

♻️ Duplicate comments (1)
packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts (1)

66-69: ⚠️ Potential issue | 🔴 Critical

Protocol filtering inconsistency for substrate mode remains unaddressed.

When isEthereum is false, protocolFilteredChains includes all static chains (both Ethereum and substrate), but metadataChains is filtered to only 'substrate' type on line 54. This creates an inconsistency where Ethereum chains from the static list are mixed with substrate-only chains from metadata.

Apply the same filtering to static chains:

 const protocolFilteredChains =
   isEthereum
     ? testnetFilteredChains.filter((chain) => chain.isEthereum)
-    : testnetFilteredChains;
+    : testnetFilteredChains.filter((chain) => !chain.isEthereum);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts` around lines
66 - 69, protocolFilteredChains currently only filters for Ethereum when
isEthereum is true, leaving static chains unfiltered for substrate mode; update
the else branch to mirror the metadataChains substrate filtering so static
chains are limited to substrate-only. Modify the assignment of
protocolFilteredChains (the ternary using isEthereum and testnetFilteredChains)
so the false branch applies the same substrate filter used by metadataChains
(e.g., testnetFilteredChains.filter(chain => chain.type === 'substrate' or
chain.isSubstrate)), ensuring protocolFilteredChains and metadataChains remain
consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts`:
- Around line 66-69: protocolFilteredChains currently only filters for Ethereum
when isEthereum is true, leaving static chains unfiltered for substrate mode;
update the else branch to mirror the metadataChains substrate filtering so
static chains are limited to substrate-only. Modify the assignment of
protocolFilteredChains (the ternary using isEthereum and testnetFilteredChains)
so the false branch applies the same substrate filter used by metadataChains
(e.g., testnetFilteredChains.filter(chain => chain.type === 'substrate' or
chain.isSubstrate)), ensuring protocolFilteredChains and metadataChains remain
consistent.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3b162d86-284c-4fd6-9b25-0c3d71db236e

📥 Commits

Reviewing files that changed from the base of the PR and between bc9232a and 5400693.

📒 Files selected for processing (1)
  • packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts

Copy link
Copy Markdown
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

♻️ Duplicate comments (1)
packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts (1)

67-70: ⚠️ Potential issue | 🔴 Critical

Filter the substrate branch the same way as metadata.

Line 70 still falls back to the full static list, so useGenesisHashOptions({}) mixes Ethereum chains with substrate-only metadata. packages/extension-polkagate/src/hooks/useChainSelectionSettings.ts already uses the default {} path, so this regression is live outside the modal refactor too.

Suggested fix
     const protocolFilteredChains =
       isEthereum
         ? testnetFilteredChains.filter((chain) => chain.isEthereum)
-        : testnetFilteredChains;
+        : testnetFilteredChains.filter((chain) => !chain.isEthereum);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts` around lines
67 - 70, The protocolFilteredChains assignment in useGenesisHashOptions.ts lets
the substrate branch fall back to the full static list and thus mixes Ethereum
chains into substrate-only options; update the else branch so that when
isEthereum is false you also filter testnetFilteredChains to exclude Ethereum
chains (e.g., filter by chain.isEthereum === false or !chain.isEthereum). Locate
the symbol protocolFilteredChains and the variables isEthereum and
testnetFilteredChains and apply the same filtering logic used for the Ethereum
branch to the substrate branch so substrate-only metadata is returned.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts`:
- Around line 51-58: When isEthereum changes the effect should clear and guard
metadataChains to avoid stale overwrites: inside the useEffect that calls
getMetadataChains(chainType) (the effect using isEthereum, getMetadataChains,
metadataChains and setMetadataChains), immediately call setMetadataChains([])
when the protocol flips and add a local cancelled flag (e.g., let cancelled =
false) and check it before calling setMetadataChains in the promise resolution;
also set cancelled = true in the effect cleanup to ignore any late-resolving
promises from previous requests so old results cannot overwrite the new state.

---

Duplicate comments:
In `@packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts`:
- Around line 67-70: The protocolFilteredChains assignment in
useGenesisHashOptions.ts lets the substrate branch fall back to the full static
list and thus mixes Ethereum chains into substrate-only options; update the else
branch so that when isEthereum is false you also filter testnetFilteredChains to
exclude Ethereum chains (e.g., filter by chain.isEthereum === false or
!chain.isEthereum). Locate the symbol protocolFilteredChains and the variables
isEthereum and testnetFilteredChains and apply the same filtering logic used for
the Ethereum branch to the substrate branch so substrate-only metadata is
returned.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9ae6e26f-2c6d-447c-8c6b-b72af0edd1e0

📥 Commits

Reviewing files that changed from the base of the PR and between 5400693 and 6502f89.

📒 Files selected for processing (2)
  • packages/extension-polkagate/src/fullscreen/components/layout/Bread.tsx
  • packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts

Comment thread packages/extension-polkagate/src/hooks/useGenesisHashOptions.ts Outdated
@Nick-1979 Nick-1979 merged commit 817605a into main Apr 3, 2026
5 checks passed
@Nick-1979 Nick-1979 deleted the refactoChainSelect branch April 3, 2026 20:40
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.

1 participant