Skip to content

Conversation

@MananTank
Copy link
Member

@MananTank MananTank commented Oct 3, 2025


PR-Codex overview

This PR primarily focuses on enhancing the payment widget functionality within the thirdweb application. Key updates include making various properties optional, adding a receiver address field, and improving UI components for better usability.

Detailed summary

  • Added receiverAddress as an optional property in multiple components.
  • Made amount and chainId optional in the buy object.
  • Improved UI for token selection and wallet connection.
  • Enhanced FundWallet component to include initial selection for tokens.
  • Updated BuyWidget to handle new optional properties.
  • Refactored components for better readability and maintainability.
  • Introduced new sections for receiver wallet information and token balance display.

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

Summary by CodeRabbit

  • New Features

    • Receiver address input for Buy/Pay flows.
    • New compact wallet header, selectable token button, and improved decimal input for amounts.
    • Current balance shown and wallet disconnect option.
  • Improvements

    • Chain and amount can be optional; token and chain remain changeable.
    • Both fiat and token amounts editable; improved theming, responsive layouts, and story variants (light/dark).
    • Copy icon supports configurable size.
  • Documentation

    • Examples updated to reflect buy prefill changes.
  • Style

    • Simplified address text styling.

@linear
Copy link

linear bot commented Oct 3, 2025

@changeset-bot
Copy link

changeset-bot bot commented Oct 3, 2025

🦋 Changeset detected

Latest commit: e612f16

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

@vercel
Copy link

vercel bot commented Oct 3, 2025

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

Project Deployment Preview Comments Updated (UTC)
docs-v2 Ready Ready Preview Comment Oct 4, 2025 0:02am
nebula Ready Ready Preview Comment Oct 4, 2025 0:02am
thirdweb_playground Ready Ready Preview Comment Oct 4, 2025 0:02am
thirdweb-www Ready Ready Preview Comment Oct 4, 2025 0:02am
wallet-ui Ready Ready Preview Comment Oct 4, 2025 0:02am

@MananTank MananTank marked this pull request as ready for review October 3, 2025 22:23
@MananTank MananTank requested review from a team as code owners October 3, 2025 22:23
@github-actions github-actions bot added Playground Changes involving the Playground codebase. packages SDK Involves changes to the thirdweb SDK labels Oct 3, 2025
@MananTank MananTank changed the title SDK: BuyWidget Improvements [MNY-192] SDK: BuyWidget Improvements Oct 3, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 3, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Walkthrough

Relaxed BuyWidget/BridgeWidget prop requirements (amount/chain optional), removed locale, added onDisconnect; refactored FundWallet to accept initialSelection with token/chain/amount, added receiverAddress support across playgrounds and UI, introduced shared Bridge UI components/hooks, small type updates and story/readme adjustments.

Changes

Cohort / File(s) Summary
Changeset
/.changeset/slow-crews-thank.md
Adds changelog entry describing BuyWidget UI and behavior updates.
Playground: default options & receiver address
apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx, apps/playground-web/src/app/payments/components/types.ts, apps/playground-web/src/app/payments/components/LeftSection.tsx, apps/playground-web/src/app/payments/components/RightSection.tsx, apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx, apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx, apps/playground-web/src/app/payments/components/CodeGen.tsx
Adds optional receiverAddress to playground payOptions/defaultOptions; adds Receiver Address input in Buy UI and TokenSelector disableAddress usage; passes receiverAddress into BuyWidget and forces remount when buy options change; CodeGen emits receiverAddress conditionally.
Buy/Bridge widget API and wiring
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx, packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, packages/thirdweb/src/script-exports/bridge-widget-script.tsx
Makes buy amount and chain/chainId optional, makes buy optional on script API, removes locale prop from BuyWidget, adds onDisconnect callback; updates internal wiring to use optional chaining for buy fields.
FundWallet refactor
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
Replaces initialAmount/destinationToken props with initialSelection { tokenAddress?, chainId?, amount? }; introduces token selection modal, TokenSection, ReceiverWalletSection, balance UI, DetailsModal, getAmounts helper, mobile handling, and new public props theme and onDisconnect; signature changed to accept props object.
Shared Bridge UI components & hooks
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx, .../decimal-input.tsx, .../selected-token-button.tsx, .../token-balance.tsx, .../token-query.ts, .../WithHeader.tsx
Adds ActiveWalletDetails, DecimalInput, SelectedTokenButton, useTokenBalance hook; makes useTokenQuery guard when chainId is undefined; makes WithHeader.title optional and adjusts spacing.
Swap UI consolidation
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
Replaces local implementations (DecimalInput, SelectedTokenButton, ActiveWalletDetails, useTokenBalance, WalletButton) with shared common imports; updates styling.
Fiat currency type updates
packages/thirdweb/src/react/web/ui/Bridge/types.ts, packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
Changes fiat currency type from string to SupportedFiatCurrency and imports the type from pay/convert/type.js; updates formatCurrencyAmount signature.
ConnectWallet small changes
packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx, packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
Stops forwarding locale to BuyWidget in Details modal; hides modal close cross in buy screen; simplifies WalletRow primary text styling.
UI component enhancement
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
Adds optional iconSize?: number prop and uses it to size the copy/check icon.
Stories
packages/thirdweb/src/stories/BuyWidget.stories.tsx
Reworks stories to export multiple variants and introduces internal Variant wrapper rendering dark and light BuyWidget instances; updates story exports.
Script exports README
packages/thirdweb/src/script-exports/readme.md
Removes default buy chainId/amount examples and adds tokenAddress in examples.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Consumer
  participant BridgeWidget
  participant BuyWidget
  participant FundWallet
  participant Wallet as ActiveWallet
  participant TokenAPI as Token/Price Queries

  Consumer->>BridgeWidget: Render (buy { amount?, chainId?, receiverAddress? })
  BridgeWidget->>BuyWidget: Props (amount?, chain?, receiverAddress?, onDisconnect?)
  BuyWidget->>FundWallet: Render with initialSelection { tokenAddress?, chainId?, amount? } and receiverAddress
  FundWallet->>Wallet: Read active wallet info
  alt chainId provided
    FundWallet->>TokenAPI: Fetch tokens & prices (enabled)
  else chainId missing
    Note over FundWallet,TokenAPI: token queries disabled until chainId present
  end
  FundWallet-->>BuyWidget: Render UI (token select, DecimalInput, balance, receiver preview)
  BuyWidget-->>BridgeWidget: User interactions (select token/chain, edit amount, disconnect)
Loading
sequenceDiagram
  autonumber
  actor User
  participant FundWallet
  participant SelectToken as Token Select Modal
  participant Balance as useTokenBalance
  participant ENS as Receiver Preview

  User->>FundWallet: Open widget / Edit amount
  User->>FundWallet: Open token selector
  FundWallet->>SelectToken: Show tokens
  SelectToken-->>FundWallet: Select token { chainId, tokenAddress }
  FundWallet->>Balance: Query balance (native vs ERC-20)
  FundWallet->>ENS: Resolve receiver preview (if receiverAddress)
  FundWallet-->>User: Update UI (balance, amounts, action button)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Out of Scope Changes Check ⚠️ Warning The PR introduces several new features and UI components—such as receiverAddress fields, onDisconnect callbacks, ActiveWalletDetails, DecimalInput, SelectedTokenButton, CopyIcon sizing, and swap-widget refactoring—that are not part of the “Allow changing tokens/chains in BuyWidget” objective. Please separate unrelated enhancements into distinct PRs or reduce this PR to only include changes directly related to token and chain selection in the BuyWidget to maintain focused scope.
Description Check ⚠️ Warning The PR description includes only the template comment and a generated PR-Codex overview but does not fill in the required template sections for title, reviewer notes, or testing instructions. Please update the description to replace the PR template comment with an actual title following the format, provide content under “## Notes for the reviewer,” and include clear “## How to test” instructions to complete the required sections.
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title “[MNY-192] SDK: BuyWidget Improvements” accurately summarizes the primary focus of the changeset by highlighting enhancements to the BuyWidget in the SDK and follows the repository’s title format.
Linked Issues Check ✅ Passed The changes make chain and amount props optional and add UI components and logic that allow users to select and change tokens and chains in the BuyWidget, satisfying the objectives of MNY-192.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch mny-192

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.

Copy link
Member 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.

@github-actions
Copy link
Contributor

github-actions bot commented Oct 3, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.6 KB (0%) 1.3 s (0%) 291 ms (+56.83% 🔺) 1.6 s
thirdweb (cjs) 365.75 KB (0%) 7.4 s (0%) 1.6 s (+0.52% 🔺) 8.9 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 104 ms (+930.88% 🔺) 219 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 40 ms (+386.83% 🔺) 51 ms
thirdweb/react (minimal + tree-shaking) 19.13 KB (0%) 383 ms (0%) 90 ms (+1147.49% 🔺) 472 ms

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (6)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)

67-69: Consider monospace font for address display.

Removing monospace styling may reduce readability for blockchain addresses. Monospace fonts help users visually verify addresses by preventing character confusion (0/O, 1/I/l) and maintaining consistent spacing. While the addresses are shortened here, applying fontFamily: "monospace" or weight: 500 to the Text component when displaying non-ENS addresses could improve UX.

If desired, apply this diff to restore monospace for addresses only:

-          <Text color="primaryText" size={props.textSize || "xs"}>
+          <Text 
+            color="primaryText" 
+            size={props.textSize || "xs"}
+            style={ensNameQuery.data ? {} : { fontFamily: "monospace" }}
+          >
             {addressOrENS || shortenAddress(props.address)}
           </Text>
packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1)

19-23: Defensive guard is redundant but acceptable.

The enabled: !!params.chainId flag on line 19 prevents the query from executing when chainId is undefined, so the runtime guard on lines 21-23 should never be reached. However, this defensive check provides an extra safety layer and explicit error messaging if the query somehow executes despite the guard.

If you prefer strictly minimal code, you could remove the runtime guard since the enabled flag already prevents execution:

   return useQuery({
     enabled: !!params.chainId,
     queryFn: async (): Promise<TokenQueryResult> => {
-      if (!params.chainId) {
-        throw new Error("Chain ID is required");
-      }
+      // chainId is guaranteed by enabled flag
       const tokenAddress = params.tokenAddress || NATIVE_TOKEN_ADDRESS;

However, keeping it provides clearer error messages if the query logic changes in the future.

apps/playground-web/src/app/payments/components/RightSection.tsx (1)

71-75: Consider if forced remounting is necessary.

The dynamic key forces the BuyWidget to fully remount whenever amount, chain, or tokenAddress changes. This can:

  • Cause unnecessary re-initialization overhead
  • Reset internal widget state (selection, validation, etc.)
  • Create a brief flicker in the UI

Verify whether BuyWidget properly handles prop updates internally. If it does, the forced remount may be unnecessary:

#!/bin/bash
# Check if BuyWidget uses useEffect to handle prop changes
ast-grep --pattern $'function BuyWidget($$$) {
  $$$
  useEffect($$$, [$$$amount$$$])
  $$$
}' 

If BuyWidget doesn't react to prop changes, the current approach is correct. Otherwise, consider removing the key and letting React's reconciliation handle updates naturally.

packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (3)

48-48: Remove commented-out import.

The commented import TokenAndChain should be removed if it's no longer needed to keep the codebase clean.

Apply this diff:

-// import { TokenAndChain } from "./common/TokenAndChain.js";

344-366: Add explicit return type and validation for number conversions.

The getAmounts helper performs Number() conversions on lines 352 and 359 without validating the result. While DecimalInput should prevent invalid input, adding an explicit return type and NaN checks would improve type safety and prevent potential runtime issues.

Apply this diff:

 function getAmounts(
   amountSelection: AmountSelection,
   fiatPricePerToken: number | undefined,
-) {
+): { fiatValue: string | number | undefined; tokenValue: string | number | undefined } {
   const fiatValue =
     amountSelection.type === "usd"
       ? amountSelection.value
       : fiatPricePerToken
-        ? fiatPricePerToken * Number(amountSelection.value)
+        ? (() => {
+            const num = Number(amountSelection.value);
+            return Number.isNaN(num) ? undefined : fiatPricePerToken * num;
+          })()
         : undefined;
 
   const tokenValue =
     amountSelection.type === "token"
       ? amountSelection.value
       : fiatPricePerToken
-        ? Number(amountSelection.value) / fiatPricePerToken
+        ? (() => {
+            const num = Number(amountSelection.value);
+            return Number.isNaN(num) ? undefined : num / fiatPricePerToken;
+          })()
         : undefined;
 
   return {
     fiatValue,
     tokenValue,
   };
 }

493-511: Consider UX for fiat input when price data is unavailable.

On line 494, when fiatValue is undefined (e.g., no price data available), the fiat input displays "0". This could be confusing for users who might think the token is worthless. Consider showing an empty string, a placeholder, or disabling the input when fiatPricePerToken is unavailable.

Apply this diff to show empty input when price unavailable:

           <DecimalInput
-            value={String(fiatValue || 0)}
+            value={fiatValue !== undefined ? String(fiatValue) : ""}
             setValue={(value) => {
               props.setAmount({
                 type: "usd",
                 value,
               });
             }}
📜 Review details

Configuration used: CodeRabbit 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 4a30b9c and 943d0e8.

📒 Files selected for processing (25)
  • .changeset/slow-crews-thank.md (1 hunks)
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/LeftSection.tsx (4 hunks)
  • apps/playground-web/src/app/payments/components/RightSection.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/types.ts (1 hunks)
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (12 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (0 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2 hunks)
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1 hunks)
  • packages/thirdweb/src/script-exports/readme.md (1 hunks)
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx (8 hunks)
💤 Files with no reviewable changes (1)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Write idiomatic TypeScript with explicit function declarations and return types
Limit each 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
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size

Files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
  • apps/playground-web/src/app/payments/components/LeftSection.tsx
  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • apps/playground-web/src/app/payments/components/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
  • apps/playground-web/src/app/payments/components/LeftSection.tsx
  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • apps/playground-web/src/app/payments/components/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
packages/thirdweb/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/thirdweb/**/*.{ts,tsx}: Every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g., const { jsPDF } = await import("jspdf"))

Files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
**/types.ts

📄 CodeRabbit inference engine (AGENTS.md)

Provide and re‑use local type barrels in a types.ts file

Files:

  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • apps/playground-web/src/app/payments/components/types.ts
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
  • apps/playground-web/src/app/payments/components/LeftSection.tsx
  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx
  • apps/playground-web/src/app/payments/components/types.ts
.changeset/*.md

📄 CodeRabbit inference engine (AGENTS.md)

.changeset/*.md: Each change in packages/* must include a changeset for the appropriate package
Version bump rules: patch for non‑API changes; minor for new/modified public API

Files:

  • .changeset/slow-crews-thank.md
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
🧠 Learnings (2)
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
🧬 Code graph analysis (12)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (20)
packages/thirdweb/src/exports/react.ts (3)
  • Theme (6-6)
  • ConnectButton (161-161)
  • useEnsName (119-119)
packages/thirdweb/src/react/core/design-system/index.ts (5)
  • Theme (49-96)
  • spacing (174-186)
  • fontSize (164-172)
  • radius (188-196)
  • iconSize (198-208)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/exports/utils.ts (2)
  • checksumAddress (146-146)
  • shortenAddress (149-149)
packages/thirdweb/src/exports/thirdweb.ts (2)
  • NATIVE_TOKEN_ADDRESS (31-31)
  • ThirdwebClient (25-25)
packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1)
  • useTokenQuery (13-49)
packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1)
  • useTokenBalance (7-23)
packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (1)
  • WithHeader (9-66)
packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (1)
  • DetailsModal (372-1034)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
  • Modal (32-164)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx (1)
  • SelectToken (58-130)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/pay/convert/type.ts (2)
  • SupportedFiatCurrency (27-27)
  • getFiatSymbol (29-31)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/use-bridge-chains.ts (1)
  • useBridgeChains (5-14)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-94)
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1)
  • SelectedTokenButton (19-168)
packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1)
  • DecimalInput (5-57)
packages/thirdweb/src/react/web/ui/components/Skeleton.tsx (1)
  • Skeleton (10-28)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
  • formatTokenAmount (26-35)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (1)
  • CopyIcon (10-61)
packages/thirdweb/src/react/web/ui/Bridge/types.ts (1)
packages/thirdweb/src/pay/convert/type.ts (1)
  • SupportedFiatCurrency (27-27)
apps/playground-web/src/app/payments/components/LeftSection.tsx (1)
packages/thirdweb/src/react/web/ui/components/formElements.tsx (2)
  • Label (20-28)
  • Input (37-110)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (4)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/types.ts (1)
  • ActiveWalletInfo (140-144)
packages/thirdweb/src/react/core/design-system/index.ts (4)
  • iconSize (198-208)
  • radius (188-196)
  • spacing (174-186)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/exports/utils.ts (1)
  • shortenAddress (149-149)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
packages/thirdweb/src/pay/convert/type.ts (1)
  • SupportedFiatCurrency (27-27)
packages/thirdweb/src/stories/BuyWidget.stories.tsx (2)
packages/thirdweb/src/stories/utils.tsx (1)
  • storyClient (14-16)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
  • BuyWidgetProps (45-209)
  • BuyWidget (321-370)
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (6)
packages/thirdweb/src/exports/thirdweb.ts (1)
  • ThirdwebClient (25-25)
packages/thirdweb/src/bridge/types/Chain.ts (1)
  • BridgeChain (42-42)
packages/thirdweb/src/react/core/design-system/index.ts (4)
  • spacing (174-186)
  • radius (188-196)
  • iconSize (198-208)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/utils.ts (1)
  • cleanedChainName (1-3)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (2)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (188-196)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-94)
packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1)
packages/thirdweb/src/exports/thirdweb.ts (1)
  • ThirdwebClient (25-25)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1)
packages/ui/src/components/input.tsx (1)
  • InputProps (4-5)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (3)
packages/thirdweb/src/bridge/types/Chain.ts (1)
  • Chain (5-40)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
  • FundWallet (136-347)
🪛 Gitleaks (8.28.0)
packages/thirdweb/src/stories/BuyWidget.stories.tsx

[high] 29-29: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 138-138: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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: Size
  • GitHub Check: Unit Tests
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (28)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2)

16-16: LGTM!

The optional iconSize prop is a clean addition that maintains backward compatibility with the default size of 16.


44-54: LGTM!

The sizing logic is consistently applied to both icons with an appropriate fallback to 16. The implementation maintains visual consistency between the copy and check states.

.changeset/slow-crews-thank.md (1)

1-11: LGTM!

The changeset accurately describes the BuyWidget improvements implemented in this PR, including the optional props, enhanced UI capabilities, and new features.

packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2)

11-11: LGTM!

Making the title optional aligns with the PR's theme of relaxing widget prop requirements, allowing more flexible usage scenarios.


37-37: Minor spacing adjustment noted.

The spacing change from "md+" to "md" is a minor visual refinement with no functional impact.

packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1)

1-23: LGTM!

The useTokenBalance hook correctly delegates to useWalletBalance and properly distinguishes between native token balances (passing undefined for tokenAddress) and ERC-20 token balances (passing the normalized address). The ternary logic at lines 17-20 handles all three cases correctly:

  • Native token explicitly specified → undefined
  • ERC-20 token specified → normalized address
  • No token specified → undefined (defaults to native)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (4)

121-131: LGTM! Optional props improve flexibility.

Making chain and amount optional (lines 121, 131) enhances widget flexibility, allowing users to select these values within the widget UI rather than requiring them upfront. This aligns with the PR objectives.


205-208: LGTM! Disconnect callback added.

The onDisconnect callback provides a proper hook for handling wallet disconnection events from the widget. The typo from the previous review has been correctly fixed to onDisconnect.


482-486: LGTM! Initial selection properly handles optional values.

The initialSelection object correctly passes through the optional tokenAddress, chainId, and amount values to FundWallet, maintaining the optional prop semantics throughout the component hierarchy.


457-489: Verify wallet-disconnection behavior

The condition if (screen.id === "1:buy-ui" || !activeWalletInfo) forces users back to the FundWallet screen whenever activeWalletInfo is undefined, even if they’re mid-flow. No disconnection-handling patterns were found in packages/thirdweb/src/react/web/ui/Bridge. Confirm whether you want to preserve user progress on temporary wallet disconnects or always reset to FundWallet.

apps/playground-web/src/app/payments/components/RightSection.tsx (1)

70-70: LGTM! Receiver address support added.

The receiverAddress prop is correctly wired through from the playground options to the BuyWidget, enabling the receiver address feature in the playground UI.

packages/thirdweb/src/script-exports/readme.md (1)

59-62: LGTM! Documentation reflects API changes.

The addition of tokenAddress to the buy configuration example correctly documents the new capability for specifying which token to purchase in the bridge widget script API.

apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1)

21-21: LGTM! Consistent playground option extension.

Adding receiverAddress: undefined to the default options maintains consistency with the broader playground changes and enables the receiver address feature in the checkout playground.

apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1)

23-23: LGTM! Consistent addition of receiverAddress field.

The addition of receiverAddress: undefined to defaultOptions.payOptions aligns with the broader PR changes introducing receiver address support across playground components.

apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (1)

20-20: LGTM! Consistent addition of receiverAddress field.

The addition of receiverAddress: undefined to defaultOptions.payOptions is consistent with the broader PR pattern of introducing receiver address support across playground components.

apps/playground-web/src/app/payments/components/types.ts (1)

51-51: LGTM! Type definition for receiverAddress field.

The addition of receiverAddress: Address | undefined to the payOptions type is well-placed alongside sellerAddress and correctly typed as optional.

packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1)

44-46: LGTM! API relaxation for optional buy configuration.

Making buy and its amount and chainId fields optional provides more flexibility for consumers who may want to configure the bridge widget without pre-filling buy parameters. This aligns with the broader PR changes to relax BuyWidget requirements.

packages/thirdweb/src/react/web/ui/Bridge/types.ts (2)

2-2: LGTM! Import added for type strengthening.

Adding the SupportedFiatCurrency import enables stronger typing for the currency field in the fiat PaymentMethod variant.


45-45: LGTM! Type strengthening from string to SupportedFiatCurrency.

Changing the currency field from string to SupportedFiatCurrency provides better type safety and aligns with the defined set of supported currencies in the pay module.

apps/playground-web/src/app/payments/components/LeftSection.tsx (4)

143-143: LGTM! Disable address input in token selector.

Adding disableAddress prop to TokenSelector is appropriate for the playground context where address input may not be needed.


158-161: LGTM! Layout spacing adjustments.

The removal of "my-2" class and the increase of Buy mode spacing from "space-y-4" to "space-y-6" improves visual hierarchy to accommodate the new Receiver Address field.


181-203: LGTM! Well-structured Receiver Address UI block.

The new Receiver Address input is properly:

  • Conditionally rendered for Buy mode only
  • Labeled with clear helper text
  • Bound to payOptions.receiverAddress via onChange
  • Using an appropriate placeholder

234-234: LGTM! Cleanup of extra whitespace.

Removing the extra whitespace div improves code cleanliness.

packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (2)

21-94: LGTM! Well-structured wallet details component.

The ActiveWalletDetails component is well-designed with proper use of:

  • Design system tokens for consistent styling
  • Nested providers to establish wallet/account context
  • Appropriate fallback components for avatar and name
  • Clean separation of concerns

96-105: LGTM! Styled button with proper hover effects.

The WalletButton styled component properly uses theme colors and implements smooth hover transitions.

packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2)

152-160: LGTM! API relaxation for optional buy configuration.

Making buy and its amount and chainId fields optional provides flexibility for use cases where buy parameters may not be pre-configured. This change aligns with the broader PR objective of relaxing BuyWidget prop requirements.


294-310: LGTM! Proper handling of optional buy fields.

The BuyWidget rendering correctly handles the optional buy configuration using:

  • Optional chaining for all buy-derived props (buy?.amount, buy?.tokenAddress, etc.)
  • Conditional logic for chain prop (undefined when buy?.chainId is absent)
  • Maintains required props (client, theme, currency, etc.)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)

287-307: Type safety is correct: guard clauses narrow receiver to a string and ensure tokenValue is defined; String(tokenValue) safely handles both number and string.

Likely an incorrect or invalid review comment.

@codecov
Copy link

codecov bot commented Oct 3, 2025

Codecov Report

❌ Patch coverage is 8.33333% with 704 lines in your changes missing coverage. Please review.
✅ Project coverage is 55.03%. Comparing base (4a30b9c) to head (e612f16).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...es/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx 5.03% 434 Missing ⚠️
...act/web/ui/Bridge/common/selected-token-button.tsx 8.00% 115 Missing ⚠️
...act/web/ui/Bridge/common/active-wallet-details.tsx 17.28% 67 Missing ⚠️
...b/src/react/web/ui/Bridge/common/decimal-input.tsx 4.44% 43 Missing ⚠️
...ges/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx 10.00% 18 Missing ⚠️
...b/src/react/web/ui/Bridge/common/token-balance.tsx 29.41% 12 Missing ⚠️
.../thirdweb/src/react/web/ui/components/CopyIcon.tsx 50.00% 5 Missing ⚠️
...dweb/src/react/web/ui/Bridge/common/token-query.ts 0.00% 4 Missing ⚠️
...web/ui/ConnectWallet/screens/formatTokenBalance.ts 25.00% 3 Missing ⚠️
...dweb/src/react/web/ui/Bridge/common/WithHeader.tsx 0.00% 1 Missing ⚠️
... and 2 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8181      +/-   ##
==========================================
- Coverage   56.07%   55.03%   -1.04%     
==========================================
  Files         905      919      +14     
  Lines       59228    60562    +1334     
  Branches     4124     4125       +1     
==========================================
+ Hits        33212    33333     +121     
- Misses      25912    27126    +1214     
+ Partials      104      103       -1     
Flag Coverage Δ
packages 55.03% <8.33%> (-1.04%) ⬇️
Files with missing lines Coverage Δ
...dweb/src/react/web/ui/Bridge/common/WithHeader.tsx 12.96% <0.00%> (ø)
...hirdweb/src/react/web/ui/ConnectWallet/Details.tsx 57.92% <66.66%> (+0.07%) ⬆️
...eb/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx 20.00% <0.00%> (+0.88%) ⬆️
...web/ui/ConnectWallet/screens/formatTokenBalance.ts 35.13% <25.00%> (-3.11%) ⬇️
...dweb/src/react/web/ui/Bridge/common/token-query.ts 11.42% <0.00%> (-1.48%) ⬇️
.../thirdweb/src/react/web/ui/components/CopyIcon.tsx 74.41% <50.00%> (-5.59%) ⬇️
...b/src/react/web/ui/Bridge/common/token-balance.tsx 29.41% <29.41%> (ø)
...ges/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx 5.82% <10.00%> (-0.19%) ⬇️
...b/src/react/web/ui/Bridge/common/decimal-input.tsx 4.44% <4.44%> (ø)
...act/web/ui/Bridge/common/active-wallet-details.tsx 17.28% <17.28%> (ø)
... and 2 more

... and 15 files with indirect coverage changes

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

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/Bridge/common/WithHeader.tsx (1)

9-15: Add comprehensive TSDoc for public component.

Per coding guidelines, every public symbol in packages/thirdweb/**/*.{ts,tsx} must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.). The WithHeader component is exported and appears to be part of the public API.

As per coding guidelines.

Apply this diff to add TSDoc:

+/**
+ * A wrapper component that renders content with an optional header section containing an image, title, and description.
+ * 
+ * @example
+ * ```tsx
+ * import { WithHeader } from "@thirdweb-dev/react";
+ * 
+ * function MyComponent({ client }: { client: ThirdwebClient }) {
+ *   return (
+ *     <WithHeader
+ *       title="Bridge Funds"
+ *       description="Transfer assets across chains"
+ *       image="ipfs://..."
+ *       client={client}
+ *     >
+ *       <div>Your content here</div>
+ *     </WithHeader>
+ *   );
+ * }
+ * ```
+ * 
+ * @beta
+ */
 export function WithHeader(props: {
🧹 Nitpick comments (4)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (1)

16-16: Document the new iconSize prop.

While the component is marked @internal, adding TSDoc for the new prop improves maintainability and aligns with the coding guidelines for this package.

Consider adding documentation:

 export const CopyIcon: React.FC<{
   text: string;
   tip: string;
   side?: "top" | "bottom" | "left" | "right";
   align?: "start" | "center" | "end";
   hasCopied?: boolean;
+  /** Optional size for the icon in pixels. Defaults to 16. */
   iconSize?: number;
 }> = (props) => {
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)

67-67: Verify that removing monospace styling aligns with design intent.

The removal of inline fontFamily and fontWeight props simplifies styling, but addresses are typically rendered in monospace fonts to improve character-by-character readability during verification. Confirm that this change is intentional and consistent with the design system's approach to displaying wallet addresses across the application.

If monospace styling is still desired, consider adding a monospace or fontFamily prop to the Text component rather than using inline styles:

<Text color="primaryText" size={props.textSize || "xs"} monospace>
  {addressOrENS || shortenAddress(props.address)}
</Text>

Alternatively, if the design system intentionally moved away from monospace for addresses, ensure this change is documented and applied consistently across all address display components.

packages/thirdweb/src/react/web/ui/Bridge/types.ts (1)

45-45: Good type strengthening for fiat currency.

Changing from string to SupportedFiatCurrency improves type safety by restricting the currency field to valid fiat currency codes defined in the pay module. This prevents invalid currency strings at compile time.

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (1)

750-763: Consider style variant props for DecimalInput.

The component requires extensive inline style overrides (border, boxShadow, fontSize, padding, etc.) at multiple usage sites. This pattern suggests DecimalInput might benefit from accepting style variant props to reduce boilerplate.

This is not critical for the current PR but could improve developer ergonomics in future iterations.

📜 Review details

Configuration used: CodeRabbit 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 cf6d447 and 7adce2d.

📒 Files selected for processing (26)
  • .changeset/slow-crews-thank.md (1 hunks)
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/CodeGen.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/LeftSection.tsx (4 hunks)
  • apps/playground-web/src/app/payments/components/RightSection.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/types.ts (1 hunks)
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (12 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (0 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2 hunks)
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1 hunks)
  • packages/thirdweb/src/script-exports/readme.md (1 hunks)
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx (8 hunks)
💤 Files with no reviewable changes (1)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
✅ Files skipped from review due to trivial changes (1)
  • .changeset/slow-crews-thank.md
🚧 Files skipped from review as they are similar to previous changes (9)
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx
  • apps/playground-web/src/app/payments/components/LeftSection.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
🧰 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 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
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size

Files:

  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • apps/playground-web/src/app/payments/components/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • apps/playground-web/src/app/payments/components/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
  • apps/playground-web/src/app/payments/components/types.ts
packages/thirdweb/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/thirdweb/**/*.{ts,tsx}: Every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g., const { jsPDF } = await import("jspdf"))

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
**/types.ts

📄 CodeRabbit inference engine (AGENTS.md)

Provide and re‑use local type barrels in a types.ts file

Files:

  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • apps/playground-web/src/app/payments/components/types.ts
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
🧠 Learnings (2)
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
🧬 Code graph analysis (8)
apps/playground-web/src/app/payments/components/CodeGen.tsx (1)
apps/playground-web/src/lib/code-gen.ts (1)
  • quotes (17-19)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/ui/Bridge/types.ts (1)
packages/thirdweb/src/pay/convert/type.ts (1)
  • SupportedFiatCurrency (27-27)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (4)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/types.ts (1)
  • ActiveWalletInfo (140-144)
packages/thirdweb/src/react/core/design-system/index.ts (4)
  • iconSize (198-208)
  • radius (188-196)
  • spacing (174-186)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/exports/utils.ts (1)
  • shortenAddress (149-149)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (18)
packages/thirdweb/src/exports/react.ts (3)
  • Theme (6-6)
  • ConnectButton (161-161)
  • useEnsName (119-119)
packages/thirdweb/src/react/core/design-system/index.ts (5)
  • Theme (49-96)
  • spacing (174-186)
  • fontSize (164-172)
  • radius (188-196)
  • iconSize (198-208)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/exports/utils.ts (2)
  • checksumAddress (146-146)
  • shortenAddress (149-149)
packages/thirdweb/src/exports/thirdweb.ts (1)
  • NATIVE_TOKEN_ADDRESS (31-31)
packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1)
  • useTokenQuery (13-49)
packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1)
  • useTokenBalance (7-23)
packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (1)
  • WithHeader (9-66)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
  • Modal (32-164)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/select-token-ui.tsx (1)
  • SelectToken (58-130)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/types.ts (1)
  • ActiveWalletInfo (140-144)
packages/thirdweb/src/pay/convert/type.ts (2)
  • SupportedFiatCurrency (27-27)
  • getFiatSymbol (29-31)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/use-bridge-chains.ts (1)
  • useBridgeChains (5-14)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-92)
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1)
  • SelectedTokenButton (19-168)
packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1)
  • DecimalInput (5-61)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
  • formatTokenAmount (26-35)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (1)
  • CopyIcon (10-61)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
  • FundWallet (136-342)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (2)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (188-196)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-92)
packages/thirdweb/src/stories/BuyWidget.stories.tsx (2)
packages/thirdweb/src/stories/utils.tsx (1)
  • storyClient (14-16)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
  • BuyWidgetProps (45-209)
  • BuyWidget (321-370)
🪛 Gitleaks (8.28.0)
packages/thirdweb/src/stories/BuyWidget.stories.tsx

[high] 29-29: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 138-138: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

packages/thirdweb/src/script-exports/readme.md

[high] 61-61: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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). (6)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (21)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2)

44-48: LGTM!

The CheckIcon correctly uses the iconSize prop with a sensible default of 16, maintaining backward compatibility.


50-54: LGTM!

The CopyIconSVG correctly uses the iconSize prop with a sensible default of 16, maintaining consistency with CheckIcon.

packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2)

11-11: LGTM: Title prop now optional.

The type change from string to string | undefined is backward compatible and aligns with the PR's goal of making fields optional across Bridge components. The existing conditional rendering logic (line 42) already handles undefined values correctly.


37-37: Spacing refinement applied.

The change from "md+" to "md" reduces vertical spacing slightly. This appears to be an intentional UI polish adjustment.

packages/thirdweb/src/script-exports/readme.md (1)

58-62: Documentation correctly reflects the updated buy configuration.

The addition of tokenAddress to the buy configuration aligns with the broader PR changes that make amount and chainId optional in the buy block. The example demonstrates the correct usage pattern.

Note: The static analysis tool flagged line 61 as a potential API key, but this is a false positive—it's a valid Ethereum token address (Base USDC: 0x833589fcd6edb6e08f4c7c32d4f71b54bda02913).

apps/playground-web/src/app/payments/components/CodeGen.tsx (1)

121-127: LGTM—Conditional logic for seller and receiverAddress is correct.

The seller field is now properly restricted to the "checkout" widget, and the receiverAddress field is correctly handled with optional quoting. This aligns with the broader type changes that add receiverAddress to the playground options surface.

packages/thirdweb/src/react/web/ui/Bridge/types.ts (1)

2-2: LGTM—Import added for stronger currency typing.

apps/playground-web/src/app/payments/components/RightSection.tsx (2)

70-70: LGTM—receiverAddress prop correctly passed through.


71-75: Consider including receiverAddress in the remount key.

The dynamic key forces a BuyWidget remount when amount, chain, or tokenAddress changes. However, receiverAddress is also a BuyWidget prop that might benefit from triggering a remount when changed.

Should receiverAddress be included in the key to ensure the widget remounts when the receiver address changes? If the BuyWidget internally handles receiverAddress changes without requiring a remount, the current approach is fine. Otherwise, consider:

 key={JSON.stringify({
   amount: props.options.payOptions.buyTokenAmount,
   chain: props.options.payOptions.buyTokenChain,
   tokenAddress: props.options.payOptions.buyTokenAddress,
+  receiverAddress: props.options.payOptions.receiverAddress,
 })}
apps/playground-web/src/app/payments/components/types.ts (1)

51-51: LGTM—receiverAddress field correctly added to playground options.

The optional receiverAddress field with Address | undefined type aligns with the broader PR changes that add receiver address support across the playground and BuyWidget components.

packages/thirdweb/src/stories/BuyWidget.stories.tsx (3)

5-8: LGTM—Imports updated for typed Variant wrapper.


19-55: Good addition of new story variants.

The new stories (Basic, PayAnotherWallet, JPYCurrency, NoThirdwebBranding) provide comprehensive coverage of the updated BuyWidget API, including the new receiverAddress prop demonstrated in PayAnotherWallet.

Note: Static analysis flagged line 29 as a potential API key, but this is a false positive—it's a valid Ethereum token address (Base USDC).


144-151: LGTM—Variant wrapper enables theme comparison.

The Variant component pattern provides a clean way to render both dark and light themes side-by-side for visual comparison in Storybook. This improves the developer experience when working with themed components.

packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2)

152-160: LGTM—buy configuration fields correctly made optional.

The amount and chainId fields in the buy configuration are now optional, aligning with the PR objectives to relax BuyWidget prop requirements. This enables more flexible buy configurations where users can omit these fields.


294-310: Optional chaining correctly applied for buy fields.

The BuyWidget usage properly accesses all buy fields via optional chaining (props.buy?.amount, props.buy?.tokenAddress, etc.), ensuring safe access when buy configuration is undefined or fields are omitted. The chain handling correctly returns undefined when chainId is absent.

packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1)

44-46: LGTM—Script export types correctly updated for optional buy configuration.

The buy field is now optional, and within it, amount and chainId are also optional. This aligns with the internal BridgeWidget changes and enables more flexible script-based widget configurations.

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (2)

38-41: LGTM! Good consolidation of common components.

The refactor to use centralized components from common/ improves maintainability and follows DRY principles.


415-415: Consistent button styling applied.

The change to radius.full aligns the ConnectButton styling with the primary Button at line 446, ensuring visual consistency across both connected and disconnected states.

packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)

121-131: LGTM! Props relaxation improves flexibility.

Making chain and amount optional allows more flexible widget initialization scenarios while maintaining safety through optional chaining throughout the implementation.


205-209: Good addition of wallet lifecycle callback.

The onDisconnect callback provides a clean integration point for applications to respond to wallet disconnection events, properly threaded through the component hierarchy.

packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)

344-366: No changes needed: getAmounts uses truthiness checks to avoid NaN/Infinity (skipping zero‐price as falsy) and DecimalInput already filters invalid numeric input.

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

♻️ Duplicate comments (2)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)

37-42: TSDoc still missing for public function.

The required comprehensive TSDoc documentation with @example and a custom tag (@beta, @internal, @experimental, etc.) has not been added to this exported function.

As per coding guidelines.

packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)

136-136: Missing required TSDoc for public export.

Per coding guidelines for packages/thirdweb/**/*.{ts,tsx}, every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.).

Apply this diff to add the required documentation:

+/**
+ * Component for funding a wallet with token purchases. Supports token selection,
+ * amount input, and receiver address specification.
+ * 
+ * @example
+ * ```tsx
+ * import { FundWallet } from "thirdweb/react";
+ * import { createThirdwebClient } from "thirdweb";
+ * 
+ * const client = createThirdwebClient({ clientId: "YOUR_CLIENT_ID" });
+ * 
+ * function MyComponent() {
+ *   return (
+ *     <FundWallet
+ *       client={client}
+ *       receiverAddress={undefined}
+ *       onContinue={(amount, token, receiver) => console.log("Funding wallet")}
+ *       presetOptions={[5, 10, 20]}
+ *       connectOptions={undefined}
+ *       showThirdwebBranding={true}
+ *       initialSelection={{ tokenAddress: undefined, chainId: 1, amount: "0.1" }}
+ *       currency="USD"
+ *       buttonLabel={undefined}
+ *       theme="dark"
+ *       onDisconnect={() => console.log("Disconnected")}
+ *       metadata={{ title: "Fund Wallet", description: undefined, image: undefined }}
+ *     />
+ *   );
+ * }
+ * ```
+ * 
+ * @internal
+ */
 export function FundWallet(props: FundWalletProps) {

As per coding guidelines.

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

16-16: Use nullish coalescing ?? instead of logical OR || for the iconSize default.

The current use of props.iconSize || 16 will incorrectly default to 16 when iconSize is 0, which might be an intentional value to hide or collapse the icon. Using the nullish coalescing operator ?? ensures that only null or undefined trigger the fallback.

Apply this diff:

           {showCheckIcon ? (
             <CheckIcon
               className="tw-check-icon"
-              width={props.iconSize || 16}
-              height={props.iconSize || 16}
+              width={props.iconSize ?? 16}
+              height={props.iconSize ?? 16}
             />
           ) : (
             <CopyIconSVG
               className="tw-copy-icon"
-              width={props.iconSize || 16}
-              height={props.iconSize || 16}
+              width={props.iconSize ?? 16}
+              height={props.iconSize ?? 16}
             />
           )}

Also applies to: 44-54

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (1)

750-763: Consider extracting DecimalInput styles.

The DecimalInput has extensive inline styles (lines 753-762). While explicit styling provides precise control, consider extracting these into a styled component or a shared style object if this pattern is repeated elsewhere. This would improve maintainability.

Example refactor:

const SwapAmountInput = styled(DecimalInput)(() => ({
  border: "none",
  boxShadow: "none",
  fontSize: fontSize.xl,
  fontWeight: 500,
  paddingInline: 0,
  paddingBlock: 0,
  letterSpacing: "-0.025em",
  height: "30px",
}));

Then use:

<SwapAmountInput
  value={props.amount.data}
  setValue={props.setAmount}
/>
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (4)

48-48: Remove commented-out import.

The commented-out import suggests incomplete refactoring. If TokenAndChain is no longer used, remove this line to keep the code clean.


298-300: Clarify validation for zero amount.

The check if (!tokenValue) will fail for tokenValue = 0, preventing the user from continuing with a zero amount. If zero is an invalid amount, consider using a more explicit check (e.g., tokenValue <= 0 || tokenValue === undefined) for clarity. If zero is valid, this is a bug.


358-360: Add defensive check for zero price.

If fiatPricePerToken is 0, line 359 will compute Infinity. While token prices should never be zero in practice, adding a defensive check (e.g., fiatPricePerToken > 0) would prevent potential runtime issues.


446-446: Inconsistent handling of zero values in inputs.

Line 446 displays an empty string when tokenValue is 0 (tokenValue ? String(tokenValue) : ""), while Line 494 displays "0" when fiatValue is undefined or 0 (String(fiatValue || 0)). This inconsistency might confuse users. Consider handling zero values uniformly across both inputs.

Also applies to: 494-494

📜 Review details

Configuration used: CodeRabbit 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 7adce2d and c38a39d.

📒 Files selected for processing (26)
  • .changeset/slow-crews-thank.md (1 hunks)
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/CodeGen.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/LeftSection.tsx (4 hunks)
  • apps/playground-web/src/app/payments/components/RightSection.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/types.ts (1 hunks)
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (12 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2 hunks)
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1 hunks)
  • packages/thirdweb/src/script-exports/readme.md (1 hunks)
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx (8 hunks)
🚧 Files skipped from review as they are similar to previous changes (13)
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • apps/playground-web/src/app/payments/components/LeftSection.tsx
  • .changeset/slow-crews-thank.md
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx
  • apps/playground-web/src/app/payments/components/types.ts
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.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 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
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
packages/thirdweb/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/thirdweb/**/*.{ts,tsx}: Every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g., const { jsPDF } = await import("jspdf"))

Files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
apps/{dashboard,playground-web}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

apps/{dashboard,playground-web}/**/*.{ts,tsx}: Import UI primitives from @/components/ui/* (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps
Use NavLink for internal navigation with automatic active states in dashboard and playground apps
Use Tailwind CSS only – no inline styles or CSS modules
Use cn() from @/lib/utils for conditional class logic
Use design system tokens (e.g., bg-card, border-border, text-muted-foreground)
Server Components (Node edge): Start files with import "server-only";
Client Components (browser): Begin files with 'use client';
Always call getAuthToken() to retrieve JWT from cookies on server side
Use Authorization: Bearer header – never embed tokens in URLs
Return typed results (e.g., Project[], User[]) – avoid any
Wrap client-side data fetching calls in React Query (@tanstack/react-query)
Use descriptive, stable queryKeys for React Query cache hits
Configure staleTime/cacheTime in React Query based on freshness (default ≥ 60s)
Keep tokens secret via internal API routes or server actions
Never import posthog-js in server components

Files:

  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
🧠 Learnings (4)
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/**/*.{ts,tsx} : Every public symbol must have comprehensive TSDoc with at least one compiling `example` and a custom tag (`beta`, `internal`, `experimental`, etc.)

Applied to files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/exports/** : Every public symbol must have comprehensive TSDoc with at least one `example` block that compiles and custom annotation tags (`beta`, `internal`, `experimental`)

Applied to files:

  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
🧬 Code graph analysis (7)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
packages/thirdweb/src/pay/convert/type.ts (1)
  • SupportedFiatCurrency (27-27)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
  • FundWallet (136-342)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (19)
packages/thirdweb/src/react/core/design-system/index.ts (5)
  • Theme (49-96)
  • spacing (174-186)
  • fontSize (164-172)
  • radius (188-196)
  • iconSize (198-208)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/exports/utils.ts (2)
  • checksumAddress (146-146)
  • shortenAddress (149-149)
packages/thirdweb/src/exports/thirdweb.ts (2)
  • NATIVE_TOKEN_ADDRESS (31-31)
  • ThirdwebClient (25-25)
packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1)
  • useTokenQuery (13-49)
packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1)
  • useTokenBalance (7-23)
packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (1)
  • DetailsModal (372-1037)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
  • Modal (32-164)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/web/ui/components/buttons.tsx (1)
  • Button (27-161)
packages/thirdweb/src/react/web/ui/ConnectWallet/ConnectButton.tsx (1)
  • ConnectButton (301-424)
packages/thirdweb/src/pay/convert/type.ts (2)
  • SupportedFiatCurrency (27-27)
  • getFiatSymbol (29-31)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/use-bridge-chains.ts (1)
  • useBridgeChains (5-14)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-92)
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1)
  • SelectedTokenButton (19-168)
packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1)
  • DecimalInput (5-61)
packages/thirdweb/src/react/web/ui/components/Skeleton.tsx (1)
  • Skeleton (10-28)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
  • formatTokenAmount (26-35)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (1)
  • CopyIcon (10-61)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (2)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (188-196)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-92)
apps/playground-web/src/app/payments/components/CodeGen.tsx (1)
apps/playground-web/src/lib/code-gen.ts (1)
  • quotes (17-19)
packages/thirdweb/src/stories/BuyWidget.stories.tsx (2)
packages/thirdweb/src/stories/utils.tsx (1)
  • storyClient (14-16)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
  • BuyWidgetProps (45-209)
  • BuyWidget (321-370)
🪛 Gitleaks (8.28.0)
packages/thirdweb/src/script-exports/readme.md

[high] 61-61: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

packages/thirdweb/src/stories/BuyWidget.stories.tsx

[high] 29-29: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 138-138: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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: Size
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Lint Packages
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Unit Tests
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (19)
apps/playground-web/src/app/payments/components/CodeGen.tsx (1)

121-127: LGTM! Clean conditional prop generation.

The seller field is now correctly scoped to checkout widgets only, and the new receiverAddress field follows the same optional pattern as other fields. The logic is clear and consistent.

apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1)

23-23: LGTM! Consistent with PR-wide receiverAddress integration.

The receiverAddress field is correctly added to defaultOptions with an appropriate undefined default, matching the pattern used in CheckoutPlayground.tsx and BuyPlayground.tsx.

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)

67-69: LGTM!

The removal of monospace font styling for the address/ENS display is a minor presentational change that aligns with the broader UI standardization effort described in the PR. The Text component correctly preserves the color and size props, and the conditional fallback logic for addressOrENS remains intact.

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

16-16: Nice addition of the optional iconSize prop!

This change improves the flexibility of the CopyIcon component by allowing consumers to customize the icon size while maintaining a sensible default.

packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2)

11-11: LGTM! Optional title aligns with PR objectives.

The change from string to string | undefined makes the title prop optional, consistent with the broader PR goal of relaxing widget prop requirements. The conditional rendering at lines 39-46 already handles undefined correctly.


37-37: Verify the spacing reduction is intentional.

The Spacer prop changed from y="md+" to y="md", reducing vertical spacing. Confirm this aligns with the design system updates and intended layout adjustments for the Bridge UI.

packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)

1-1: LGTM! Type-only import for signature refinement.

The type-only import of SupportedFiatCurrency correctly supports the parameter type change in formatCurrencyAmount, improving type safety across the codebase.

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

1014-1016: Verify UX: close button hidden during buy flow.

The close button is hidden when screen === "buy" by setting display: "none". This prevents users from dismissing the modal during the purchase flow. Confirm this is intentional and that users have alternative exit paths (e.g., a back button or cancel action within BuyWidget).

packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (4)

121-121: Document breaking change: chain and amount now optional.

The chain and amount props are now optional in BuyWidgetProps. This is a breaking change for consumers who relied on these props being required. Ensure this is documented in release notes and migration guides.

The code handles the optionality gracefully with optional chaining (e.g., props.chain?.id on line 327), so the implementation is sound.

Also applies to: 131-131


205-208: Good addition: onDisconnect callback.

Adding the onDisconnect callback allows consumers to hook into the wallet disconnection lifecycle. This is a useful addition for cleanup and state management.


427-427: Good pattern: wallet-aware UI gating.

Using useActiveWalletInfo() to gate wallet-dependent UI paths is a solid pattern that ensures the component behaves correctly based on wallet connection state.


482-486: Safe construction of initialSelection.

The initialSelection object is constructed safely from optional props (tokenAddress, chain?.id, amount), preventing runtime errors when these props are undefined.

packages/thirdweb/src/script-exports/readme.md (1)

59-62: Documentation updated correctly.

The addition of tokenAddress to the buy configuration example aligns with the API changes in this PR. The example correctly demonstrates how to specify a token (USDC on Base) for purchase.

Note: The static analysis hint flagging line 61 as a potential API key is a false positive—this is a sample token contract address, not a secret.

packages/thirdweb/src/stories/BuyWidget.stories.tsx (2)

144-151: Good pattern: Variant wrapper for theme testing.

The Variant component renders BuyWidget with both dark and light themes side-by-side. This is an excellent pattern for Storybook, allowing visual comparison of theme variations in a single story.


23-33: Good coverage: PayAnotherWallet story.

The new PayAnotherWallet story demonstrates the receiverAddress prop, which is a key feature addition in this PR. This provides valuable documentation and testing coverage.

Note: The static analysis hint flagging lines 29-30 as API keys is a false positive—these are Ethereum addresses (USDC contract and a receiver address), not secrets.

packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2)

152-184: Document breaking change: buy and its fields now optional.

The buy prop in BridgeWidgetProps is now optional, and its nested fields (amount, chainId) are also optional. This is a breaking change for consumers who relied on these props being required.

Ensure this is documented in release notes and migration guides. The implementation correctly handles undefined values with optional chaining.


294-310: Safe optional chaining implementation.

All buy fields are accessed safely with optional chaining (props.buy?.amount, props.buy?.chainId, etc.), preventing runtime errors when buy is undefined. The implementation is correct.

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (2)

38-41: Good refactor: shared component imports.

Importing ActiveWalletDetails, DecimalInput, SelectedTokenButton, and useTokenBalance from common modules reduces code duplication and improves maintainability. This centralizes wallet and token UI logic across the Bridge components.


415-415: UI refinement: increased button roundness.

Changing borderRadius from radius.lg to radius.full makes the Swap button more rounded. This is a minor but consistent UI refinement that aligns with modern design trends.

@graphite-app
Copy link
Contributor

graphite-app bot commented Oct 3, 2025

Merge activity

<!--

## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes"

If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000):

## Notes for the reviewer

Anything important to call out? Be sure to also clarify these in your comments.

## How to test

Unit tests, playground, etc.

-->

<!-- start pr-codex -->

---

## PR-Codex overview
This PR introduces several enhancements to the payment features, including optional props for token and chain selection, improvements to UI components, and the addition of a receiver address input for transactions.

### Detailed summary
- Added `receiverAddress` to various components.
- Made `amount` and `chainId` optional in `BuyWidget`.
- Improved UI for `BuyWidget`, allowing token and chain selection.
- Updated `FundWallet` to handle token selection and input.
- Enhanced `DecimalInput` for better user experience.
- Refactored components for better code organization and readability.

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

<!-- end pr-codex -->

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

* **New Features**
  * Receiver address input for Buy/Pay flows.
  * Editable fiat and token amounts, current balance visible, and wallet disconnect option.
  * Copy icon supports configurable size.

* **Improvements**
  * Chain and amount can be optional; token and chain remain changeable.
  * Enhanced token selection, preset amount buttons, compact active-wallet header, improved theming and responsive layouts.
  * Added story variants (light/dark).

* **Documentation**
  * Examples updated to reflect buy prefill changes.

* **Style**
  * Simplified address text styling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
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

Caution

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

⚠️ Outside diff range comments (2)
packages/thirdweb/src/script-exports/bridge-widget-script.tsx (2)

18-60: Add comprehensive TSDoc for public API.

BridgeWidgetScriptProps is a public type exposed via script exports but lacks TSDoc. Per coding guidelines for packages/thirdweb/**/*.{ts,tsx}, every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.).

As per coding guidelines.

Example structure:

/**
 * Configuration options for the Bridge Widget when used via script tag.
 * 
 * @example
 * ```typescript
 * const config: BridgeWidgetScriptProps = {
 *   clientId: "your-client-id",
 *   theme: "dark",
 *   buy: {
 *     chainId: 1,
 *     tokenAddress: "0x...",
 *     amount: "100"
 *   }
 * };
 * ```
 * 
 * @beta
 */
export type BridgeWidgetScriptProps = {
  // ... existing properties with individual JSDoc comments
};

62-72: Add comprehensive TSDoc for public function.

BridgeWidgetScript is a public function but lacks TSDoc. Per coding guidelines for packages/thirdweb/**/*.{ts,tsx}, every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag.

As per coding guidelines.

Example structure:

/**
 * Renders the Bridge Widget component with simplified props for script tag usage.
 * Creates a thirdweb client and theme configuration internally.
 * 
 * @param props - Configuration options for the Bridge Widget
 * @returns React component
 * 
 * @example
 * ```tsx
 * <BridgeWidgetScript
 *   clientId="your-client-id"
 *   theme="dark"
 *   buy={{
 *     chainId: 1,
 *     amount: "100"
 *   }}
 * />
 * ```
 * 
 * @beta
 */
export function BridgeWidgetScript(props: BridgeWidgetScriptProps) {
  // ... existing implementation
}
♻️ Duplicate comments (2)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)

37-42: Add required TSDoc for public export.

Per coding guidelines for packages/thirdweb/**/*.{ts,tsx}, every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.).

As per coding guidelines.

packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)

136-136: Add required TSDoc for public export.

Per coding guidelines for packages/thirdweb/**/*.{ts,tsx}, every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.).

As per coding guidelines.

🧹 Nitpick comments (3)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)

67-69: Consider monospace font for address/ENS display.

Removing the monospace font from the address/ENS text may reduce readability when users verify wallet addresses character-by-character. Crypto addresses are commonly displayed in monospace fonts to help distinguish similar-looking hexadecimal characters (e.g., '0' vs 'O', '1' vs 'l').

If you want to maintain consistent styling across the refactor while preserving address readability, you could add a monospace prop to the Text component or create a specialized AddressText component for address display throughout the codebase.

-<Text color="primaryText" size={props.textSize || "xs"}>
+<Text color="primaryText" size={props.textSize || "xs"} style={{ fontFamily: "monospace" }}>
  {addressOrENS || shortenAddress(props.address)}
</Text>
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1)

19-29: Add explicit return type annotation.

The function lacks an explicit return type. Per coding guidelines, all functions should have explicit return types for clarity and type safety.

Apply this diff:

 export function SelectedTokenButton(props: {
   selectedToken:
     | {
         data: TokenWithPrices | undefined;
         isFetching: boolean;
       }
     | undefined;
   client: ThirdwebClient;
   onSelectToken: () => void;
   chain: BridgeChain | undefined;
-}) {
+}): React.ReactElement {
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (1)

327-327: Consider adding test coverage for new/changed logic.

The following areas lack test coverage:

  • Optional chain/amount prop handling (lines 327, 482-486).
  • onDisconnect callback wiring (lines 460-461).
  • useActiveWalletInfo gating logic (lines 427, 457).
  • BridgeWidgetContainer refactor (lines 349-369).

Adding tests for these paths would improve confidence in the changes and prevent regressions.

Also applies to: 349-369, 427-427, 457-461, 482-486, 496-496

📜 Review details

Configuration used: CodeRabbit 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 c38a39d and e612f16.

📒 Files selected for processing (26)
  • .changeset/slow-crews-thank.md (1 hunks)
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/CodeGen.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/LeftSection.tsx (4 hunks)
  • apps/playground-web/src/app/payments/components/RightSection.tsx (1 hunks)
  • apps/playground-web/src/app/payments/components/types.ts (1 hunks)
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx (1 hunks)
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (12 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1 hunks)
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (2 hunks)
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2 hunks)
  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1 hunks)
  • packages/thirdweb/src/script-exports/readme.md (1 hunks)
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx (8 hunks)
✅ Files skipped from review due to trivial changes (1)
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts
🚧 Files skipped from review as they are similar to previous changes (10)
  • apps/playground-web/src/app/payments/components/CodeGen.tsx
  • apps/playground-web/src/app/payments/components/RightSection.tsx
  • apps/playground-web/src/app/payments/commerce/CheckoutPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx
  • apps/playground-web/src/app/payments/components/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx
  • apps/playground-web/src/app/payments/fund-wallet/BuyPlayground.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx
  • apps/playground-web/src/app/payments/transactions/TransactionPlayground.tsx
  • apps/playground-web/src/app/payments/components/LeftSection.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 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
Avoid any and unknown unless unavoidable; narrow generics when possible
Choose composition over inheritance; leverage utility types (Partial, Pick, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose

**/*.{ts,tsx}: Use explicit function declarations and explicit return types in TypeScript
Limit each file to one stateless, single‑responsibility function
Re‑use shared types from @/types where applicable
Prefer type aliases over interface except for nominal shapes
Avoid any and unknown unless unavoidable; narrow generics when possible
Prefer composition over inheritance; use utility types (Partial, Pick, etc.)
Lazy‑import optional features and avoid top‑level side‑effects to reduce bundle size

Files:

  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Load heavy dependencies inside async paths to keep initial bundle lean (lazy loading)

Files:

  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
packages/thirdweb/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

packages/thirdweb/**/*.{ts,tsx}: Every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.)
Comment only ambiguous logic; avoid restating TypeScript in prose
Lazy‑load heavy dependencies inside async paths (e.g., const { jsPDF } = await import("jspdf"))

Files:

  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
  • packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
  • packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx
**/types.ts

📄 CodeRabbit inference engine (AGENTS.md)

Provide and re‑use local type barrels in a types.ts file

Files:

  • packages/thirdweb/src/react/web/ui/Bridge/types.ts
.changeset/*.md

📄 CodeRabbit inference engine (AGENTS.md)

.changeset/*.md: Each change in packages/* must include a changeset for the appropriate package
Version bump rules: patch for non‑API changes; minor for new/modified public API

Files:

  • .changeset/slow-crews-thank.md
**/*.stories.tsx

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
🧠 Learnings (7)
📚 Learning: 2025-09-24T11:08:43.783Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx:34-41
Timestamp: 2025-09-24T11:08:43.783Z
Learning: In BridgeWidgetProps for packages/thirdweb/src/react/web/ui/Bridge/bridge-widget/bridge-widget.tsx, the Swap onError callback signature requires a non-undefined SwapPreparedQuote parameter (unlike Buy's onError which allows undefined quote). This is intentional - SwapWidget's onError is only called when a quote is available.

Applied to files:

  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
📚 Learning: 2025-10-03T23:36:00.590Z
Learnt from: MananTank
PR: thirdweb-dev/js#8181
File: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx:27-27
Timestamp: 2025-10-03T23:36:00.590Z
Learning: In packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx, the component intentionally uses a hardcoded English locale (connectLocaleEn) rather than reading from the provider, as BuyWidget is designed to be English-only and does not require internationalization support.

Applied to files:

  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx
  • packages/thirdweb/src/stories/BuyWidget.stories.tsx
📚 Learning: 2025-09-24T11:09:45.142Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/script-exports/readme.md:6-7
Timestamp: 2025-09-24T11:09:45.142Z
Learning: For thirdweb Bridge Widget script exports, the module is exported with globalName: "BridgeWidget" in tsup config, making the global API `BridgeWidget.render()` rather than `window.thirdweb.BridgeWidget.render()`.

Applied to files:

  • packages/thirdweb/src/script-exports/bridge-widget-script.tsx
📚 Learning: 2025-09-23T19:56:43.668Z
Learnt from: MananTank
PR: thirdweb-dev/js#8106
File: packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx:482-485
Timestamp: 2025-09-23T19:56:43.668Z
Learning: In packages/thirdweb/src/react/web/ui/ConnectWallet/Modal/ConnectEmbed.tsx, the EmbedContainer uses width: "100vw" intentionally rather than "100%" - this is by design for the bridge widget embedding use case.

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx
📚 Learning: 2025-08-29T15:37:38.513Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: AGENTS.md:0-0
Timestamp: 2025-08-29T15:37:38.513Z
Learning: Applies to packages/thirdweb/**/*.{ts,tsx} : Every public symbol must have comprehensive TSDoc with at least one compiling `example` and a custom tag (`beta`, `internal`, `experimental`, etc.)

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/exports/** : Every public symbol must have comprehensive TSDoc with at least one `example` block that compiles and custom annotation tags (`beta`, `internal`, `experimental`)

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Interactive UI that relies on hooks (`useState`, `useEffect`, React Query, wallet hooks).

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
🧬 Code graph analysis (9)
packages/thirdweb/src/react/web/ui/Bridge/types.ts (1)
packages/thirdweb/src/pay/convert/type.ts (1)
  • SupportedFiatCurrency (27-27)
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (6)
packages/thirdweb/src/exports/thirdweb.ts (1)
  • ThirdwebClient (25-25)
packages/thirdweb/src/bridge/types/Chain.ts (1)
  • BridgeChain (42-42)
packages/thirdweb/src/react/core/design-system/index.ts (4)
  • spacing (174-186)
  • radius (188-196)
  • iconSize (198-208)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/components/basic.tsx (1)
  • Container (80-193)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/utils.ts (1)
  • cleanedChainName (1-3)
packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1)
packages/thirdweb/src/exports/thirdweb.ts (2)
  • ThirdwebClient (25-25)
  • NATIVE_TOKEN_ADDRESS (31-31)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (2)
packages/thirdweb/src/react/core/design-system/index.ts (2)
  • radius (188-196)
  • fontSize (164-172)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-92)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
packages/thirdweb/src/react/web/ui/Bridge/swap-widget/hooks.ts (1)
  • useActiveWalletInfo (7-21)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
  • FundWallet (136-342)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (13)
packages/thirdweb/src/react/core/design-system/index.ts (5)
  • Theme (49-96)
  • spacing (174-186)
  • fontSize (164-172)
  • radius (188-196)
  • iconSize (198-208)
packages/thirdweb/src/exports/utils.ts (2)
  • checksumAddress (146-146)
  • shortenAddress (149-149)
packages/thirdweb/src/exports/thirdweb.ts (2)
  • NATIVE_TOKEN_ADDRESS (31-31)
  • ThirdwebClient (25-25)
packages/thirdweb/src/react/web/ui/Bridge/common/token-query.ts (1)
  • useTokenQuery (13-49)
packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx (1)
  • useTokenBalance (7-23)
packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (1)
  • WithHeader (9-66)
packages/thirdweb/src/react/web/ui/ConnectWallet/Details.tsx (1)
  • DetailsModal (372-1037)
packages/thirdweb/src/react/web/ui/components/Modal.tsx (1)
  • Modal (32-164)
packages/thirdweb/src/pay/convert/type.ts (2)
  • SupportedFiatCurrency (27-27)
  • getFiatSymbol (29-31)
packages/thirdweb/src/react/web/ui/Bridge/common/active-wallet-details.tsx (1)
  • ActiveWalletDetails (21-92)
packages/thirdweb/src/react/web/ui/Bridge/common/selected-token-button.tsx (1)
  • SelectedTokenButton (19-168)
packages/thirdweb/src/react/web/ui/Bridge/common/decimal-input.tsx (1)
  • DecimalInput (5-61)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
  • formatTokenAmount (26-35)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/Buy/swap/WalletRow.tsx (1)
packages/thirdweb/src/react/web/ui/components/text.tsx (1)
  • Text (18-34)
packages/thirdweb/src/stories/BuyWidget.stories.tsx (2)
packages/thirdweb/src/stories/utils.tsx (1)
  • storyClient (14-16)
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (2)
  • BuyWidgetProps (45-209)
  • BuyWidget (321-370)
packages/thirdweb/src/react/web/ui/ConnectWallet/screens/formatTokenBalance.ts (1)
packages/thirdweb/src/pay/convert/type.ts (1)
  • SupportedFiatCurrency (27-27)
🪛 GitHub Check: codecov/patch
packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx

[warning] 327-327: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L327
Added line #L327 was not covered by tests


[warning] 349-353: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L349-L353
Added lines #L349 - L353 were not covered by tests


[warning] 357-357: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L357
Added line #L357 was not covered by tests


[warning] 368-368: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L368
Added line #L368 was not covered by tests


[warning] 427-427: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L427
Added line #L427 was not covered by tests


[warning] 457-457: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L457
Added line #L457 was not covered by tests


[warning] 460-461: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L460-L461
Added lines #L460 - L461 were not covered by tests


[warning] 482-486: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L482-L486
Added lines #L482 - L486 were not covered by tests


[warning] 496-496: packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx#L496
Added line #L496 was not covered by tests

packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx

[warning] 137-144: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L137-L144
Added lines #L137 - L144 were not covered by tests


[warning] 146-147: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L146-L147
Added lines #L146 - L147 were not covered by tests


[warning] 149-155: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L149-L155
Added lines #L149 - L155 were not covered by tests


[warning] 157-159: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L157-L159
Added lines #L157 - L159 were not covered by tests


[warning] 162-166: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L162-L166
Added lines #L162 - L166 were not covered by tests


[warning] 168-172: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L168-L172
Added lines #L168 - L172 were not covered by tests


[warning] 174-175: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L174-L175
Added lines #L174 - L175 were not covered by tests


[warning] 177-182: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L177-L182
Added lines #L177 - L182 were not covered by tests


[warning] 184-185: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L184-L185
Added lines #L184 - L185 were not covered by tests


[warning] 189-192: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L189-L192
Added lines #L189 - L192 were not covered by tests


[warning] 194-210: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L194-L210
Added lines #L194 - L210 were not covered by tests


[warning] 213-224: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L213-L224
Added lines #L213 - L224 were not covered by tests


[warning] 226-236: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L226-L236
Added lines #L226 - L236 were not covered by tests


[warning] 240-253: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L240-L253
Added lines #L240 - L253 were not covered by tests


[warning] 255-255: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L255
Added line #L255 was not covered by tests


[warning] 257-270: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L257-L270
Added lines #L257 - L270 were not covered by tests


[warning] 272-272: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L272
Added line #L272 was not covered by tests


[warning] 274-275: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L274-L275
Added lines #L274 - L275 were not covered by tests


[warning] 280-280: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L280
Added line #L280 was not covered by tests


[warning] 283-283: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L283
Added line #L283 was not covered by tests


[warning] 285-285: packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx#L285
Added line #L285 was not covered by tests

🪛 Gitleaks (8.28.0)
packages/thirdweb/src/stories/BuyWidget.stories.tsx

[high] 29-29: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)


[high] 138-138: Detected a Generic API Key, potentially exposing access to various services and sensitive operations.

(generic-api-key)

⏰ 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). (7)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Size
  • GitHub Check: Lint Packages
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (14)
packages/thirdweb/src/react/web/ui/components/CopyIcon.tsx (2)

16-16: LGTM!

The optional iconSize prop is correctly typed and follows idiomatic React prop patterns.


44-54: LGTM!

The iconSize prop is correctly applied to both icon components with an appropriate default of 16. The fallback pattern (props.iconSize || 16) correctly handles the optional prop.

packages/thirdweb/src/react/web/ui/Bridge/common/WithHeader.tsx (2)

11-11: LGTM: Type signature now matches implementation.

Widening title to string | undefined correctly reflects the component's existing conditional rendering logic (line 42). This change is backward compatible and aligns with the PR's goal of making fields optional across the widget surface.


37-37: LGTM: Layout spacing adjustment.

The spacing change from "md+" to "md" is a straightforward layout adjustment that reduces the vertical gap. The change is consistent with standard Spacer sizing tokens.

packages/thirdweb/src/script-exports/bridge-widget-script.tsx (1)

44-46: LGTM: Optional buy parameters improve flexibility.

Making buy, amount, and chainId optional aligns with the broader PR objective to relax BuyWidget prop requirements and provides better flexibility for script tag usage.

packages/thirdweb/src/script-exports/readme.md (1)

61-61: LGTM: Aligns with updated buy configuration surface.

The addition of tokenAddress to the buy configuration block is consistent with the broader refactor that supports token-centric initialization and optional chain/amount fields across bridge widgets.

packages/thirdweb/src/react/web/ui/Bridge/types.ts (1)

2-2: LGTM: Type safety improvement via SupportedFiatCurrency.

The change from currency: string to currency: SupportedFiatCurrency improves compile-time guarantees for valid currency codes and aligns with the broader standardization of currency types across bridge components.

Also applies to: 45-45

.changeset/slow-crews-thank.md (1)

1-11: LGTM: Changeset accurately reflects the UI improvements.

The changeset clearly documents the patch-level changes to BuyWidget, including optional props, editable amounts, disconnect support, and balance display.

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

1014-1016: LGTM: Conditional close icon display for buy screen.

The crossContainerStyles logic correctly hides the close icon when the buy screen is active, providing a cleaner UX for the buy flow.

packages/thirdweb/src/stories/BuyWidget.stories.tsx (1)

5-8: LGTM: Story refactor aligns with updated BuyWidget API.

The introduction of the Variant wrapper to render both dark and light theme instances of BuyWidget improves story consistency and coverage. The public export of BuyWidgetProps type aligns with the broader API surface changes.

Note: The static analysis hints at lines 29 and 138 are false positives—these are Ethereum addresses, not API keys.

Also applies to: 19-55, 144-151

packages/thirdweb/src/react/web/ui/Bridge/swap-widget/swap-ui.tsx (1)

38-41: LGTM: Centralized shared components.

Refactoring to use shared components from ../common/ reduces duplication and improves maintainability across the BuyWidget and swap-widget modules.

packages/thirdweb/src/react/web/ui/Bridge/BuyWidget.tsx (3)

121-121: LGTM: Optional props improve flexibility.

Making chain and amount optional allows more flexible usage patterns. Downstream code correctly handles undefined with optional chaining (lines 327, 484-485).

Also applies to: 131-131


205-208: LGTM: onDisconnect callback properly wired.

The onDisconnect callback is correctly typed and propagated to FundWallet and downstream to DetailsModal, enabling parent components to handle wallet disconnection events.


349-369: LGTM: Improved component composition.

Refactoring to separate BridgeWidgetContainer (theme/layout) from BridgeWidgetContent (business logic) improves maintainability. Theme fallback to "dark" is consistently applied.

Also applies to: 674-691

Comment on lines +7 to +23
export function useTokenBalance(props: {
chainId: number | undefined;
tokenAddress: string | undefined;
client: ThirdwebClient;
walletAddress: string | undefined;
}) {
return useWalletBalance({
address: props.walletAddress,
chain: props.chainId ? defineChain(props.chainId) : undefined,
client: props.client,
tokenAddress: props.tokenAddress
? getAddress(props.tokenAddress) === getAddress(NATIVE_TOKEN_ADDRESS)
? undefined
: getAddress(props.tokenAddress)
: undefined,
});
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Add required TSDoc for public hook.

Per coding guidelines for packages/thirdweb/**/*.{ts,tsx}, every public symbol must have comprehensive TSDoc with at least one compiling @example and a custom tag (@beta, @internal, @experimental, etc.).

As per coding guidelines.

Add TSDoc documentation:

+/**
+ * Hook to fetch wallet balance for a given token on a specific chain.
+ * Normalizes native token address internally.
+ * @param props - The token balance query parameters
+ * @returns The wallet balance query result from useWalletBalance
+ * @example
+ * ```ts
+ * import { useTokenBalance } from "thirdweb/react";
+ * 
+ * const balanceQuery = useTokenBalance({
+ *   chainId: 1,
+ *   tokenAddress: "0x...",
+ *   client: myClient,
+ *   walletAddress: "0x...",
+ * });
+ * console.log(balanceQuery.data?.value);
+ * ```
+ * @internal
+ */
 export function useTokenBalance(props: {
   chainId: number | undefined;
   tokenAddress: string | undefined;
   client: ThirdwebClient;
   walletAddress: string | undefined;
 }) {
🤖 Prompt for AI Agents
In packages/thirdweb/src/react/web/ui/Bridge/common/token-balance.tsx around
lines 7 to 23, the public hook useTokenBalance is missing the required TSDoc;
add a JSDoc/TSDoc block immediately above the function that includes a short
description, a compiling @example showing import and a minimal usage (creating
props with chainId, tokenAddress, client, walletAddress and reading
balanceQuery.data?.value), and include one custom visibility tag such as
@internal (or @beta/@experimental as appropriate); ensure the example is fenced
and compiles, the tags are present, and the comment follows project TSDoc style
so the file passes lint/type checks.

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

Labels

packages Playground Changes involving the Playground codebase. SDK Involves changes to the thirdweb SDK

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants