Skip to content

Conversation

@MananTank
Copy link
Contributor

@MananTank MananTank commented Jan 13, 2026


PR-Codex overview

This PR introduces a Last Used badge in the Connect UI to indicate the most recently used sign-in method, enhancing user experience by providing quick access to their preferred wallet or authentication option.

Detailed summary

  • Added LastUsedBadge component to highlight the last used sign-in method.
  • Updated InputSelectionUI and WalletTypeRowButton to accept lastUsedBadge prop.
  • Modified sortWallets to prioritize the last used wallet.
  • Integrated badge logic into various wallet connection components.
  • Updated state management to track last used wallet and social auth methods.

✨ Ask PR-Codex anything about this PR by commenting with /codex {your question}

Summary by CodeRabbit

  • New Features

    • Added a "Last used" badge to highlight the most recently used wallet and sign-in method.
    • Last-used wallet and social sign-in are tracked and prioritized to surface the preferred option.
  • UI

    • Layout and spacing adjusted across wallet and sign-in screens to accommodate the badge; badge shown across wallet, social, email, phone, passkey, and guest flows.
  • Documentation

    • Release entry added and new Storybook examples for modal sizes.
  • Tests

    • Updated tests to include the new badge prop where applicable.

✏️ Tip: You can customize this high-level summary in your review settings.

@linear
Copy link

linear bot commented Jan 13, 2026

@vercel
Copy link

vercel bot commented Jan 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
docs-v2 Ready Ready Preview, Comment Jan 13, 2026 5:57pm
nebula Ready Ready Preview, Comment Jan 13, 2026 5:57pm
thirdweb_playground Ready Ready Preview, Comment Jan 13, 2026 5:57pm
thirdweb-www Ready Ready Preview, Comment Jan 13, 2026 5:57pm
wallet-ui Ready Ready Preview, Comment Jan 13, 2026 5:57pm

@changeset-bot
Copy link

changeset-bot bot commented Jan 13, 2026

🦋 Changeset detected

Latest commit: 97c0825

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 4 packages
Name Type
thirdweb Patch
@thirdweb-dev/nebula Patch
@thirdweb-dev/wagmi-adapter Patch
wagmi-inapp Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 13, 2026

Walkthrough

Adds a "Last used" badge to the Connect Wallet UI: persists last-used wallet ID on connect/activate, exposes defensive storage helpers, provides a Badge component, updates wallet sorting to prioritize last-used, and threads a lastUsedBadge prop through wallet and social-auth UI to render the indicator.

Changes

Cohort / File(s) Summary
Changeset & Persistence
\.changeset/three-fans-flow.md, packages/thirdweb/src/wallets/manager/index.ts, packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
Adds changeset; exports LAST_USED_WALLET_ID and persists it on connect/activation; adds defensive localStorage helpers getLastUsedWalletId() and getLastUsedSocialAuth().
Badge UI
packages/thirdweb/src/react/web/ui/components/badge.tsx
New LastUsedBadge component and LAST_USED_BADGE_VERTICAL_RESERVED_SPACE constant; small internal Badge helper with absolute positioning.
Wallet selector & row/button plumbing
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx, packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx, packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
Thread lastUsedBadge prop through components, conditionally render LastUsedBadge, add position: "relative" and adjust padding/spacing to reserve space for the badge.
Social auth & input UI
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx, packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx, packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
Read last-used social auth and wallet id, reorder auth options to surface last-used provider, render LastUsedBadge for matching social entries, add lastUsedBadge prop to inputs; disable badge in linking flows.
Wallet sorting
packages/thirdweb/src/react/web/utils/sortWallets.ts
Adds a sorting pass to prioritize the last-used wallet ahead of recommended wallets while preserving existing ordering passes.
Stories & tests
packages/thirdweb/src/stories/ConnectButton/others.stories.tsx, packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx, packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
Adds compact/wide modal story, renames/adjusts theme story colors, and updates tests to supply the new lastUsedBadge prop.

Sequence Diagram(s)

sequenceDiagram
  participant UI as Connect UI
  participant Selector as WalletSelector
  participant Sorter as sortWallets
  participant Storage as localStorage (helpers)
  participant Manager as Wallet Manager

  UI->>Storage: getLastUsedWalletId() / getLastUsedSocialAuth()
  Storage-->>UI: lastUsedWalletId / lastUsedSocialAuth
  UI->>Selector: render wallet list (include lastUsed flags)
  Selector->>Sorter: request sorted wallets
  Sorter-->>Selector: ordered wallet list
  Selector-->>UI: render wallet rows with lastUsedBadge where applicable
  UI->>Manager: user connects or sets active wallet
  Manager->>Storage: persist LAST_USED_WALLET_ID
  Storage-->>Manager: ack
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

🚥 Pre-merge checks | ✅ 2 | ❌ 3
❌ Failed checks (2 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The PR includes two minor out-of-scope changes: renaming the CustomBlack story to Custom and adding new Storybook stories for ConnectButton modal sizes (wide/compact), which are unrelated to the Last Used badge feature. Remove or separate the Storybook story renaming (themes.stories.tsx) and the new others.stories.tsx into a separate PR focused on Storybook improvements, keeping this PR focused solely on the Last Used badge feature.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive The description includes a detailed summary of changes from PR-Codex but lacks explicit sections for 'Notes for the reviewer' and 'How to test' specified in the template, though the PR-Codex overview provides substantial context. Add 'How to test' section with specific testing instructions (unit tests, Storybook, playground examples) and clarify any reviewer notes about implementation details or potential edge cases.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: adding a Last Used badge to the Connect UI. It includes the issue reference (MNY-233) and accurately reflects the primary objective of this changeset.
Linked Issues check ✅ Passed The PR successfully implements the core requirements from MNY-233: adds a Last Used badge component (badge.tsx), integrates it across wallet/auth UI components, implements sorting logic to prioritize last used wallets (sortWallets.ts), and tracks last used wallet/auth in storage.

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

✨ Finishing touches
  • 📝 Generate docstrings

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.

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

@github-actions github-actions bot added packages SDK Involves changes to the thirdweb SDK labels Jan 13, 2026
@MananTank MananTank marked this pull request as ready for review January 13, 2026 16:55
@MananTank MananTank requested review from a team as code owners January 13, 2026 16:55
Copy link
Contributor Author


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • merge-queue - adds this PR to the back of the merge queue
  • hotfix - for urgent hot fixes, skip the queue and merge this PR next

You must have a Graphite account in order to use the merge queue. Sign up using this link.

An organization admin has enabled the Graphite Merge Queue in this repository.

Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue.

This stack of pull requests is managed by Graphite. Learn more about stacking.

@MananTank MananTank changed the title [MNY-233] Add Last Used badge in Connect UI [MNY-233] SDK: Add Last Used badge in Connect UI Jan 13, 2026
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: 0

Caution

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

⚠️ Outside diff range comments (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (1)

222-237: Badge may display incorrectly when no wallet was previously used.

The condition lastUsedWalletId !== "inApp" && !lastUsedWalletId?.startsWith("ecosystem.") evaluates to true when lastUsedWalletId is null (no previous usage), causing the badge to appear on "Connect a Wallet" even when there's no last-used wallet.

🐛 Proposed fix to guard against null
     <WalletTypeRowButton
       className="tw-select-connect-a-wallet-button"
       lastUsedBadge={
+        !!lastUsedWalletId &&
         lastUsedWalletId !== "inApp" &&
         !lastUsedWalletId?.startsWith("ecosystem.")
       }
🧹 Nitpick comments (7)
packages/thirdweb/src/react/web/ui/components/badge.tsx (2)

32-47: Minor: Redundant cursor style.

The cursor: "default" on line 41 has no effect when pointerEvents: "none" is set, since the element won't receive pointer events anyway.

Suggested fix
       style={{
         position: "absolute",
         top: -10,
         right: -10,
         zIndex: 1,
         pointerEvents: "none",
-        cursor: "default",
       }}

49-49: Consider adding a brief comment for the constant.

The purpose of LAST_USED_BADGE_VERTICAL_RESERVED_SPACE may not be immediately clear to future maintainers. A short comment explaining it reserves space for the badge's overflow above the container would help.

Suggested improvement
+/** Vertical padding to reserve for the LastUsedBadge overflow above its container */
 export const LAST_USED_BADGE_VERTICAL_RESERVED_SPACE = 12;
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)

6-17: Add explicit return type annotation.

Per coding guidelines, functions should have explicit return types. This also documents the contract for consumers.

Suggested fix
-export function getLastUsedWalletId() {
+export function getLastUsedWalletId(): WalletId | null {

19-30: Add explicit return type and simplify the type cast.

The & string intersection is redundant—AuthArgsType["strategy"] is already a union of string literals ("email" | "phone" | "google" | "apple" | ... | "backend"). Remove it and add an explicit return type for consistency with the coding guidelines.

Suggested fix
-export function getLastUsedSocialAuth() {
+export function getLastUsedSocialAuth(): AuthArgsType["strategy"] | null {
   try {
     if (typeof window !== "undefined" && window.localStorage) {
       return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as
-        | (AuthArgsType["strategy"] & string)
+        | AuthArgsType["strategy"]
         | null;
     }
   } catch {
     // ignore
   }
   return null;
 }
packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx (1)

30-30: Consider making lastUsedBadge optional with a default value.

The prop is currently required, which means all existing callers of InputSelectionUI must be updated. Since this is marked @internal, the impact may be limited, but making it optional with a default of false would be more defensive.

Suggested change
-  lastUsedBadge: boolean;
+  lastUsedBadge?: boolean;

Then update line 77:

-        {props.lastUsedBadge && <LastUsedBadge />}
+        {props.lastUsedBadge === true && <LastUsedBadge />}
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)

16-16: Consider making lastUsedBadge optional for consistency.

Same suggestion as InputSelectionUI - making this optional with a default of false would be more defensive and consistent with typical React patterns for feature flags.

Suggested change
-  lastUsedBadge: boolean;
+  lastUsedBadge?: boolean;
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (1)

648-662: Consider extracting the "Last used" string for localization.

The badge text "Last used" is hardcoded here and in badge.tsx. For consistency with the existing locale pattern in this codebase, consider adding this string to the ConnectLocale type.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 5766c90 and 41ee2ec.

📒 Files selected for processing (13)
  • .changeset/three-fans-flow.md
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.) in TypeScript

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
packages/thirdweb/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g. const { jsPDF } = await import("jspdf");)

Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Biome governs formatting and linting; its rules live in biome.json. Run pnpm fix & pnpm lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Lazy-import optional features; avoid top-level side-effects

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Add Storybook stories (*.stories.tsx) alongside new UI components for documentation

Files:

  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
**/*.stories.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

For new UI components, add Storybook stories (*.stories.tsx) alongside the code

Files:

  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
🧬 Code graph analysis (6)
packages/thirdweb/src/react/web/ui/components/badge.tsx (3)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (156-164)
  • spacing (142-154)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
  • getLastUsedSocialAuth (19-30)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/wallets/types.ts (1)
  • authOptions (41-49)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LastUsedBadge (32-47)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (3)
packages/thirdweb/src/wallets/manager/index.ts (1)
  • LAST_USED_WALLET_ID (27-27)
packages/thirdweb/src/react/core/utils/storage.ts (1)
  • LAST_AUTH_PROVIDER_STORAGE_KEY (4-4)
packages/thirdweb/src/wallets/in-app/core/authentication/types.ts (1)
  • AuthArgsType (82-85)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LastUsedBadge (32-47)
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (5)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • spacing (142-154)
  • iconSize (166-176)
packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
  • IconButton (165-186)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LAST_USED_BADGE_VERTICAL_RESERVED_SPACE (49-49)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (20)
.changeset/three-fans-flow.md (1)

1-5: LGTM!

Changeset is properly formatted with an appropriate patch version bump for this new feature.

packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx (1)

31-40: LGTM!

The renamed Custom story with updated theme colors provides a cleaner example of dark theme customization, including the new borderColor property which aligns with the badge styling needs.

packages/thirdweb/src/stories/ConnectButton/others.stories.tsx (1)

1-34: LGTM!

Well-structured Storybook file following existing patterns. The WideModal and CompactModal stories provide good coverage for testing the modal size variations. This aligns with the coding guidelines to add stories alongside UI component changes.

packages/thirdweb/src/react/web/ui/components/badge.tsx (1)

5-30: LGTM!

The Badge component properly leverages design system tokens for spacing and radius. The hardcoded fontSize: 10 is acceptable for this small decorative element.

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx (1)

155-157: LGTM!

Setting lastUsedBadge={false} is appropriate here since this is a WalletConnect URI input field, not a wallet selection context where "Last Used" would be meaningful.

packages/thirdweb/src/react/web/utils/sortWallets.ts (1)

43-52: LGTM!

The sorting logic correctly uses stable sort chaining, where later sorts take precedence. The last-used wallet will properly appear before recommended wallets due to running after the recommended sort pass.

packages/thirdweb/src/wallets/manager/index.ts (2)

221-224: LGTM!

Correctly guards against storing "smart" as the last used wallet ID, preserving the underlying EOA wallet selection for UI display purposes.


152-152: The code correctly persists LAST_USED_WALLET_ID to localStorage. In web contexts, createConnectionManager() receives webLocalStorage, which wraps window.localStorage. Both the manager's storage.setItem() call and getLastUsedWalletId()'s direct read target the same window.localStorage object, so there is no storage mismatch.

packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx (1)

77-78: LGTM!

The conditional rendering integrates well with the existing InputContainer which already has position: "relative" (line 74), allowing the absolutely-positioned LastUsedBadge to render correctly.

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)

32-36: LGTM!

The position: "relative" addition correctly anchors the absolutely-positioned LastUsedBadge, and the conditional rendering pattern is clean.

packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (6)

34-39: LGTM!

Clean imports for the new last-used functionality.


105-106: LGTM!

Using useMemo with empty dependencies to read localStorage values once on mount is appropriate here, avoiding unnecessary re-reads while ensuring the values are stable throughout the component lifecycle.


149-163: LGTM!

The sorting logic correctly prioritizes the last-used auth option when the current wallet matches the last-used wallet ID. The guard condition on line 150 ensures we only reorder options when relevant.


396-401: LGTM!

The position: relative style correctly enables the absolute-positioned LastUsedBadge overlay. The badge condition correctly matches the wallet and auth method.


428-430: LGTM!

Badge condition correctly identifies when email was the last-used auth method for this wallet.


567-578: LGTM!

Explicitly setting lastUsedBadge={false} for the linking button is correct—linking is a special operation that shouldn't display the "Last used" badge.

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (4)

22-22: LGTM!

Clean import for the vertical spacing constant needed to accommodate the badge overlay.


536-560: LGTM!

The reworked back navigation block with explicit styling provides better control over the layout. The transform: translateX(-${spacing.xs}) compensates for the button's internal padding to maintain visual alignment.


613-622: LGTM!

Computing lastUsedWalletId via useMemo in WalletSelection is appropriate since it's a separate component from WalletSelectorInner. The dynamic paddingTop correctly reserves space for the badge in compact mode while avoiding unnecessary spacing in wide mode.


746-748: LGTM!

Increasing paddingInline to spacing.md provides adequate horizontal space for the badge overlay positioning.

@github-actions
Copy link
Contributor

github-actions bot commented Jan 13, 2026

size-limit report 📦

Path Size
@thirdweb-dev/nexus (esm) 105.66 KB (0%)
@thirdweb-dev/nexus (cjs) 319.47 KB (0%)

@codecov
Copy link

codecov bot commented Jan 13, 2026

Codecov Report

❌ Patch coverage is 25.16129% with 116 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.95%. Comparing base (5766c90) to head (97c0825).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ges/thirdweb/src/react/web/ui/components/badge.tsx 12.19% 36 Missing ⚠️
.../src/react/web/ui/ConnectWallet/WalletSelector.tsx 11.42% 31 Missing ⚠️
.../web/wallets/shared/ConnectWalletSocialOptions.tsx 24.32% 28 Missing ⚠️
...ckages/thirdweb/src/react/web/utils/sortWallets.ts 9.09% 10 Missing ⚠️
...eb/src/react/web/ui/ConnectWallet/Modal/storage.ts 63.63% 8 Missing ⚠️
...react/web/ui/ConnectWallet/WalletTypeRowButton.tsx 66.66% 1 Missing ⚠️
...nectWallet/screens/WalletConnectReceiverScreen.tsx 0.00% 1 Missing ⚠️
.../src/react/web/wallets/in-app/InputSelectionUI.tsx 50.00% 1 Missing ⚠️

❌ Your patch status has failed because the patch coverage (25.16%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8631      +/-   ##
==========================================
- Coverage   53.00%   52.95%   -0.06%     
==========================================
  Files         929      931       +2     
  Lines       62109    62239     +130     
  Branches     4077     4086       +9     
==========================================
+ Hits        32921    32958      +37     
- Misses      29089    29182      +93     
  Partials       99       99              
Flag Coverage Δ
packages 52.95% <25.16%> (-0.06%) ⬇️
Files with missing lines Coverage Δ
...c/react/web/ui/ConnectWallet/WalletEntryButton.tsx 12.62% <ø> (ø)
packages/thirdweb/src/wallets/manager/index.ts 90.94% <100.00%> (+0.09%) ⬆️
...react/web/ui/ConnectWallet/WalletTypeRowButton.tsx 96.42% <66.66%> (-3.58%) ⬇️
...nectWallet/screens/WalletConnectReceiverScreen.tsx 7.48% <0.00%> (-0.05%) ⬇️
.../src/react/web/wallets/in-app/InputSelectionUI.tsx 64.03% <50.00%> (-0.26%) ⬇️
...eb/src/react/web/ui/ConnectWallet/Modal/storage.ts 63.63% <63.63%> (ø)
...ckages/thirdweb/src/react/web/utils/sortWallets.ts 5.66% <9.09%> (+0.89%) ⬆️
.../web/wallets/shared/ConnectWalletSocialOptions.tsx 34.84% <24.32%> (-0.79%) ⬇️
.../src/react/web/ui/ConnectWallet/WalletSelector.tsx 9.33% <11.42%> (+0.17%) ⬆️
...ges/thirdweb/src/react/web/ui/components/badge.tsx 12.19% <12.19%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

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

🤖 Fix all issues with AI agents
In @packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx:
- Line 30: Tests are failing because the InputSelectionUI component now requires
the boolean prop lastUsedBadge; update the three render calls of
InputSelectionUI in InputSelectionUI.test.tsx to include a boolean value (e.g.,
lastUsedBadge={false} or lastUsedBadge={true}) so each test supplies the
required prop.
🧹 Nitpick comments (2)
packages/thirdweb/src/react/web/ui/components/badge.tsx (2)

20-24: Consider using design-system font size token.

The hardcoded fontSize: 10 could use a design-system token for consistency. However, if 10px is intentionally smaller than the smallest token, this is acceptable.

Suggested change
       <Text
         style={{
-          fontSize: 10,
+          fontSize: fontSize.xs, // or keep 10 if intentionally smaller
           whiteSpace: "nowrap",
         }}
       >

This would require importing fontSize from the design-system index.


40-41: Optional: Remove redundant cursor style.

The cursor: "default" style has no effect when pointerEvents: "none" is set, since the element won't receive any pointer events.

Suggested change
         zIndex: 1,
         pointerEvents: "none",
-        cursor: "default",
       }}
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 41ee2ec and 61e44c7.

📒 Files selected for processing (13)
  • .changeset/three-fans-flow.md
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
✅ Files skipped from review due to trivial changes (1)
  • .changeset/three-fans-flow.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.) in TypeScript

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose

Files:

  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
packages/thirdweb/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g. const { jsPDF } = await import("jspdf");)

Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)

Files:

  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

Add Storybook stories (*.stories.tsx) alongside new UI components for documentation

Files:

  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Biome governs formatting and linting; its rules live in biome.json. Run pnpm fix & pnpm lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Lazy-import optional features; avoid top-level side-effects

Files:

  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
**/*.stories.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

For new UI components, add Storybook stories (*.stories.tsx) alongside the code

Files:

  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
🧬 Code graph analysis (3)
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
  • getLastUsedSocialAuth (19-30)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/wallets/types.ts (1)
  • authOptions (41-49)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LastUsedBadge (32-47)
packages/thirdweb/src/react/web/ui/components/badge.tsx (3)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (156-164)
  • spacing (142-154)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Build Packages
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (9)
packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx (1)

31-40: LGTM!

The story rename from CustomBlack to Custom appropriately reflects the updated color scheme, and the new dark purple theme colors (#0c0a2e, #2f2987) provide a more visually distinct custom theme example. Adding borderColor is a nice addition to demonstrate additional theming capabilities.

packages/thirdweb/src/react/web/utils/sortWallets.ts (1)

3-3: LGTM! Last-used wallet sorting is correctly implemented.

The new sorting pass correctly prioritizes the last used wallet while preserving the existing sort order (in-app wallets still take precedence as the final sort pass). The synchronous localStorage read via getLastUsedWalletId() is acceptable here since it's a simple key lookup.

Also applies to: 14-14, 43-52

packages/thirdweb/src/wallets/manager/index.ts (1)

27-27: LGTM! Last-used wallet persistence is correctly integrated.

The LAST_USED_WALLET_ID is properly persisted in both connection flows (handleConnection and setActiveWallet), consistently storing the EOA wallet ID rather than smart wallet IDs. The await ensures proper async sequencing.

Also applies to: 151-152, 221-224

packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx (1)

77-78: LGTM! Badge placement is correct.

The LastUsedBadge is conditionally rendered inside the InputContainer which has position: relative, allowing the badge's absolute positioning to work correctly.

packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (4)

105-106: LGTM! Storage values are correctly memoized.

Using useMemo with an empty dependency array ensures the localStorage reads happen once on mount, avoiding unnecessary repeated reads during re-renders.


149-163: LGTM! Auth options sorting logic is correct.

The sorting correctly prioritizes the last used social auth only when the current wallet matches the last used wallet ID, preventing incorrect badge/ordering when switching between wallets.


396-401: LGTM! Badge integration for social buttons.

The position: "relative" style enables proper badge positioning, and the condition correctly shows the badge only when both wallet ID and auth method match the last used values.


567-578: LGTM! Linking button correctly excludes the badge.

The lastUsedBadge={false} is appropriate for the linking flow since it represents a distinct action rather than a "last used" sign-in method.

packages/thirdweb/src/react/web/ui/components/badge.tsx (1)

1-49: LGTM! Clean badge component implementation.

The component structure follows existing patterns well, with proper use of design-system tokens and absolute positioning for overlay behavior.

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

🤖 Fix all issues with AI agents
In @packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx:
- Around line 225-228: The badge logic for lastUsedBadge incorrectly shows when
lastUsedWalletId is null because null?.startsWith returns undefined and the
first truthy check fails; update the condition to explicitly ensure
lastUsedWalletId is not null/undefined before checking startsWith (e.g., use a
null check like lastUsedWalletId != null or Boolean(lastUsedWalletId) &&
!lastUsedWalletId.startsWith("ecosystem.") ) so lastUsedBadge is true only when
a real lastUsedWalletId exists and does not start with "ecosystem.".
🧹 Nitpick comments (3)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)

20-27: Consider using a design system token for font size.

The fontSize: 10 is hardcoded while other styling uses design system tokens. Consider using fontSize.xs or defining a token if 10px is intentional for badges.

packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (1)

400-401: Consider extracting the repeated badge condition.

The condition lastUsedWalletId === wallet.id && lastUsedSocialAuth === X is repeated across multiple components. Consider extracting a helper function to improve maintainability.

♻️ Suggested helper function
const isLastUsed = (authMethod: string) =>
  lastUsedWalletId === wallet.id && lastUsedSocialAuth === authMethod;

// Usage:
lastUsedBadge={isLastUsed("email")}
lastUsedBadge={isLastUsed("phone")}
// etc.

Also applies to: 428-430, 451-453, 475-477, 504-506, 520-522, 537-539, 553-555

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (1)

613-614: Consider passing lastUsedWalletId as a prop instead of recomputing.

WalletSelectorInner already computes this value at line 141. Passing it down as a prop would avoid the redundant useMemo call and make the data flow more explicit.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 61e44c7 and 10dfce2.

📒 Files selected for processing (14)
  • .changeset/three-fans-flow.md
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
✅ Files skipped from review due to trivial changes (1)
  • .changeset/three-fans-flow.md
🚧 Files skipped from review as they are similar to previous changes (6)
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/wallets/manager/index.ts
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.) in TypeScript

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
packages/thirdweb/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g. const { jsPDF } = await import("jspdf");)

Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Biome governs formatting and linting; its rules live in biome.json. Run pnpm fix & pnpm lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Lazy-import optional features; avoid top-level side-effects

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.test.{ts,tsx}: Place tests alongside code: foo.tsfoo.test.ts in the same directory
Use real function invocations with stub data in tests; avoid brittle mocks
Use Mock Service Worker (MSW) for fetch/HTTP call interception in tests
Keep tests deterministic and side-effect free
Use predefined test accounts from test/src/test-wallets.ts in tests
Use FORKED_ETHEREUM_CHAIN for mainnet interactions and ANVIL_CHAIN for isolated tests

**/*.test.{ts,tsx}: Co-locate tests with source files using the pattern foo.ts ↔ foo.test.ts
Use real function invocations with stub data in tests; avoid brittle mocks
For network interactions in tests, use Mock Service Worker (MSW) to intercept fetch/HTTP calls, mocking only scenarios that are hard to reproduce
Keep tests deterministic and side-effect free; Vitest is pre-configured

Files:

  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
🧬 Code graph analysis (4)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LastUsedBadge (32-47)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
  • getLastUsedSocialAuth (19-30)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/wallets/types.ts (1)
  • authOptions (41-49)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LastUsedBadge (32-47)
packages/thirdweb/src/react/web/utils/sortWallets.ts (1)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (4)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • spacing (142-154)
  • iconSize (166-176)
packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
  • IconButton (165-186)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LAST_USED_BADGE_VERTICAL_RESERVED_SPACE (49-49)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (12)
packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx (1)

18-18: LGTM!

Test updates correctly pass the new required lastUsedBadge prop. Setting it to false is appropriate since these tests focus on SMS country code functionality rather than badge behavior.

Also applies to: 35-35, 54-54

packages/thirdweb/src/react/web/utils/sortWallets.ts (1)

43-52: LGTM! The last-used prioritization is correctly placed.

The sorting chain ensures the final priority order is: in-app > last-used > recommended > installed. This correctly shows the last-used wallet at the top while still keeping in-app wallets highest priority.

packages/thirdweb/src/react/web/ui/components/badge.tsx (1)

32-47: LGTM!

The LastUsedBadge component is well-structured with appropriate absolute positioning and non-interactive styling (pointerEvents: "none").

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx (1)

16-16: LGTM!

Clean integration of the lastUsedBadge prop. The position: "relative" correctly enables the absolutely-positioned badge overlay.

Also applies to: 32-32, 36-36

packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)

105-106: LGTM!

Using useMemo with empty dependencies correctly computes these values once on mount, avoiding unnecessary localStorage reads on re-renders while preserving the initial last-used state throughout the component lifecycle.


149-163: LGTM!

The sorting logic correctly prioritizes the last-used social auth option only when the current wallet matches the last-used wallet ID. The early return on line 150-152 prevents unnecessary sorting when the context doesn't apply.


569-569: LGTM!

Correctly sets lastUsedBadge={false} for the linking button since it represents a different action flow and shouldn't display the last-used indicator.

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (5)

3-3: LGTM!

Imports are appropriate for the new "Last Used" badge functionality.

Also applies to: 22-22, 42-42


141-141: LGTM!

Memoizing with an empty dependency array correctly captures the last-used wallet ID at mount time, ensuring the badge reflects the state from before the current session.


507-560: LGTM!

Layout adjustments and the new back button UI for the expanded wallet group state are well-implemented. The padding changes appropriately accommodate the "Last Used" badge, and the back button provides a consistent navigation experience when the header is hidden.


621-622: LGTM!

The conditional padding reservation for compact mode and the badge prop logic for individual wallet entries are correctly implemented. The direct ID comparison ensures the badge only appears on the exact wallet that was last used.

Also applies to: 650-650


746-748: LGTM!

The paddingInline usage appropriately sets horizontal padding for the wallet list.

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

🧹 Nitpick comments (2)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)

32-47: Minor: cursor: "default" is redundant with pointerEvents: "none".

When pointerEvents: "none" is set, the element won't receive any pointer interactions, making cursor: "default" ineffective since the cursor style won't apply to a non-interactive element.

🧹 Suggested cleanup
       style={{
         position: "absolute",
         top: -10,
         right: -10,
         zIndex: 1,
         pointerEvents: "none",
-        cursor: "default",
       }}
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)

19-30: Consider simplifying the type assertion.

The & string intersection in (AuthArgsType["strategy"] & string) appears unnecessary since AuthArgsType["strategy"] should already resolve to a string union type. The intersection with string doesn't add type safety here.

🧹 Simplified type
 export function getLastUsedSocialAuth() {
   try {
     if (typeof window !== "undefined" && window.localStorage) {
-      return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as
-        | (AuthArgsType["strategy"] & string)
-        | null;
+      return window.localStorage.getItem(LAST_AUTH_PROVIDER_STORAGE_KEY) as
+        | AuthArgsType["strategy"]
+        | null;
     }
   } catch {
     // ignore
   }
   return null;
 }
📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 10dfce2 and 97c0825.

📒 Files selected for processing (14)
  • .changeset/three-fans-flow.md
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
💤 Files with no reviewable changes (1)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletEntryButton.tsx
🚧 Files skipped from review as they are similar to previous changes (9)
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.test.tsx
  • packages/thirdweb/src/react/web/wallets/in-app/InputSelectionUI.tsx
  • .changeset/three-fans-flow.md
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletTypeRowButton.tsx
  • packages/thirdweb/src/stories/ConnectButton/others.stories.tsx
  • packages/thirdweb/src/react/web/utils/sortWallets.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/WalletConnectReceiverScreen.tsx
  • packages/thirdweb/src/stories/ConnectButton/themes.stories.tsx
  • packages/thirdweb/src/wallets/manager/index.ts
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each TypeScript file to one stateless, single-responsibility function for clarity
Re-use shared types from @/types or local types.ts barrels
Prefer type aliases over interface except for nominal shapes in TypeScript
Avoid any and unknown in TypeScript unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.) in TypeScript

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each file to one stateless, single-responsibility function for clarity and testability
Re-use shared types from @/types or local types.ts barrel exports
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics whenever possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic in TypeScript files; avoid restating TypeScript types and signatures in prose

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
packages/thirdweb/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

packages/thirdweb/src/**/*.{ts,tsx}: Comment only ambiguous logic in SDK code; avoid restating TypeScript in prose
Load heavy dependencies inside async paths to keep initial bundle lean (e.g. const { jsPDF } = await import("jspdf");)

Lazy-load heavy dependencies inside async paths to keep the initial bundle lean (e.g., const { jsPDF } = await import('jspdf');)

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{js,jsx,ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Biome governs formatting and linting; its rules live in biome.json. Run pnpm fix & pnpm lint before committing, ensure there are no linting errors

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

Lazy-import optional features; avoid top-level side-effects

Files:

  • packages/thirdweb/src/react/web/ui/components/badge.tsx
  • packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts
  • packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx
🧬 Code graph analysis (3)
packages/thirdweb/src/react/web/ui/components/badge.tsx (3)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (156-164)
  • spacing (142-154)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
  • getLastUsedSocialAuth (19-30)
  • getLastUsedWalletId (6-17)
packages/thirdweb/src/wallets/types.ts (1)
  • authOptions (41-49)
packages/thirdweb/src/react/web/ui/components/badge.tsx (1)
  • LastUsedBadge (32-47)
packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (2)
packages/thirdweb/src/wallets/manager/index.ts (1)
  • LAST_USED_WALLET_ID (27-27)
packages/thirdweb/src/wallets/in-app/core/authentication/types.ts (1)
  • AuthArgsType (82-85)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (19)
packages/thirdweb/src/react/web/ui/components/badge.tsx (2)

1-30: LGTM! Badge component uses design tokens appropriately.

The internal Badge component correctly leverages the design system's radius.full, spacing["3xs"], and spacing.xs tokens for consistent styling.

Minor observation: Line 22 uses a hardcoded fontSize: 10 instead of a design-system token. Consider using fontSize.xs or similar if a matching token exists, though this may be intentional for the small badge size.


49-49: Verify the reserved space constant aligns with badge positioning.

The constant LAST_USED_BADGE_VERTICAL_RESERVED_SPACE = 12 is used to allocate space for the badge, but LastUsedBadge uses top: -10. Ensure that consumers applying this constant correctly account for the badge's full overflow (badge height + offset).

packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/storage.ts (1)

6-17: LGTM! Defensive localStorage access pattern.

The function correctly handles:

  • SSR environments (typeof window !== "undefined")
  • Missing localStorage (window.localStorage check)
  • Storage exceptions via try/catch
packages/thirdweb/src/react/web/wallets/shared/ConnectWalletSocialOptions.tsx (7)

105-106: LGTM! Proper memoization of localStorage reads.

Using useMemo with an empty dependency array ensures the localStorage values are read once on mount, which is appropriate since these values won't change during the component's lifecycle.


149-163: LGTM! Correct sorting logic to prioritize last-used auth method.

The sorting comparator correctly:

  • Only reorders when the current wallet matches the last-used wallet ID
  • Moves the last-used auth method to the front of the list
  • Preserves relative order of other items

396-411: LGTM! Badge integration on social login buttons.

The position: relative enables correct absolute positioning of the LastUsedBadge, and the conditional rendering correctly checks both wallet ID and auth method match.


424-463: LGTM! Consistent badge propagation for email input/button variants.

The lastUsedBadge prop is correctly passed to both InputSelectionUI and WalletTypeRowButton based on the same condition (lastUsedWalletId === wallet.id && lastUsedSocialAuth === "email"), ensuring consistent behavior regardless of which UI variant is rendered.


465-516: LGTM! Phone input badge integration follows the same pattern.

Consistent with the email implementation.


518-565: LGTM! Badge support for passkey, wallet, and guest login options.

Each auth method correctly compares against its respective strategy string ("passkey", "wallet", "guest").


567-578: LGTM! Linking flow correctly excludes the last-used badge.

Hardcoding lastUsedBadge={false} for the linking flow makes sense since linking a wallet is a distinct action from the user's previous sign-in method.

packages/thirdweb/src/react/web/ui/ConnectWallet/WalletSelector.tsx (9)

3-3: LGTM!

useMemo import added to support memoization of localStorage reads.


22-22: LGTM!

Import of the badge spacing constant for layout adjustments.


141-141: LGTM! Consistent memoization pattern.

Same pattern as in ConnectWalletSocialOptions.tsx - localStorage read memoized with empty deps.


222-238: LGTM! Correct badge condition for "Connect a Wallet" button.

The condition correctly excludes:

  • "inApp" wallets (handled separately in social options)
  • Ecosystem wallets (ecosystem.*) (also handled separately)

This prevents duplicate badges when the last-used wallet was an in-app or ecosystem wallet.


508-519: LGTM!

Header padding adjusted with design tokens.


536-562: Verify this back-navigation refactor is intentional.

This segment significantly restructures the back navigation UI with new Container nesting and IconButton styling. While the changes appear functional, they seem more extensive than what's needed for badge support. Consider confirming this is intentional as part of this PR or if it should be a separate change.


614-624: LGTM! Badge space reservation for wallet list.

The paddingTop correctly applies LAST_USED_BADGE_VERTICAL_RESERVED_SPACE in compact mode to prevent badge clipping, while wide mode uses 0 (likely handled differently in that layout).


649-663: LGTM! Badge passed to WalletEntryButton.

The badge prop uses a string value ("Last used") instead of a boolean, which aligns with WalletEntryButton's existing API that likely supports arbitrary badge text.


747-748: LGTM!

Padding adjustment for wallet list layout.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages SDK Involves changes to the thirdweb SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants