Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

gregfromstl
Copy link
Member

@gregfromstl gregfromstl commented Aug 28, 2025


PR-Codex overview

This PR introduces the TokenWithPrices type to manage tokens with associated prices, enhancing the Bridge.tokens functionality. It allows for the exclusion of prices when fetching tokens, improving efficiency and flexibility in token management.

Detailed summary

  • Added TokenWithPrices type extending Token to include prices.
  • Updated various modules to use TokenWithPrices instead of Token.
  • Modified tokens function to accept an includePrices option.
  • Added tests to verify the exclusion of prices when includePrices is false.

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

Summary by CodeRabbit

  • New Features
    • Tokens across Bridge, Onramp, and Pay now include pricing data, enabling USD calculations and richer UI displays.
    • Bridge.tokens supports an option to exclude prices for faster responses when pricing isn’t needed.
    • Routes and quotes surface price-aware origin/destination tokens throughout SDK and React components.
    • Route steps now include their associated transactions for better transparency in bridging flows.
  • Refactor
    • Standardized token data to a price-aware format across APIs, hooks, and UI components for consistency.

@gregfromstl gregfromstl requested review from a team as code owners August 28, 2025 21:20
Copy link

changeset-bot bot commented Aug 28, 2025

🦋 Changeset detected

Latest commit: 152069a

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

This PR includes changesets to release 3 packages
Name Type
thirdweb Patch
@thirdweb-dev/nebula Patch
@thirdweb-dev/wagmi-adapter 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

Copy link

vercel bot commented Aug 28, 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 Aug 28, 2025 9:34pm
nebula Ready Ready Preview Comment Aug 28, 2025 9:34pm
thirdweb_playground Ready Ready Preview Comment Aug 28, 2025 9:34pm
thirdweb-www Ready Ready Preview Comment Aug 28, 2025 9:34pm
wallet-ui Ready Ready Preview Comment Aug 28, 2025 9:34pm

Copy link
Contributor

coderabbitai bot commented Aug 28, 2025

Walkthrough

Adds price-aware token types across bridge, pay, and react layers by introducing TokenWithPrices, updating APIs to return/include it, and adding an includePrices option to Bridge.tokens. Adjusts related types/exports, tests, and UI/fixtures. Route types gain transactions: RouteTransaction[]. Onramp and various consumers now use TokenWithPrices.

Changes

Cohort / File(s) Summary
Release metadata
\.changeset/ripe-teeth-fold.md
Adds patch changeset describing ability to exclude prices from Bridge.tokens.
Token types and exports
packages/thirdweb/src/bridge/types/Token.ts, packages/thirdweb/src/bridge/index.ts
Introduces TokenWithPrices (Token plus prices map) and re-exports it publicly.
Bridge tokens API
packages/thirdweb/src/bridge/Token.ts, packages/thirdweb/src/bridge/Token.test.ts
tokens() made generic with includePrices option; returns Token or TokenWithPrices. URL includes includePrices when provided. Tests updated to assert prices presence/absence and property rename from priceUsd to prices.
Onramp and route typing
packages/thirdweb/src/bridge/Onramp.ts, packages/thirdweb/src/bridge/types/Route.ts
Onramp prepare quote now exposes destinationToken as TokenWithPrices. Route types switched origin/destination tokens to TokenWithPrices and added RouteStep.transactions: RouteTransaction[].
Pay token fetch
packages/thirdweb/src/pay/convert/get-token.ts
getToken now returns TokenWithPrices; type import updated.
React core hooks/machine
packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts, packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts, packages/thirdweb/src/react/core/machines/paymentMachine.ts
Replace Token with TokenWithPrices in API response typings, TransactionDetails.tokenInfo, PaymentMethod.originToken, context/event destinationToken.
React UI components
packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx, packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx, packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx, packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
Public props updated to use TokenWithPrices (destination/payment tokens, onContinue signatures).
Stories/fixtures
packages/thirdweb/src/stories/Bridge/fixtures.ts
Fixture tokens switched to TokenWithPrices and populated with prices and metadata.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Caller
  participant SDK as Bridge.tokens()
  participant HTTP as Bridge API

  Dev->>SDK: tokens({ chainId, ... , includePrices?: boolean })
  alt includePrices defined
    SDK->>HTTP: GET /bridge/tokens?chainId=...&includePrices={true|false}
  else not provided
    SDK->>HTTP: GET /bridge/tokens?chainId=...
  end
  HTTP-->>SDK: { data: Token[] | TokenWithPrices[] }
  SDK-->>Dev: Promise<Token[] | TokenWithPrices[]>
  note over Dev,SDK: Returned element type matches includePrices generic
Loading
sequenceDiagram
  autonumber
  actor UI as UI Flow
  participant PM as paymentMachine
  participant OR as Onramp.prepareQuote

  UI->>PM: DESTINATION_CONFIRMED(destinationToken: TokenWithPrices)
  PM-->>UI: Context updated with TokenWithPrices

  UI->>OR: prepareQuote(...)
  OR-->>UI: { destinationToken: TokenWithPrices, ... }
  note over UI: Consumers can read token.prices[...] for display/calcs
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

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.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/include-prices

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbit in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbit in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbit gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbit read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbit help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbit ignore or @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbit summary or @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbit or @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

graphite-app bot commented Aug 28, 2025

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.

Copy link
Contributor

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.01 KB (-0.09% 🔽) 1.3 s (-0.09% 🔽) 301 ms (+146.52% 🔺) 1.6 s
thirdweb (cjs) 357.32 KB (+0.08% 🔺) 7.2 s (+0.08% 🔺) 1.1 s (+20.13% 🔺) 8.2 s
thirdweb (minimal + tree-shaking) 5.73 KB (0%) 115 ms (0%) 81 ms (+737.52% 🔺) 196 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 73 ms (+2145.35% 🔺) 83 ms
thirdweb/react (minimal + tree-shaking) 19.15 KB (0%) 383 ms (0%) 104 ms (+539.78% 🔺) 487 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: 6

Caution

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

⚠️ Outside diff range comments (7)
packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx (3)

107-111: Fix optional chaining to avoid crash when erc20Value/tokenAddress are undefined

Calling toLowerCase() on possibly undefined will throw.

-          erc20Value?.tokenAddress.toLowerCase() !== NATIVE_TOKEN_ADDRESS
+          erc20Value?.tokenAddress?.toLowerCase() !== NATIVE_TOKEN_ADDRESS
             ? erc20Value?.tokenAddress
             : undefined,

116-117: Harden react-query cache key to include chain + token

Balance depends on chain and token; current key risks stale data when those change.

-    queryKey: ["user-balance", activeAccount?.address],
+    queryKey: [
+      "user-balance",
+      activeAccount?.address,
+      uiOptions.transaction.chain.id,
+      (await resolvePromisedValue(uiOptions.transaction.erc20Value))?.tokenAddress ??
+        NATIVE_TOKEN_ADDRESS,
+    ],

Note: If you prefer not to await in queryKey, precompute erc20Value via a useMemo outside the query and reference it here.


372-407: Compare balances using on-chain units (bigint) instead of Number()
Replace the formatted string comparisons with raw wei values to eliminate float imprecision:

  • Have your balance query return the wallet balance as a bigint (e.g. balanceWei) rather than a decimal string.
  • In the click handler, compare userBalanceWei directly against transactionDataQuery.data.totalCostWei (both bigints) instead of Number(userBalance) vs Number(totalCost).
  • Remove all Number(...) conversions in this block.
packages/thirdweb/src/stories/Bridge/fixtures.ts (3)

348-349: Replace legacy priceUsd with prices to match TokenWithPrices

-          priceUsd: 2500.0,
+          prices: { USD: 2500.0 },

395-397: Replace remaining priceUsd occurrences with prices in buyWithApprovalQuote

-          priceUsd: 1.0,
+          prices: { USD: 1.0 },

Apply to both destinationToken and originToken blocks.

Also applies to: 407-409


462-464: Normalize all complexBuyQuote tokens to prices map

-          priceUsd: 1.0,
+          prices: { USD: 1.0 },
-          priceUsd: 2500.0,
+          prices: { USD: 2500.0 },
-          priceUsd: 0.00642458,
+          prices: { USD: 0.00642458 },

Apply to each token block listed in these ranges.

Also applies to: 472-474, 506-508, 518-520, 551-553, 563-565

packages/thirdweb/src/bridge/Token.ts (1)

32-39: Update examples: remove deprecated priceUsd and align with new shape.

Examples show priceUsd alongside prices, but the types only expose prices. This will confuse SDK consumers.

- *     iconUri: "https://assets.relay.link/icons/1/light.png",
- *     priceUsd: 2000.50,
+ *     iconUri: "https://assets.relay.link/icons/1/light.png",
 *     prices: {
 *       USD: 2000.50,
 *       EUR: 1800.00,
 *       GBP: 1500.00,
 *       JPY: 10000.00
 *     }
- *     iconUri: "https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png",
- *     priceUsd: 1.00,
+ *     iconUri: "https://assets.coingecko.com/coins/images/6319/large/USD_Coin_icon.png",
 *     prices: {
 *       USD: 1.00,
 *       EUR: 0.84,
 *       GBP: 0.73,
 *       JPY: 120.00
 *     }

Additionally, consider noting: “Return type depends on includePrices (Token[] | TokenWithPrices[]).”

Also applies to: 47-54

🧹 Nitpick comments (11)
.changeset/ripe-teeth-fold.md (1)

5-5: Clarify default behavior and public type changes in the changeset.

Spell out that Bridge.tokens now accepts includePrices?: boolean (default true), introduce TokenWithPrices, and note surfaces updated to return it (e.g., Onramp.prepare destinationToken). Add a brief migration/example to avoid confusion.

Apply this diff to expand the note:

 Adds the ability to exclude prices from Bridge.tokens
+
+- New: `TokenWithPrices` type (`{ ...Token, prices: Record<string, number> }`).
+- Bridge: `tokens(..., { includePrices?: boolean })` (default `true`). Set `false` to omit prices.
+- Affected surfaces now return `TokenWithPrices` when prices are included (e.g. `Onramp.prepare().destinationToken`).
+- Example:
+  ```ts
+  const withPrices = await Bridge.tokens(client, { includePrices: true });
+  const withoutPrices = await Bridge.tokens(client, { includePrices: false });
+  ```
packages/thirdweb/src/bridge/types/Token.ts (1)

12-14: Document and make the prices map read-only.

Clarifies currency semantics and prevents accidental mutation in consumers.

-export type TokenWithPrices = Token & {
-  prices: Record<string, number>;
-};
+/**
+ * Token extended with fiat prices keyed by ISO 4217 codes (e.g. "USD").
+ * Values are spot prices in the given currency.
+ */
+export type TokenWithPrices = Token & {
+  readonly prices: Readonly<Record<string, number>>;
+};
packages/thirdweb/src/bridge/Onramp.ts (1)

10-10: Public API now returns TokenWithPrices; update docs and example.

The JSDoc “example result” block doesn’t show destinationToken (with prices). Add a short note so SDK consumers know prices are available.

Would you like me to open a follow-up PR to:

  • add a brief JSDoc line on destinationToken mentioning prices,
  • and update the example payload in this file?

Also applies to: 36-36

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

225-247: Simplify/standardize “Unknown Contract” guard

Single check is sufficient and avoids the stray "UnknownContract" variant.

-      {contractName !== "UnknownContract" &&
-        contractName !== undefined &&
-        contractName !== "Unknown Contract" && (
+      {contractName && contractName !== "Unknown Contract" && (
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)

263-276: Disable quick-amount buttons when price is unavailable

Currently handleQuickAmount silently no-ops; better UX to disable.

-              {presetOptions?.map((amount) => (
+              {presetOptions?.map((amount) => (
                 <Button
                   key={amount}
+                  disabled={
+                    !uiOptions.destinationToken.prices[
+                      uiOptions.currency || "USD"
+                    ]
+                  }
                   onClick={() => handleQuickAmount(Number(amount))}
packages/thirdweb/src/bridge/Token.test.ts (2)

25-25: Also assert price value type to catch shape regressions

Tiny hardening: ensure at least USD (or any) entry is numeric when present.

-      expect(token).toHaveProperty("prices");
+      expect(token).toHaveProperty("prices");
+      expect(typeof Object.values(token.prices ?? {})[0]).toBe("number");

37-54: Type-level mismatch: return type should depend on includePrices
The tokens signature still defaults to TokenWithPrices[] regardless of includePrices. Update it to a single generic and conditional return:

-export async function tokens<
-  IncludePrices extends boolean = true,
-  R extends Token | TokenWithPrices = TokenWithPrices,
->(options: tokens.Options<IncludePrices>): Promise<R[]> {
+export async function tokens<IncludePrices extends boolean = true>(
+  options: tokens.Options<IncludePrices>,
+): Promise<IncludePrices extends true ? TokenWithPrices[] : Token[]> {

And in the test make the intent explicit:

-const result = await tokens({
+const result = await tokens<false>({
   client,
   includePrices: false,
});

This ensures TS enforces presence/absence of prices correctly.

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

2-2: Avoid deep import; use bridge index for stability.

Import from the index barrel to reduce churn and keep layering consistent.

-import type { TokenWithPrices } from "../../../../bridge/types/Token.js";
+import type { Token, TokenWithPrices } from "../../../../bridge/index.js";
packages/thirdweb/src/bridge/types/Route.ts (1)

32-32: Minor: simplify optional type.

Remove redundant undefined.

-  value?: bigint | undefined;
+  value?: bigint;
packages/thirdweb/src/bridge/Token.ts (2)

205-207: Doc the performance tradeoff precisely.

Nit: “Setting this to false will speed up the request” → “Setting this to false avoids price lookups and reduces latency/response size.”


244-275: Consider single-responsibility split.

Minor: this file now holds both retrieval (GET) and mutation (POST) concerns. Consider moving add() to packages/thirdweb/src/bridge/AddToken.ts for SRP.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • 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 dc3df4b and 152069a.

📒 Files selected for processing (16)
  • .changeset/ripe-teeth-fold.md (1 hunks)
  • packages/thirdweb/src/bridge/Onramp.ts (2 hunks)
  • packages/thirdweb/src/bridge/Token.test.ts (1 hunks)
  • packages/thirdweb/src/bridge/Token.ts (7 hunks)
  • packages/thirdweb/src/bridge/index.ts (1 hunks)
  • packages/thirdweb/src/bridge/types/Route.ts (1 hunks)
  • packages/thirdweb/src/bridge/types/Token.ts (1 hunks)
  • packages/thirdweb/src/pay/convert/get-token.ts (1 hunks)
  • packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts (2 hunks)
  • packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts (2 hunks)
  • packages/thirdweb/src/react/core/machines/paymentMachine.ts (4 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx (3 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (2 hunks)
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx (2 hunks)
  • packages/thirdweb/src/stories/Bridge/fixtures.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{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

Files:

  • packages/thirdweb/src/bridge/index.ts
  • packages/thirdweb/src/react/core/machines/paymentMachine.ts
  • packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts
  • packages/thirdweb/src/bridge/types/Token.ts
  • packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx
  • packages/thirdweb/src/bridge/Token.test.ts
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
  • packages/thirdweb/src/bridge/Onramp.ts
  • packages/thirdweb/src/stories/Bridge/fixtures.ts
  • packages/thirdweb/src/bridge/types/Route.ts
  • packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/pay/convert/get-token.ts
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx
  • packages/thirdweb/src/bridge/Token.ts
**/*.{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/bridge/index.ts
  • packages/thirdweb/src/react/core/machines/paymentMachine.ts
  • packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts
  • packages/thirdweb/src/bridge/types/Token.ts
  • packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx
  • packages/thirdweb/src/bridge/Token.test.ts
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
  • packages/thirdweb/src/bridge/Onramp.ts
  • packages/thirdweb/src/stories/Bridge/fixtures.ts
  • packages/thirdweb/src/bridge/types/Route.ts
  • packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/pay/convert/get-token.ts
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx
  • packages/thirdweb/src/bridge/Token.ts
**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

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

Files:

  • packages/thirdweb/src/bridge/Token.test.ts
🧠 Learnings (8)
📚 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/core/machines/paymentMachine.ts
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.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 : Anything that consumes hooks from `tanstack/react-query` or thirdweb SDKs.

Applied to files:

  • packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
  • packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.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 : Use React Query (`tanstack/react-query`) for all client data fetching.

Applied to files:

  • packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
  • packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts
📚 Learning: 2025-05-27T19:55:25.056Z
Learnt from: MananTank
PR: thirdweb-dev/js#7177
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/public-pages/erc20/_hooks/useTokenPriceData.ts:49-49
Timestamp: 2025-05-27T19:55:25.056Z
Learning: In the ERC20 public pages token price data hook (`useTokenPriceData.ts`), direct array access on `json.data[0]` without optional chaining is intentionally correct and should not be changed to use safety checks.

Applied to files:

  • packages/thirdweb/src/bridge/Token.test.ts
📚 Learning: 2025-05-30T17:14:25.332Z
Learnt from: MananTank
PR: thirdweb-dev/js#7227
File: apps/dashboard/src/app/(app)/(dashboard)/(chain)/[chain_id]/[contractAddress]/modules/components/OpenEditionMetadata.tsx:26-26
Timestamp: 2025-05-30T17:14:25.332Z
Learning: The ModuleCardUIProps interface already includes a client prop of type ThirdwebClient, so when components use `Omit<ModuleCardUIProps, "children" | "updateButton">`, they inherit the client prop without needing to add it explicitly.

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.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 test/src/test-wallets.ts : Predefined test accounts are in `test/src/test-wallets.ts`

Applied to files:

  • packages/thirdweb/src/stories/Bridge/fixtures.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 apps/{dashboard,playground-web}/**/*.{ts,tsx} : Wrap client-side data fetching calls in React Query (`tanstack/react-query`)

Applied to files:

  • packages/thirdweb/src/react/core/hooks/usePaymentMethods.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 : When you need access to browser APIs (localStorage, window, IntersectionObserver etc.).

Applied to files:

  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx
🧬 Code graph analysis (14)
packages/thirdweb/src/react/core/machines/paymentMachine.ts (2)
packages/thirdweb/src/bridge/index.ts (1)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts (2)
packages/thirdweb/src/bridge/index.ts (1)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/bridge/types/Token.ts (1)
packages/thirdweb/src/bridge/index.ts (2)
  • TokenWithPrices (20-20)
  • Token (20-20)
packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx (2)
packages/thirdweb/src/bridge/index.ts (1)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/bridge/Token.test.ts (1)
packages/thirdweb/src/bridge/Token.ts (1)
  • tokens (131-184)
packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx (2)
packages/thirdweb/src/bridge/index.ts (1)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/bridge/Onramp.ts (2)
packages/thirdweb/src/bridge/index.ts (1)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/stories/Bridge/fixtures.ts (1)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/bridge/types/Route.ts (2)
packages/thirdweb/src/bridge/index.ts (4)
  • Route (14-14)
  • TokenWithPrices (20-20)
  • RouteQuoteStep (15-15)
  • RouteStep (16-16)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts (1)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx (1)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/pay/convert/get-token.ts (1)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx (2)
packages/thirdweb/src/bridge/index.ts (1)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (1)
  • TokenWithPrices (12-14)
packages/thirdweb/src/bridge/Token.ts (2)
packages/thirdweb/src/bridge/index.ts (3)
  • tokens (7-7)
  • Token (20-20)
  • TokenWithPrices (20-20)
packages/thirdweb/src/bridge/types/Token.ts (2)
  • Token (3-10)
  • TokenWithPrices (12-14)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Build Packages
  • GitHub Check: Lint Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (11)
packages/thirdweb/src/react/core/hooks/usePaymentMethods.ts (1)

4-4: LGTM: response typing tightened to TokenWithPrices.

Import and response shape align with usage of originToken.prices.USD. No changes requested.

Also applies to: 85-86

packages/thirdweb/src/bridge/index.ts (1)

20-20: LGTM: re-exporting TokenWithPrices in public API.

This makes the new type discoverable to consumers.

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

49-53: Prop type update looks correct

onContinue now accepting TokenWithPrices aligns with downstream usage.

packages/thirdweb/src/stories/Bridge/fixtures.ts (4)

22-33: ETH fixture alignment with TokenWithPrices looks good


35-46: USDC fixture alignment with TokenWithPrices looks good


48-59: UNI fixture alignment with TokenWithPrices looks good


680-731: Story UIOptions look consistent with TokenWithPrices references

Also applies to: 733-827, 829-867

packages/thirdweb/src/react/core/hooks/useTransactionDetails.ts (1)

4-4: Import Token and TokenWithPrices, update tokenInfo and normalize currency lookup

  • Change tokenInfo: TokenWithPrices | null to (Token | TokenWithPrices) | null and add Token to the import.
  • Type-guard for the optional prices property and lookup via (currency || "USD").toUpperCase().
  • Verify that bridge/index.js actually exports both Token and TokenWithPrices and that getToken(...) returns a prices map keyed by uppercase currency codes.
packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx (1)

3-3: Accept both Token and TokenWithPrices from the bridge index

Update all four Bridge UI files— BridgeOrchestrator.tsx, FundWallet.tsx, TransactionPayment.tsx, and DirectPayment.tsx—as follows:

• Change the import at the top of each file:

- import type { TokenWithPrices } from "../../../../bridge/types/Token.js";
+ import type { Token, TokenWithPrices } from "../../../../bridge/index.js";

• In props and callback signatures, replace every TokenWithPrices with Token | TokenWithPrices.

Ensure that Token is re-exported from packages/thirdweb/src/bridge/index.js before applying these changes.

packages/thirdweb/src/bridge/Token.ts (2)

5-5: Import changes look correct.

Type import of TokenWithPrices from ./types/Token.js aligns with module path style in this package.


273-275: Verified POST /v1/tokens includes prices object. TokenWithPrices aligns with the actual response schema.

Comment on lines +131 to +135
export async function tokens<
IncludePrices extends boolean = true,
R extends Token | TokenWithPrices = TokenWithPrices,
>(options: tokens.Options<IncludePrices>): Promise<R[]> {
const {
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

⚠️ Potential issue

Fix unsound generics: bind return type to includePrices via conditional type (remove R).

Today callers can request any R regardless of includePrices, breaking type-safety. Tie the return shape to includePrices so TS infers Token[] when false and TokenWithPrices[] when true.

-export async function tokens<
-  IncludePrices extends boolean = true,
-  R extends Token | TokenWithPrices = TokenWithPrices,
->(options: tokens.Options<IncludePrices>): Promise<R[]> {
+export async function tokens<
+  IncludePrices extends boolean = true
+>(options: tokens.Options<IncludePrices>): Promise<tokens.Result<IncludePrices>> {
-  const { data }: { data: R[] } = await response.json();
+  const { data } = (await response.json()) as {
+    data: tokens.Result<IncludePrices>;
+  };
-  type Options<IncludePrices extends boolean> = {
+  type Options<IncludePrices extends boolean = true> = {
-  type Result<T extends Token | TokenWithPrices> = T[];
+  type Result<IncludePrices extends boolean> =
+    IncludePrices extends true ? TokenWithPrices[] : Token[];

Also applies to: 182-182, 190-190, 212-212

🤖 Prompt for AI Agents
In packages/thirdweb/src/bridge/Token.ts around lines 131-135 (and also adjust
similarly at 182, 190, and 212), the function uses an unconstrained generic R
which lets callers pick any return shape regardless of the IncludePrices flag;
replace R by tying the Promise return type to IncludePrices with a conditional
type (e.g. Promise<IncludePrices extends true ? TokenWithPrices[] : Token[]>)
and remove the R generic, ensuring the options generic stays as IncludePrices so
TypeScript infers Token[] when false and TokenWithPrices[] when true; update the
other affected function signatures the same way and adjust any internal type
annotations to match the new return type.

Comment on lines +135 to 145
const {
client,
chainId,
tokenAddress,
symbol,
name,
limit,
offset,
includePrices,
} = options;

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

Default includePrices at runtime and always send the flag.

Docs/defaults say true, but the request omits the param when undefined. Be explicit to avoid backend default drift and ensure perf-opt-out is intentional.

   const {
     client,
     chainId,
     tokenAddress,
     symbol,
     name,
     limit,
     offset,
-    includePrices,
+    includePrices,
   } = options;
+  const includePricesParam = includePrices ?? true;
-  if (includePrices !== undefined) {
-    url.searchParams.set("includePrices", includePrices.toString());
-  }
+  url.searchParams.set("includePrices", String(includePricesParam));

Also applies to: 167-169

🤖 Prompt for AI Agents
In packages/thirdweb/src/bridge/Token.ts around lines 135-145 (and also apply
same change at lines 167-169), the includePrices option is currently left
undefined and therefore omitted from requests; change the destructuring or
immediately set a runtime default so includePrices = options.includePrices ??
true, and ensure every outbound request always includes the includePrices flag
(true or false) rather than omitting it so the backend receives an explicit
value; update both occurrences mentioned so the flag is always present in the
request parameters/payload.

import type { ThirdwebClient } from "../../client/client.js";
import type { Action } from "./BridgeAction.js";
import type { Token } from "./Token.js";
import type { TokenWithPrices } from "./Token.js";
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

Avoid forcing routes to carry prices; accept tokens with or without prices.

This reduces coupling and supports includePrices: false.

-import type { TokenWithPrices } from "./Token.js";
+import type { Token, TokenWithPrices } from "./Token.js";
@@
-export type Route = {
-  originToken: TokenWithPrices;
-  destinationToken: TokenWithPrices;
-};
+export type Route = {
+  originToken: Token | TokenWithPrices;
+  destinationToken: Token | TokenWithPrices;
+};
@@
-export type RouteQuoteStep = {
-  originToken: TokenWithPrices;
-  destinationToken: TokenWithPrices;
+export type RouteQuoteStep = {
+  originToken: Token | TokenWithPrices;
+  destinationToken: Token | TokenWithPrices;
   originAmount: bigint;
   destinationAmount: bigint;
   estimatedExecutionTimeMs: number;
 };
@@
-export type RouteStep = {
-  originToken: TokenWithPrices;
-  destinationToken: TokenWithPrices;
+export type RouteStep = {
+  originToken: Token | TokenWithPrices;
+  destinationToken: Token | TokenWithPrices;
   originAmount: bigint;
   destinationAmount: bigint;
   estimatedExecutionTimeMs: number;
   transactions: RouteTransaction[];
 };

Also applies to: 8-10, 13-18, 21-27

tokenAddress: string,
chainId: number,
): Promise<Token> {
): Promise<TokenWithPrices> {
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

Always request prices to match the return type TokenWithPrices

You changed the return type to TokenWithPrices but don’t pass includePrices. Make it explicit to avoid runtime shape drift if defaults change.

-      const result = await tokens({
-        chainId,
-        client,
-        tokenAddress,
-      });
+      const result = await tokens({
+        chainId,
+        client,
+        tokenAddress,
+        includePrices: true,
+      });

Also applies to: 13-17

🤖 Prompt for AI Agents
In packages/thirdweb/src/pay/convert/get-token.ts around lines 10 and 13-17, the
function signature returns TokenWithPrices but the internal token fetch calls do
not explicitly request prices; update the token retrieval calls to pass
includePrices: true (or set the equivalent option) so the returned object always
contains price data and matches TokenWithPrices, and ensure any downstream
typing/handling expects the price fields.

import { useCallback, useState } from "react";
import type { Quote } from "../../../bridge/index.js";
import type { Token } from "../../../bridge/types/Token.js";
import type { TokenWithPrices } from "../../../bridge/types/Token.js";
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Broaden machine types to accept tokens without prices.

Narrowing to TokenWithPrices makes flows incompatible when prices are excluded. Use a union across method, context, and event.

-import type { TokenWithPrices } from "../../../bridge/types/Token.js";
+import type { Token, TokenWithPrices } from "../../../bridge/index.js";
@@
       type: "wallet";
       payerWallet: Wallet;
-      originToken: TokenWithPrices;
+      originToken: Token | TokenWithPrices;
       balance: bigint;
       quote: Quote;
@@
-  destinationToken?: TokenWithPrices;
+  destinationToken?: Token | TokenWithPrices;
@@
   | {
       type: "DESTINATION_CONFIRMED";
-      destinationToken: TokenWithPrices;
+      destinationToken: Token | TokenWithPrices;
       destinationAmount: string;
       receiverAddress: Address;
     }

Verify other send sites don’t assume prices:

Also applies to: 26-29, 46-47, 75-79


🏁 Script executed:

#!/bin/bash
rg -nP -C2 'DESTINATION_CONFIRMED|originToken|destinationToken' packages/thirdweb/src
rg -nP -C2 '\.prices\s*\[' packages/thirdweb/src

Length of output: 181786


Broaden paymentMachine types & guard against missing prices

  • In packages/thirdweb/src/react/core/machines/paymentMachine.ts, import both Token and TokenWithPrices (from "../../../bridge/index.js") and change
    • originToken (line 26)
    • destinationToken (line 46)
    • DESTINATION_CONFIRMED event payload (lines 75–79)
    to use Token | TokenWithPrices
  • Audit all .prices usages (e.g. in FundWallet.tsx, TokenSelection.tsx, getTransfer.ts, etc.) and add optional chaining or defaults so flows won’t crash when a plain Token (without prices) is used.
🤖 Prompt for AI Agents
In packages/thirdweb/src/react/core/machines/paymentMachine.ts around lines 3,
26, 46 and 75-79, broaden the types to accept either Token or TokenWithPrices:
import both Token and TokenWithPrices from "../../../bridge/index.js" and change
the types of originToken (line 26), destinationToken (line 46) and the
DESTINATION_CONFIRMED event payload (lines 75–79) to Token | TokenWithPrices;
then audit all usages of .prices across the codebase (e.g., FundWallet.tsx,
TokenSelection.tsx, getTransfer.ts) and guard them with optional chaining or
sensible defaults (e.g., token.prices?.[...] or fallback values) so flows don’t
crash when a plain Token without prices is supplied.

Comment on lines +31 to +35
onContinue: (
amount: string,
token: TokenWithPrices,
receiverAddress: Address,
) => void;
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Don’t narrow public prop to TokenWithPrices; accept Token | TokenWithPrices to avoid a breaking change.

This keeps DirectPayment usable when Bridge.tokens is called with includePrices: false.

   onContinue: (
     amount: string,
-    token: TokenWithPrices,
+    token: Token | TokenWithPrices,
     receiverAddress: Address,
   ) => void;

Run to spot other public surfaces narrowed to TokenWithPrices:


🏁 Script executed:

#!/bin/bash
rg -nP -C2 'TokenWithPrices' packages/thirdweb/src/react

Length of output: 9427


Allow Token | TokenWithPrices for all Bridge callbacks to support includePrices=false
Replace TokenWithPrices with Token | TokenWithPrices in:

  • packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx onContinue (line 33)
  • packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx onContinue (line 51)
  • packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx onContinue (line 51)
  • packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx
    destinationToken (line 49)
    paymentInfo.token (line 57)
    handleRequirementsResolved callback signature (line 238)
🤖 Prompt for AI Agents
packages/thirdweb/src/react/web/ui/Bridge/DirectPayment.tsx around lines 31-35:
the onContinue callback currently types the token parameter as TokenWithPrices
which breaks when includePrices=false; update the token type to Token |
TokenWithPrices, and make the same replacement in the other files mentioned
(packages/thirdweb/src/react/web/ui/Bridge/TransactionPayment.tsx onContinue at
~line 51, packages/thirdweb/src/react/web/ui/Bridge/FundWallet.tsx onContinue at
~line 51, and packages/thirdweb/src/react/web/ui/Bridge/BridgeOrchestrator.tsx
for destinationToken at ~line 49, paymentInfo.token at ~line 57, and the
handleRequirementsResolved callback signature at ~line 238). Ensure any related
imports/types remain valid after the union type change and update usages that
assumed price fields to safely handle absence of prices.

@gregfromstl gregfromstl merged commit 50c6371 into main Aug 28, 2025
21 of 22 checks passed
@gregfromstl gregfromstl deleted the feat/include-prices branch August 28, 2025 22:22
@joaquim-verges joaquim-verges mentioned this pull request Aug 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
packages SDK Involves changes to the thirdweb SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants