Repository: thirdweb-dev/js
Pull request #6952: [Portal] Clean up UB docs
Author: login: gregfromstl
Labels: name: Portal
description: Involves changes to the Portal (docs) codebase.
name: packages
name: SDK
description: Involves changes to the thirdweb SDK
Created: 2025-05-06T01:43:09Z | Merged: 2025-05-06T02:46:38Z

<!--

## 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 focuses on deprecating legacy payment functions in the `thirdweb` package and updating various components across the codebase to enhance functionality and maintainability.

### Detailed summary
- Added `@deprecated` tag to multiple functions in `thirdweb` related to payment:
  - `getBuyWithCryptoQuote`
  - `getPostOnRampQuote`
  - `getBuyWithCryptoTransfer`
  - `getBuyWithCryptoStatus`
  - `getBuyWithCryptoHistory`
  - `useBuyWithFiatQuote`
  - `useBuyWithFiatStatus`
  - `useBuyWithFiatHistory`
  - `useBuyWithCryptoQuote`
  - `useBuyWithCryptoStatus`
  - `useBuyWithCryptoHistory`
- Updated logic for `selectedDoc` in `apps/portal/src/app/typescript/v5/[...slug]/page.tsx` and `apps/portal/src/app/references/components/TDoc/PageLayout.tsx` to include a fallback for `slugToDoc`.
- Changed sidebar structure in `apps/portal/src/app/typescript/v5/sidebar.tsx` to categorize payment links under "Bridge, Swap, and Onramp".
- Updated the `Universal Bridge` section in `apps/portal/src/app/connect/pay/overview/page.mdx` to clarify its capabilities.
- Enhanced webhook documentation in `apps/portal/src/app/connect/pay/webhooks/page.mdx` for better clarity on webhook implementation and verification.
- Various updates to the `TypedocSummary` component to include `key` props for React elements to prevent potential rendering issues.

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

<!-- end pr-codex -->


Diff:
diff --git a/.changeset/icy-points-wish.md b/.changeset/icy-points-wish.md
new file mode 100644
index 00000000000..a34dfb6c65c
--- /dev/null
+++ b/.changeset/icy-points-wish.md
@@ -0,0 +1,5 @@
+---
+"thirdweb": patch
+---
+
++Deprecate legacy Pay functions
diff --git a/apps/portal/src/app/connect/pay/overview/page.mdx b/apps/portal/src/app/connect/pay/overview/page.mdx
index 3b54a45c9cf..7d71ce33785 100644
--- a/apps/portal/src/app/connect/pay/overview/page.mdx
+++ b/apps/portal/src/app/connect/pay/overview/page.mdx
@@ -13,9 +13,9 @@ export const metadata = createMetadata({
 		"Learn everything about thirdweb’s web3 payments solution, Universal Bridge. Technical docs on onramping, bridging + swapping.",
 });
 
-# Overview
+# Universal Bridge
 
-Universal Bridge allows your users to bridge, swap, and purchase cryptocurrencies and execute transactions with any fiat options or tokens via cross-chain routing. It enables users to purchase or complete in-app transactions with any token they hold.
+Universal Bridge allows you to create both simple and advanced payment flows for bridging, swapping, onramping, and peer-to-peer purchases. It's been used to drive millions in NFT sales, bridge native tokens to brand new chains, send stablecoins between users, and more. To get started check out the [SDK functions](https://portal.thirdweb.com/typescript/v5/buy/quote), [API reference](https://bridge.thirdweb.com/reference), or [playground](https://playground.thirdweb.com/connect/pay).
 
 <DocImage src={PayOverviewImage} />
 
@@ -35,7 +35,7 @@ Universal Bridge allows your users to bridge, swap, and purchase cryptocurrencie
     	description="Bridging support in over 160+ countries to reach a truly global audience."
     		iconUrl={<Globe/>}
     />
-    	    <FeatureCard
+    <FeatureCard
     	title="Earn revenue"
     	description="Monetize your application and earn swap fees on each transaction."
     		iconUrl={<PiggyBank />}
@@ -80,7 +80,6 @@ Universal Bridge is supported on select EVM compatible chains. To view the full
 | Provider | Supported Countries                                                                                     |
 | -------- | ------------------------------------------------------------------------------------------------------- |
 | Transak  | https://transak.notion.site/On-Ramp-Payment-Methods-Fees-Other-Details-b0761634feed4b338a69f4f186d906a5 |
-| Kado     | https://www.kado.money/supported-countries                                                              |
 | Stripe   | https://docs.stripe.com/crypto/onramp                                                                   |
 | Coinbase | https://docs.cdp.coinbase.com/onramp/docs/payment-methods/ |
 
@@ -91,4 +90,5 @@ Universal Bridge is supported on select EVM compatible chains. To view the full
 | [Buy Crypto](https://playground.thirdweb.com/connect/pay/)                                 | Developers who want onramp and crypto purchase experiences directly in their application.                                                 |
 | [Transactions](https://playground.thirdweb.com/connect/pay/transactions) | Developers who want users to onramp or purchase crypto directly into a transaction. Great for minting and NFT purchase flows.             |
 | [In-App Purchases](https://playground.thirdweb.com/connect/pay/commerce)                        | Developers who want to take payments from Fiat or Crypto directly to a seller wallet |
-| [Headless](https://playground.thirdweb.com/connect/pay/backend)                        | Developers who prefer a headless customized flow using APIs. |
+| [SDK](https://portal.thirdweb.com/typescript/v5/buy/quote)                        | Build your own UI with the SDK.  |
+| [API](https://playground.thirdweb.com/connect/pay/backend)                        | Control the full experience with the API.  |
diff --git a/apps/portal/src/app/connect/pay/webhooks/page.mdx b/apps/portal/src/app/connect/pay/webhooks/page.mdx
index 141e23495bd..08a888fd7bf 100644
--- a/apps/portal/src/app/connect/pay/webhooks/page.mdx
+++ b/apps/portal/src/app/connect/pay/webhooks/page.mdx
@@ -4,279 +4,120 @@ import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
 export const metadata = createMetadata({
 	title: "Universal Bridge Webhooks Implementation Guide — thirdweb Docs",
 	description:
-		"Learn how to set up webhooks for web3 payments with thirdweb’s Universal bridge feature: the technical docs",
+		"Learn how to set up webhooks for any Universal Bridge transactions.",
 });
 
 # Webhooks
 
-Universal Bridge can be configured to send webhook events to notify your application any time an event happens on your transaction. Universal Bridge sends a response, via a HTTP request, to any endpoint URLs that you have provided us in your Team > Project > Connect > Universal Bridge > Webhooks page in [thirdweb dashboard](https://thirdweb.com/team).
+You can create a webhook in your project dashboard under the Universal Bridge tab. You'll be prompted to copy a secret key before saving the webhook. This will be used for verification on all webhook requests received by your backend.
 
-## Events
+## Response Objects
 
-To listen to events, create a webhook in your Team > Project > Connect > Pay > Webhooks page in [thirdweb dashboard](https://thirdweb.com/team). Webhook URLs must start with `https://`.
+To get the TypeScript type for webhook responses, see the [`Webhook.Payload`](https://portal.thirdweb.com/typescript/v5/webhook/payload) type in the SDK.
 
-| Event               | Description                         |
-| ------------------- | ----------------------------------- |
-| `purchase_complete` | A transaction is confirmed onchain. |
+### Example Payloads
 
-### Purchase Complete
-
-Triggered when a transaction is confirmed onchain. This event provides information about the new status of the order and its transactionHash, as well as other relevant information.
-
-Example Response:
-
-<Tabs defaultValue="fiat">
+<Tabs defaultValue="bridge">
 
 <TabsList>
-	<TabsTrigger value="fiat">Fiat Purchase</TabsTrigger>
-	<TabsTrigger value="crypto">Crypto Purchase</TabsTrigger>
+	<TabsTrigger value="bridge">Bridge & Swap</TabsTrigger>
+	<TabsTrigger value="onramp">Onramp</TabsTrigger>
 </TabsList>
-
-<TabsContent value='fiat'>
+<TabsContent value='onramp'>
 ```json
 {
+  "version": 2,
   "data": {
-    "buyWithFiatStatus": {
-      "intentId": "f4cf8ab7-bb62-4b3b-a180-70fc7d72446c",
-      "status": "ON_RAMP_TRANSFER_COMPLETED",
-      "toAddress": "0xebfb127320fcbe8e07e5a03a4bfb782219f4735b",
-      "quote": {
-        "createdAt": "2024-06-18T23:46:46.024Z",
-        "fromCurrency": {
-          "amountUnits": "279",
-          "amount": "2.79",
-          "currencySymbol": "USD",
-          "decimals": 2,
-          "amountUSDCents": 279
-        },
-        "fromCurrencyWithFees": {
-          "amountUnits": "294",
-          "amount": "2.94",
-          "currencySymbol": "USD",
-          "decimals": 2,
-          "amountUSDCents": 279
-        },
-        "onRampToken": {
-          "chainId": 137,
-          "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-          "name": "Matic",
-          "symbol": "MATIC",
-          "decimals": 18,
-          "priceUSDCents": 54.797200000000004
-        },
-        "toToken": {
-          "chainId": 137,
-          "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-          "name": "Matic",
-          "symbol": "MATIC",
-          "decimals": 18,
-          "priceUSDCents": 54.797200000000004
-        },
-        "estimatedOnRampAmountWei": "5000000000000000000",
-        "estimatedOnRampAmount": "5",
-        "estimatedToTokenAmount": "5",
-        "estimatedToTokenAmountWei": "5000000000000000000",
-        "estimatedDurationSeconds": 30
-      },
-      "source": {
-        "completedAt": "2024-06-18T23:49:00.347Z",
-        "amount": "5",
-        "amountWei": "5000000000000000000",
-        "token": {
-          "chainId": 137,
-          "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-          "name": "Matic",
-          "symbol": "MATIC",
-          "decimals": 18,
-          "priceUSDCents": 54.797200000000004
-        },
-        "transactionHash": "0x4bb089f6a60b49235a817b52bf39bc078f1246df15731b85837526bb62cf4e70",
-        "explorerLink": "https://polygonscan.com/tx/0x4bb089f6a60b49235a817b52bf39bc078f1246df15731b85837526bb62cf4e70",
-        "amountUSDCents": 275
-      }
-    }
+    "id": "d5d33244-f855-441d-af62-4593094a3eb1",
+    "onramp": "stripe",
+    "token": {
+      "chainId": 8453,
+      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
+      "symbol": "USDC",
+      "name": "USD Coin",
+      "decimals": 6,
+      "priceUsd": 0.99995,
+      "iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
+    },
+    "amount": "5100000",
+    "currency": "USDC",
+    "currencyAmount": 5.36,
+    "receiver": "0xa5a484Af10FF67257A06DDbf8DdE6A99a483f098",
+    "status": "PENDING",
+    "purchaseData": null
   }
 }
 ```
 </TabsContent>
 
-<TabsContent value='crypto'>
+<TabsContent value='bridge'>
 ```json
 {
+  "version": 2,
   "data": {
-    "buyWithCryptoStatus": {
-      "swapType": "SAME_CHAIN",
-      "source": {
-        "transactionHash": "0x74d6c619a09e78f03f4bd495f29d5937a2539d0bbe8973e7710dce3e88c30b8b",
-        "token": {
-          "chainId": 10,
-          "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-          "decimals": 18,
-          "name": "ETH",
-          "symbol": "ETH",
-          "priceUSDCents": 346529
-        },
-        "amountWei": "318486512146714",
-        "amount": "0.000318486512146714",
-        "amountUSDCents": 110,
-        "completedAt": "2024-06-18T23:44:07.000Z"
-      },
-      "status": "COMPLETED",
-      "subStatus": "SUCCESS",
-      "fromAddress": "0xebfb127320fcbe8e07e5a03a4bfb782219f4735b",
-      "toAddress": "0xebfb127320fcbe8e07e5a03a4bfb782219f4735b",
-      "quote": {
-        "fromToken": {
-          "chainId": 10,
-          "tokenAddress": "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
-          "decimals": 18,
-          "name": "ETH",
-          "symbol": "ETH",
-          "priceUSDCents": 346529
-        },
-        "toToken": {
-          "chainId": 10,
-          "tokenAddress": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
-          "decimals": 6,
-          "name": "USD Coin",
-          "symbol": "USDC",
-          "priceUSDCents": 99
-        },
-        "fromAmountWei": "318486512146714",
-        "fromAmount": "0.000318486512146714",
-        "toAmountWei": "1100000",
-        "toAmount": "1.1",
-        "toAmountMinWei": "1100000",
-        "toAmountMin": "1.1",
-        "estimated": {
-          "fromAmountUSDCents": 110,
-          "toAmountMinUSDCents": 109,
-          "toAmountUSDCents": 109,
-          "slippageBPS": 91,
-          "feesUSDCents": 32,
-          "gasCostUSDCents": 40,
-          "durationSeconds": 30
-        },
-        "createdAt": "2024-06-18T23:43:45.900Z"
+    "transactionId": "0x7baae858e28628fe57cb0ca93c86fcda68f556563199cb4472044bfd9fbe5ec8",
+    "paymentId": "0xbea711bf1da223b29b176cff7f01596834dd63c7ad85477a3504f4b9285b33a2",
+    "clientId": "c56b27030ad22846003fafbb4302b5d7",
+    "action": "SELL",
+    "status": "COMPLETED",
+    "originToken": {
+      "chainId": 466,
+      "address": "0x675C3ce7F43b00045a4Dab954AF36160fb57cB45",
+      "symbol": "USDC",
+      "name": "USD Coin",
+      "decimals": 6,
+      "priceUsd": 0.99995,
+      "iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
+    },
+    "originAmount": "24875000",
+    "destinationToken": {
+      "chainId": 8453,
+      "address": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
+      "symbol": "USDC",
+      "name": "USD Coin",
+      "decimals": 6,
+      "priceUsd": 0.99995,
+      "iconUri": "https://coin-images.coingecko.com/coins/images/6319/large/usdc.png?1696506694"
+    },
+    "destinationAmount": "24794905",
+    "sender": "0xb4523A0D69612B9A4629A70E42021B2F384CC8Fa",
+    "receiver": "0x044A83bA68f36CF1F27836Cb93614f86d8B0ea96",
+    "type": "sell",
+    "transactions": [
+      {
+        "chainId": 466,
+        "transactionHash": "0xc507bde1da0832d097c2160aacc2c9333ac3a0516c8dca4fb955f4c949da1ef6"
       },
-      "destination": {
-        "transactionHash": "0x74d6c619a09e78f03f4bd495f29d5937a2539d0bbe8973e7710dce3e88c30b8b",
-        "token": {
-          "chainId": 10,
-          "tokenAddress": "0x0b2c639c533813f4aa9d7837caf62653d097ff85",
-          "decimals": 6,
-          "name": "USD Coin",
-          "symbol": "USDC",
-          "priceUSDCents": 99
-        },
-        "amountWei": "1100000",
-        "amount": "1.1",
-        "amountUSDCents": 109,
-        "completedAt": "2024-06-18T23:44:07.000Z"
+      {
+        "chainId": 8453,
+        "transactionHash": "0xc44b372284061a11ec96c67acfc96a67cc6180d14753b55a93c1f780d16ddc95"
       }
-    }
+    ],
+    "developerFeeBps": 20,
+    "developerFeeRecipient": "0x66d3d733e597bdf8b794ab6e13c8f2be0fcda39b"
   }
 }
 ```
 </TabsContent>
 </Tabs>
 
-## Webhook Verification (Recommended)
-
-Since any outside origin can call your webhook endpoint, it is recommended to verify the webhook signature to ensure a request comes from your Pay instance.
-
-### Check the Signature
-
-The payload body is signed with the webhook secret and provided in the X-Pay-Signature request header.
-
-Get the webhook secret for your webhook endpoint from the dashboard.
-
-This code example checks if the signature is valid:
-
-```tsx
-const generateSignature = (
-	body: string,
-	timestamp: string,
-	secret: string,
-): string => {
-	const payload = `${timestamp}.${body}`;
-	return crypto.createHmac("sha256", secret).update(payload).digest("hex");
-};
-
-const isValidSignature = (
-	body: string,
-	timestamp: string,
-	signature: string,
-	secret: string,
-): boolean => {
-	const expectedSignature = generateSignature(body, timestamp, secret);
-	return crypto.timingSafeEqual(
-		Buffer.from(expectedSignature),
-		Buffer.from(signature),
-	);
-};
-```
+## Webhook Verification
 
-Check the timestamp
-The event timestamp is provided in the X-Pay-Timestamp request header.
+There are two ways to verify a webhook request authenticity:
+1. Checking that the bearer token in the `Authorization` header matches the secret key received when you created the webhook.
+2. Decrypting the payload signature from the `x-payload-signature` header and verifying it against the received webhook body.
 
-This code example checks if the event exceeds a given expiration duration:
+### Decrypting the Payload Signature
 
-```tsx
-export const isExpired = (
-	timestamp: string,
-	expirationInSeconds: number,
-): boolean => {
-	const currentTime = Math.floor(Date.now() / 1000);
-	return currentTime - parseInt(timestamp) > expirationInSeconds;
-};
+The payload signature is constructed using the `x-timestamp` header and the webhook's full body:
+```ts
+const signature = crypto
+  .createHmac("sha256", decryptedSecret)
+  .update(`${timestamp}.${payload}`)
+  .digest("hex");
 ```
+The `x-timestamp` header is a UNIX timestamp in seconds, and the webhook body is the JSON payload received by your webhook endpoint.
 
-### Example webhook endpoint
-
-This NodeJS code example listens for event notifications on the /webhook endpoint:
-
-```tsx
-import express from "express";
-import bodyParser from "body-parser";
-import { isValidSignature, isExpired } from "./webhookHelper";
-
-const app = express();
-const port = 3000;
-
-const WEBHOOK_SECRET = "<your_webhook_auth_secret>";
-
-app.use(bodyParser.text());
-
-app.post("/webhook", (req, res) => {
-	const signatureFromHeader = req.header("X-Pay-Signature");
-	const timestampFromHeader = req.header("X-Pay-Timestamp");
+Then verify that the signature matches the `x-payload-signature` header.
 
-	if (!signatureFromHeader || !timestampFromHeader) {
-		return res.status(401).send("Missing signature or timestamp header");
-	}
-
-	if (
-		!isValidSignature(
-			req.body,
-			timestampFromHeader,
-			signatureFromHeader,
-			WEBHOOK_SECRET,
-		)
-	) {
-		return res.status(401).send("Invalid signature");
-	}
-
-	if (isExpired(timestampFromHeader, 300)) {
-		// Assuming expiration time is 5 minutes (300 seconds)
-		return res.status(401).send("Request has expired");
-	}
-
-	// Process the request
-	res.status(200).send("Webhook received!");
-});
-
-app.listen(port, () => {
-	console.log(`Server started on http://localhost:${port}`);
-});
-```
+**When using webhooks to distribute purchased items, always verify that the proper amount was paid to the proper address.**
diff --git a/apps/portal/src/app/connect/sidebar.tsx b/apps/portal/src/app/connect/sidebar.tsx
index 33e86eb472d..4a92fd885f9 100644
--- a/apps/portal/src/app/connect/sidebar.tsx
+++ b/apps/portal/src/app/connect/sidebar.tsx
@@ -236,6 +236,10 @@ export const sidebar: SideBar = {
           name: "Service Fees",
           href: `${paySlug}/fees`,
         },
+        {
+          name: "API",
+          href: "https://bridge.thirdweb.com/reference",
+        },
         {
           name: "Get Started",
           href: `${paySlug}/get-started`,
@@ -246,7 +250,7 @@ export const sidebar: SideBar = {
               href: `${paySlug}/get-started#option-1-connectbutton`,
             },
             {
-              name: "Embed Pay",
+              name: "Embed",
               href: `${paySlug}/get-started#option-2-embed-pay`,
             },
             {
diff --git a/apps/portal/src/app/references/components/TDoc/Function.tsx b/apps/portal/src/app/references/components/TDoc/Function.tsx
index 6343228a432..512f84883df 100644
--- a/apps/portal/src/app/references/components/TDoc/Function.tsx
+++ b/apps/portal/src/app/references/components/TDoc/Function.tsx
@@ -19,6 +19,7 @@ import { DeprecatedCalloutTDoc } from "./Deprecated";
 import { SourceLinkTypeDoc } from "./SourceLink";
 import { TypedocSummary } from "./Summary";
 import fetchDocBySlug from "./fetchDocs/fetchDocBySlug";
+import { getExtensionName } from "./utils/getSidebarLinkgroups";
 import { getTags } from "./utils/getTags";
 import { getTokenLinks } from "./utils/getTokenLinks";
 
@@ -35,11 +36,17 @@ export function FunctionTDoc(props: {
     ? doc.signatures?.length > 1
     : false;
 
+  const blockTag = doc.signatures?.[0]?.blockTags?.find(
+    (b) =>
+      b.tag === "@extension" || b.tag === "@modules" || b.tag === "@bridge",
+  );
+  const extensionName = blockTag ? getExtensionName(blockTag) : undefined;
+
   return (
     <>
       {props.showHeading !== false && (
         <Heading level={props.level} id={slugger.slug(doc.name)}>
-          {doc.name}
+          {extensionName ? `${extensionName}.${doc.name}` : doc.name}
         </Heading>
       )}
 
diff --git a/apps/portal/src/app/references/components/TDoc/PageLayout.tsx b/apps/portal/src/app/references/components/TDoc/PageLayout.tsx
index f40623d3ea4..210dabea524 100644
--- a/apps/portal/src/app/references/components/TDoc/PageLayout.tsx
+++ b/apps/portal/src/app/references/components/TDoc/PageLayout.tsx
@@ -64,7 +64,8 @@ export function getTDocPage(options: {
         );
       }
 
-      const selectedDoc = docSlug && slugToDoc[docSlug];
+      const selectedDoc =
+        docSlug && (slugToDoc[docSlug] || slugToDoc[`common/${docSlug}`]);
 
       if (!selectedDoc) {
         notFound();
diff --git a/apps/portal/src/app/references/components/TDoc/Summary.tsx b/apps/portal/src/app/references/components/TDoc/Summary.tsx
index d5c4df952a3..d037b195179 100644
--- a/apps/portal/src/app/references/components/TDoc/Summary.tsx
+++ b/apps/portal/src/app/references/components/TDoc/Summary.tsx
@@ -23,12 +23,14 @@ export function TypedocSummary(props: {
       {props.summary.map((s) => {
         switch (s.type) {
           case "code": {
-            return <CodeBlock lang={s.lang} code={s.value} />;
+            return (
+              <CodeBlock lang={s.lang} code={s.value} key={Math.random()} />
+            );
           }
 
           case "html":
           case "inlineCode": {
-            return <InlineCode code={s.value} />;
+            return <InlineCode code={s.value} key={Math.random()} />;
           }
 
           case "link": {
@@ -36,7 +38,7 @@ export function TypedocSummary(props: {
 
             // TODO - link to doc
             return (
-              <DocLink href={isUrlNum ? "" : s.url}>
+              <DocLink href={isUrlNum ? "" : s.url} key={s.url}>
                 <TypedocSummary summary={s.children} />
               </DocLink>
             );
@@ -44,27 +46,27 @@ export function TypedocSummary(props: {
 
           case "paragraph": {
             return (
-              <Paragraph className={props.className}>
+              <Paragraph className={props.className} key={Math.random()}>
                 <TypedocSummary summary={s.children} />
               </Paragraph>
             );
           }
 
           case "text": {
-            return <span> {s.value}</span>;
+            return <span key={Math.random()}>{s.value}</span>;
           }
 
           case "list": {
             if (s.ordered) {
               return (
-                <OrderedList>
+                <OrderedList key={Math.random()}>
                   <TypedocSummary summary={s.children} />
                 </OrderedList>
               );
             }
 
             return (
-              <UnorderedList>
+              <UnorderedList key={Math.random()}>
                 <TypedocSummary summary={s.children} />
               </UnorderedList>
             );
@@ -72,7 +74,7 @@ export function TypedocSummary(props: {
 
           case "listItem": {
             return (
-              <li>
+              <li key={Math.random()}>
                 <TypedocSummary summary={s.children} className="mb-0" />
               </li>
             );
@@ -81,6 +83,7 @@ export function TypedocSummary(props: {
           case "heading": {
             return (
               <Heading
+                key={Math.random()}
                 level={s.depth}
                 id={slugger.slug(s.children[0]?.value, false)}
               >
@@ -92,7 +95,7 @@ export function TypedocSummary(props: {
           case "strong":
           case "emphasis": {
             return (
-              <em>
+              <em key={Math.random()}>
                 <TypedocSummary summary={s.children} />
               </em>
             );
diff --git a/apps/portal/src/app/typescript/v5/[...slug]/page.tsx b/apps/portal/src/app/typescript/v5/[...slug]/page.tsx
index 588c390b517..bc8c4bc982d 100644
--- a/apps/portal/src/app/typescript/v5/[...slug]/page.tsx
+++ b/apps/portal/src/app/typescript/v5/[...slug]/page.tsx
@@ -15,7 +15,8 @@ export default async function Page(props: PageProps) {
   }
 
   // API page
-  const selectedDoc = docSlug && slugToDoc[docSlug];
+  const selectedDoc =
+    docSlug && (slugToDoc[docSlug] || slugToDoc[`common/${docSlug}`]);
 
   if (selectedDoc) {
     return (
diff --git a/apps/portal/src/app/typescript/v5/sidebar.tsx b/apps/portal/src/app/typescript/v5/sidebar.tsx
index 71474466095..6b53ae4c23f 100644
--- a/apps/portal/src/app/typescript/v5/sidebar.tsx
+++ b/apps/portal/src/app/typescript/v5/sidebar.tsx
@@ -1,7 +1,10 @@
 import { CodeIcon, ExternalLink, ZapIcon } from "lucide-react";
 import type { SideBar } from "../../../components/Layouts/DocLayout";
 import { fetchTypeScriptDoc } from "../../references/components/TDoc/fetchDocs/fetchTypeScriptDoc";
-import { getCustomTag } from "../../references/components/TDoc/utils/getSidebarLinkgroups";
+import {
+  getCustomTag,
+  getExtensionName,
+} from "../../references/components/TDoc/utils/getSidebarLinkgroups";
 
 const slug = "/typescript/v5";
 const docs = await fetchTypeScriptDoc();
@@ -221,30 +224,86 @@ export const sidebar: SideBar = {
           href: `${slug}/storage`,
         },
         {
-          name: "Pay with Fiat",
-          links:
-            docs.functions
-              ?.filter((f) => {
-                const [tag] = getCustomTag(f) || [];
-                return tag === "@buyCrypto" && f.name.includes("Fiat");
-              })
-              ?.map((f) => ({
-                name: f.name,
-                href: `${slug}/${f.name}`,
-              })) || [],
-        },
-        {
-          name: "Bridge & Swap",
-          links:
-            docs.functions
+          name: "Bridge, Swap, and Onramp",
+          links: [
+            {
+              name: "Buy",
+              links:
+                docs.functions
+                  ?.filter((f) => {
+                    const [tag] = getCustomTag(f) || [];
+                    if (tag !== "@bridge") return false;
+                    const blockTag = f.signatures?.[0]?.blockTags?.find(
+                      (b) => b.tag === "@bridge",
+                    );
+                    const extensionName = blockTag
+                      ? getExtensionName(blockTag) || "Common"
+                      : "Common";
+                    if (extensionName !== "Buy") return false;
+                    return true;
+                  })
+                  .map((f) => {
+                    const blockTag = f.signatures?.[0]?.blockTags?.find(
+                      (b) => b.tag === "@bridge",
+                    );
+                    const extensionName = blockTag
+                      ? getExtensionName(blockTag) || "Common"
+                      : "Common";
+                    return {
+                      name: f.name,
+                      href: `${slug}/${extensionName.toLowerCase()}/${f.name}`,
+                    };
+                  }) || [],
+            },
+            {
+              name: "Sell",
+              links:
+                docs.functions
+                  ?.filter((f) => {
+                    const [tag] = getCustomTag(f) || [];
+                    if (tag !== "@bridge") return false;
+                    const blockTag = f.signatures?.[0]?.blockTags?.find(
+                      (b) => b.tag === "@bridge",
+                    );
+                    const extensionName = blockTag
+                      ? getExtensionName(blockTag) || "Common"
+                      : "Common";
+                    if (extensionName !== "Sell") return false;
+                    return true;
+                  })
+                  .map((f) => {
+                    const blockTag = f.signatures?.[0]?.blockTags?.find(
+                      (b) => b.tag === "@bridge",
+                    );
+                    const extensionName = blockTag
+                      ? getExtensionName(blockTag) || "Common"
+                      : "Common";
+                    return {
+                      name: f.name,
+                      href: `${slug}/${extensionName.toLowerCase()}/${f.name}`,
+                    };
+                  }) || [],
+            },
+            ...(docs.functions
               ?.filter((f) => {
                 const [tag] = getCustomTag(f) || [];
-                return tag === "@buyCrypto" && f.name.includes("Crypto");
+                if (tag !== "@bridge") return false;
+                const blockTag = f.signatures?.[0]?.blockTags?.find(
+                  (b) => b.tag === "@bridge",
+                );
+                const extensionName = blockTag
+                  ? getExtensionName(blockTag) || "Common"
+                  : "Common";
+                if (extensionName !== "Common") return false;
+                return true;
               })
-              ?.map((f) => ({
-                name: f.name,
-                href: `${slug}/${f.name}`,
-              })) || [],
+              ?.map((f) => {
+                return {
+                  name: f.name,
+                  href: `${slug}/${f.name}`,
+                };
+              }) || []),
+          ],
         },
       ],
     },
diff --git a/packages/thirdweb/src/pay/buyWithCrypto/getHistory.ts b/packages/thirdweb/src/pay/buyWithCrypto/getHistory.ts
index bb564769cc4..dd273b6bff6 100644
--- a/packages/thirdweb/src/pay/buyWithCrypto/getHistory.ts
+++ b/packages/thirdweb/src/pay/buyWithCrypto/getHistory.ts
@@ -61,6 +61,7 @@ export type BuyWithCryptoHistoryData = {
  * const status = await getBuyWithCryptoHistory(params)
  * ```
  * @returns Object of type [`BuyWithCryptoHistoryData`](https://portal.thirdweb.com/references/typescript/v5/BuyWithCryptoHistoryData)
+ * @deprecated
  * @buyCrypto
  */
 export async function getBuyWithCryptoHistory(
diff --git a/packages/thirdweb/src/pay/buyWithCrypto/getQuote.ts b/packages/thirdweb/src/pay/buyWithCrypto/getQuote.ts
index 47a0774707b..42c9760dadc 100644
--- a/packages/thirdweb/src/pay/buyWithCrypto/getQuote.ts
+++ b/packages/thirdweb/src/pay/buyWithCrypto/getQuote.ts
@@ -208,6 +208,7 @@ export type BuyWithCryptoQuote = {
  *  maxSlippageBPS: 50, // optional: max 0.5% slippage
  * });
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export async function getBuyWithCryptoQuote(
diff --git a/packages/thirdweb/src/pay/buyWithCrypto/getStatus.ts b/packages/thirdweb/src/pay/buyWithCrypto/getStatus.ts
index 7c74d572039..8515b68a9af 100644
--- a/packages/thirdweb/src/pay/buyWithCrypto/getStatus.ts
+++ b/packages/thirdweb/src/pay/buyWithCrypto/getStatus.ts
@@ -123,6 +123,7 @@ export type ValidBuyWithCryptoStatus = Exclude<
  * }});
  * ```
  * @returns Object of type [`BuyWithCryptoStatus`](https://portal.thirdweb.com/references/typescript/v5/BuyWithCryptoStatus)
+ * @deprecated
  * @buyCrypto
  */
 export async function getBuyWithCryptoStatus(
diff --git a/packages/thirdweb/src/pay/buyWithCrypto/getTransfer.ts b/packages/thirdweb/src/pay/buyWithCrypto/getTransfer.ts
index 5681afd4ab8..74e480db7b0 100644
--- a/packages/thirdweb/src/pay/buyWithCrypto/getTransfer.ts
+++ b/packages/thirdweb/src/pay/buyWithCrypto/getTransfer.ts
@@ -119,6 +119,7 @@ export type BuyWithCryptoTransfer = {
  *  }
  * });
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export async function getBuyWithCryptoTransfer(
diff --git a/packages/thirdweb/src/pay/buyWithFiat/getHistory.ts b/packages/thirdweb/src/pay/buyWithFiat/getHistory.ts
index a6e557b1d80..22ac53117a3 100644
--- a/packages/thirdweb/src/pay/buyWithFiat/getHistory.ts
+++ b/packages/thirdweb/src/pay/buyWithFiat/getHistory.ts
@@ -5,6 +5,7 @@ import type { BuyWithFiatStatus } from "./getStatus.js";
 
 /**
  * The parameters for [`getBuyWithFiatHistory`](https://portal.thirdweb.com/references/typescript/v5/getBuyWithFiatHistory) function
+ * @deprecated
  * @buyCrypto
  */
 export type BuyWithFiatHistoryParams = {
@@ -60,6 +61,7 @@ export type BuyWithFiatHistoryData = {
  * })
  * ```
  * @returns Object of type [`BuyWithFiatHistoryData`](https://portal.thirdweb.com/references/typescript/v5/BuyWithFiatHistoryData)
+ * @deprecated
  * @buyCrypto
  */
 export async function getBuyWithFiatHistory(
diff --git a/packages/thirdweb/src/pay/buyWithFiat/getPostOnRampQuote.ts b/packages/thirdweb/src/pay/buyWithFiat/getPostOnRampQuote.ts
index dbc5fb23a29..e40a905285e 100644
--- a/packages/thirdweb/src/pay/buyWithFiat/getPostOnRampQuote.ts
+++ b/packages/thirdweb/src/pay/buyWithFiat/getPostOnRampQuote.ts
@@ -55,6 +55,7 @@ export type GetPostOnRampQuoteParams = {
  *  });
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export async function getPostOnRampQuote({
diff --git a/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts b/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts
index 03f4ed3dcbd..d30b22406c0 100644
--- a/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts
+++ b/packages/thirdweb/src/pay/buyWithFiat/getQuote.ts
@@ -6,6 +6,7 @@ import type { FiatProvider, PayTokenInfo } from "../utils/commonTypes.js";
 import { getPayBuyWithFiatQuoteEndpoint } from "../utils/definitions.js";
 /**
  * Parameters for [`getBuyWithFiatQuote`](https://portal.thirdweb.com/references/typescript/v5/getBuyWithFiatQuote) function
+ * @deprecated
  * @buyCrypto
  */
 export type GetBuyWithFiatQuoteParams = {
@@ -102,6 +103,7 @@ export type GetBuyWithFiatQuoteParams = {
  * - The on-ramp and destination token information.
  * - Processing fees
  *
+ * @deprecated
  * @buyCrypto
  */
 export type BuyWithFiatQuote = {
diff --git a/packages/thirdweb/src/pay/buyWithFiat/getStatus.ts b/packages/thirdweb/src/pay/buyWithFiat/getStatus.ts
index 89f95e88b24..082dc4003a5 100644
--- a/packages/thirdweb/src/pay/buyWithFiat/getStatus.ts
+++ b/packages/thirdweb/src/pay/buyWithFiat/getStatus.ts
@@ -8,6 +8,7 @@ import { getPayBuyWithFiatStatusEndpoint } from "../utils/definitions.js";
 
 /**
  * Parameters for the [`getBuyWithFiatStatus`](https://portal.thirdweb.com/references/typescript/v5/getBuyWithFiatStatus) function
+ * @deprecated
  * @buyCrypto
  */
 export type GetBuyWithFiatStatusParams = {
@@ -172,6 +173,7 @@ export type BuyWithFiatStatus =
  * // when the fiatStatus.status is "ON_RAMP_TRANSFER_COMPLETED" - the process is complete
  * // when the fiatStatus.status is "CRYPTO_SWAP_REQUIRED" - start the swap process
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export async function getBuyWithFiatStatus(
diff --git a/packages/thirdweb/src/pay/buyWithFiat/isSwapRequiredPostOnramp.ts b/packages/thirdweb/src/pay/buyWithFiat/isSwapRequiredPostOnramp.ts
index f0856904143..ed0a2076d41 100644
--- a/packages/thirdweb/src/pay/buyWithFiat/isSwapRequiredPostOnramp.ts
+++ b/packages/thirdweb/src/pay/buyWithFiat/isSwapRequiredPostOnramp.ts
@@ -12,6 +12,7 @@ import type { BuyWithFiatQuote } from "./getQuote.js";
  *
  * @param buyWithFiatQuote - The quote of type [`BuyWithFiatQuote`](https://portal.thirdweb.com/references/typescript/v5/BuyWithFiatQuote) returned
  * by the [`getBuyWithFiatQuote`](https://portal.thirdweb.com/references/typescript/v5/getBuyWithFiatQuote) function.
+ * @deprecated
  * @buyCrypto
  */
 export function isSwapRequiredPostOnramp(
diff --git a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoHistory.ts b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoHistory.ts
index 6e1fc94615f..a363569e177 100644
--- a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoHistory.ts
+++ b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoHistory.ts
@@ -34,6 +34,7 @@ export type BuyWithCryptoHistoryQueryOptions = Omit<
  *  return <div> ... </div>
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export function useBuyWithCryptoHistory(
diff --git a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoQuote.ts b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoQuote.ts
index 334cfe948d4..5e79673dc8a 100644
--- a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoQuote.ts
+++ b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoQuote.ts
@@ -71,6 +71,7 @@ export type BuyWithCryptoQuoteQueryOptions = Omit<
  *  return <button onClick={handleBuyWithCrypto}>Swap</button>
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export function useBuyWithCryptoQuote(
diff --git a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoStatus.ts b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoStatus.ts
index f21838fa3b7..4879bd84384 100644
--- a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoStatus.ts
+++ b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithCryptoStatus.ts
@@ -52,6 +52,7 @@ import {
  *  return <button onClick={handleBuyWithCrypto}>Swap</button>
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export function useBuyWithCryptoStatus(params?: BuyWithCryptoTransaction) {
diff --git a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatHistory.ts b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatHistory.ts
index e414e85b99e..292295c665e 100644
--- a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatHistory.ts
+++ b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatHistory.ts
@@ -34,6 +34,7 @@ export type BuyWithFiatHistoryQueryOptions = Omit<
  *  return <div> ... </div>
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export function useBuyWithFiatHistory(
diff --git a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatQuote.ts b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatQuote.ts
index c645d974a46..9594596c2c5 100644
--- a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatQuote.ts
+++ b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatQuote.ts
@@ -60,6 +60,7 @@ export type BuyWithFiatQuoteQueryOptions = Omit<
  *   );
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export function useBuyWithFiatQuote(
diff --git a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatStatus.ts b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatStatus.ts
index 9316d45fdf4..6a54845518d 100644
--- a/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatStatus.ts
+++ b/packages/thirdweb/src/react/core/hooks/pay/useBuyWithFiatStatus.ts
@@ -32,6 +32,7 @@ import type { WithPickedOnceQueryOptions } from "../types.js";
  *   return <div>...</div>;
  * }
  * ```
+ * @deprecated
  * @buyCrypto
  */
 export function useBuyWithFiatStatus(


Reviews:
user: login: graphite-app[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T01:45:51Z
user: login: graphite-app[bot]
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-06T02:08:36Z

Review comments:
diff_hunk: @@ -0,0 +1,5 @@
+---
+"thirdweb": patch
+---
+
+Deprecate legacy Pay functins
path: .changeset/icy-points-wish.md
user: login: graphite-app[bot]
body: There's a typo in the changeset message: `functins` should be corrected to `functions`.
```suggestion
+Deprecate legacy Pay functions
```
  

*Spotted by [Diamond](https://app.graphite.dev/diamond/?org=thirdweb-dev&ref=ai-review-comment)*<i class='graphite__hidden'><br /><br />Is this helpful? React 👍 or 👎 to let us know.</i>
created_at: 2025-05-06T01:45:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -23,56 +24,62 @@ export function TypedocSummary(props: {
       {props.summary.map((s) => {
         switch (s.type) {
           case "code": {
-            return <CodeBlock lang={s.lang} code={s.value} />;
+            return (
+              <CodeBlock
+                lang={s.lang}
+                code={s.value}
+                key={hash("sha1", s.value)}
+              />
+            );
           }
 
           case "html":
           case "inlineCode": {
-            return <InlineCode code={s.value} />;
+            return <InlineCode code={s.value} key={hash("sha1", s.value)} />;
           }
 
           case "link": {
             const isUrlNum = s.url.match(/^[0-9]+$/);
 
             // TODO - link to doc
             return (
-              <DocLink href={isUrlNum ? "" : s.url}>
+              <DocLink href={isUrlNum ? "" : s.url} key={Math.random()}>
path: apps/portal/src/app/references/components/TDoc/Summary.tsx
user: login: graphite-app[bot]
body: Using `Math.random()` for React keys can lead to rendering inefficiencies since keys should remain stable across renders. This could potentially cause unnecessary re-renders or component state issues. Consider using a more deterministic approach such as creating a hash from the URL content or combining parent/child indices to generate unique but stable keys.
```suggestion
              <DocLink href={isUrlNum ? "" : s.url} key={s.url}>
```
  

*Spotted by [Diamond](https://app.graphite.dev/diamond/?org=thirdweb-dev&ref=ai-review-comment)*<i class='graphite__hidden'><br /><br />Is this helpful? React 👍 or 👎 to let us know.</i>
created_at: 2025-05-06T02:08:35Z
author_association: CONTRIBUTOR

PR comments:
user: login: linear[bot]
created_at: 2025-05-06T01:43:12Z
body: <p><a href="https://linear.app/thirdweb/issue/TOOL-4245/broken-links-in-for-universal-bridge-both-these-go-to-broken-links">TOOL-4245 broken links in for Universal Bridge both these go to broken links</a></p>
author_association: NONE
user: login: changeset-bot[bot]
created_at: 2025-05-06T01:43:14Z
body: ###  🦋  Changeset detected

Latest commit: b282750a30f6a2aca34862a174269140b888088b

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

<details><summary>This PR includes changesets to release 2 packages</summary>

  | Name                        | Type  |
| --------------------------- | ----- |
| thirdweb                    | Patch |
| @thirdweb-dev/wagmi-adapter | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/thirdweb-dev/js/new/greg/tool-4245-broken-links-in-for-universal-bridge-both-these-go-to-broken?filename=.changeset/polite-ligers-poke.md&value=---%0A%22thirdweb%22%3A%20patch%0A%22portal%22%3A%20patch%0A---%0A%0A%5BPortal%5D%20Clean%20up%20UB%20docs%0A)


author_association: NONE
user: login: vercel[bot]
created_at: 2025-05-06T01:43:14Z
body: [vc]: #xFQqub+2sgJebm8XcWlon1ooGHsl2IE3fcaQAOmCOQY=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJ0aGlyZHdlYl9wbGF5Z3JvdW5kIiwicm9vdERpcmVjdG9yeSI6ImFwcHMvcGxheWdyb3VuZC13ZWIiLCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20vdGhpcmR3ZWIvdGhpcmR3ZWJfcGxheWdyb3VuZC9HRUJFd3Bjak1QVFNHUzl3dGpEOGZUdnZRWEcxIiwicHJldmlld1VybCI6InRoaXJkd2VicGxheWdyb3VuZC1naXQtZ3JlZy10b29sLTQyNDUtYnJva2VuLWxpbmtzLWluLWZvLTFkNzZiNS50aGlyZHdlYi1wcmV2aWV3LmNvbSIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiJ0aGlyZHdlYnBsYXlncm91bmQtZ2l0LWdyZWctdG9vbC00MjQ1LWJyb2tlbi1saW5rcy1pbi1mby0xZDc2YjUudGhpcmR3ZWItcHJldmlldy5jb20ifX0seyJuYW1lIjoidGhpcmR3ZWItd3d3Iiwicm9vdERpcmVjdG9yeSI6ImFwcHMvZGFzaGJvYXJkIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3RoaXJkd2ViL3RoaXJkd2ViLXd3dy82cEo1bzlHZ2R3ejlEc2M3bm9mN0Z3bXhDR29GIiwicHJldmlld1VybCI6InRoaXJkd2ViLXd3dy1naXQtZ3JlZy10b29sLTQyNDUtYnJva2VuLWxpbmtzLWluLWZvci11bml2LTAxNmQ2Zi50aGlyZHdlYi1wcmV2aWV3LmNvbSIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiJ0aGlyZHdlYi13d3ctZ2l0LWdyZWctdG9vbC00MjQ1LWJyb2tlbi1saW5rcy1pbi1mb3ItdW5pdi0wMTZkNmYudGhpcmR3ZWItcHJldmlldy5jb20ifX0seyJuYW1lIjoid2FsbGV0LXVpIiwicm9vdERpcmVjdG9yeSI6ImFwcHMvd2FsbGV0LXVpIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3RoaXJkd2ViL3dhbGxldC11aS83YUJpaHI2Y29SZzczamFHcEpDVFY0d2Q1WkdEIiwicHJldmlld1VybCI6IndhbGxldC11aS1naXQtZ3JlZy10b29sLTQyNDUtYnJva2VuLWxpbmtzLWluLWZvci11bml2ZXJzLWY0M2FiOC50aGlyZHdlYi1wcmV2aWV3LmNvbSIsIm5leHRDb21taXRTdGF0dXMiOiJERVBMT1lFRCIsImxpdmVGZWVkYmFjayI6eyJyZXNvbHZlZCI6MCwidW5yZXNvbHZlZCI6MCwidG90YWwiOjAsImxpbmsiOiJ3YWxsZXQtdWktZ2l0LWdyZWctdG9vbC00MjQ1LWJyb2tlbi1saW5rcy1pbi1mb3ItdW5pdmVycy1mNDNhYjgudGhpcmR3ZWItcHJldmlldy5jb20ifX0seyJuYW1lIjoiZG9jcy12MiIsInJvb3REaXJlY3RvcnkiOiJhcHBzL3BvcnRhbCIsImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS90aGlyZHdlYi9kb2NzLXYyLzhmRG9TOXltMnFabmd2VlQ1U3dISlF3RzNoamQiLCJwcmV2aWV3VXJsIjoiZG9jcy12Mi1naXQtZ3JlZy10b29sLTQyNDUtYnJva2VuLWxpbmtzLWluLWZvci11bml2ZXJzYWwtODc0YWFiLnRoaXJkd2ViLXByZXZpZXcuY29tIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImRvY3MtdjItZ2l0LWdyZWctdG9vbC00MjQ1LWJyb2tlbi1saW5rcy1pbi1mb3ItdW5pdmVyc2FsLTg3NGFhYi50aGlyZHdlYi1wcmV2aWV3LmNvbSJ9fSx7Im5hbWUiOiJsb2dpbiIsInJvb3REaXJlY3RvcnkiOiJhcHBzL2xvZ2luIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3RoaXJkd2ViL2xvZ2luL0hOdVg0N3dMeEJMaDRIZmVwNkhYTFpucGs2WGYiLCJwcmV2aWV3VXJsIjoibG9naW4tZ2l0LWdyZWctdG9vbC00MjQ1LWJyb2tlbi1saW5rcy1pbi1mb3ItdW5pdmVyc2FsLWItOTAzNTgyLnRoaXJkd2ViLXByZXZpZXcuY29tIiwibmV4dENvbW1pdFN0YXR1cyI6IkRFUExPWUVEIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6ImxvZ2luLWdpdC1ncmVnLXRvb2wtNDI0NS1icm9rZW4tbGlua3MtaW4tZm9yLXVuaXZlcnNhbC1iLTkwMzU4Mi50aGlyZHdlYi1wcmV2aWV3LmNvbSJ9fV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **docs-v2** | ✅ Ready ([Inspect](https://vercel.com/thirdweb/docs-v2/8fDoS9ym2qZngvVT5SwHJQwG3hjd)) | [Visit Preview](https://docs-v2-git-greg-tool-4245-broken-links-in-for-universal-874aab.thirdweb-preview.com) | 💬 [**Add feedback**](https://vercel.live/open-feedback/docs-v2-git-greg-tool-4245-broken-links-in-for-universal-874aab.thirdweb-preview.com?via=pr-comment-feedback-link) | May 6, 2025 2:33am |
| **login** | ✅ Ready ([Inspect](https://vercel.com/thirdweb/login/HNuX47wLxBLh4Hfep6HXLZnpk6Xf)) | [Visit Preview](https://login-git-greg-tool-4245-broken-links-in-for-universal-b-903582.thirdweb-preview.com) | 💬 [**Add feedback**](https://vercel.live/open-feedback/login-git-greg-tool-4245-broken-links-in-for-universal-b-903582.thirdweb-preview.com?via=pr-comment-feedback-link) | May 6, 2025 2:33am |
| **thirdweb_playground** | ✅ Ready ([Inspect](https://vercel.com/thirdweb/thirdweb_playground/GEBEwpcjMPTSGS9wtjD8fTvvQXG1)) | [Visit Preview](https://thirdwebplayground-git-greg-tool-4245-broken-links-in-fo-1d76b5.thirdweb-preview.com) | 💬 [**Add feedback**](https://vercel.live/open-feedback/thirdwebplayground-git-greg-tool-4245-broken-links-in-fo-1d76b5.thirdweb-preview.com?via=pr-comment-feedback-link) | May 6, 2025 2:33am |
| **thirdweb-www** | ✅ Ready ([Inspect](https://vercel.com/thirdweb/thirdweb-www/6pJ5o9Ggdwz9Dsc7nof7FwmxCGoF)) | [Visit Preview](https://thirdweb-www-git-greg-tool-4245-broken-links-in-for-univ-016d6f.thirdweb-preview.com) | 💬 [**Add feedback**](https://vercel.live/open-feedback/thirdweb-www-git-greg-tool-4245-broken-links-in-for-univ-016d6f.thirdweb-preview.com?via=pr-comment-feedback-link) | May 6, 2025 2:33am |
| **wallet-ui** | ✅ Ready ([Inspect](https://vercel.com/thirdweb/wallet-ui/7aBihr6coRg73jaGpJCTV4wd5ZGD)) | [Visit Preview](https://wallet-ui-git-greg-tool-4245-broken-links-in-for-univers-f43ab8.thirdweb-preview.com) | 💬 [**Add feedback**](https://vercel.live/open-feedback/wallet-ui-git-greg-tool-4245-broken-links-in-for-univers-f43ab8.thirdweb-preview.com?via=pr-comment-feedback-link) | May 6, 2025 2:33am |






author_association: NONE
user: login: graphite-app[bot]
created_at: 2025-05-06T01:43:16Z
body: ## How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:
- <kbd>merge-queue</kbd> - adds this PR to the back of the merge queue
- <kbd>hotfix</kbd> - 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](https://app.graphite.dev/invite/github/thirdweb-dev?ref=merge-queue-instructions-comment&prId=6187805794).

<h2></h2>
<sub>

An organization admin has enabled the [Graphite Merge Queue](https://graphite.dev/docs/graphite-merge-queue) in this repository.

</sub>

<sub>

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

</sub>
author_association: CONTRIBUTOR
user: login: github-actions[bot]
created_at: 2025-05-06T01:48:49Z
body: ## size-limit report 📦 
| Path                                    | Size           | Loading time (3g) | Running time (snapdragon) | Total time |
| --------------------------------------- | -------------- | ----------------- | ------------------------- | ---------- |
| thirdweb (esm)                          | 50.92 KB (0%)  | 1.1 s (0%)        | 162 ms (+143.81% 🔺)      | 1.2 s      |
| thirdweb (cjs)                          | 143.09 KB (0%) | 2.9 s (0%)        | 280 ms (+67.66% 🔺)       | 3.2 s      |
| thirdweb (minimal + tree-shaking)       | 5.67 KB (0%)   | 114 ms (0%)       | 75 ms (+1472.12% 🔺)      | 188 ms     |
| thirdweb/chains (tree-shaking)          | 514 B (0%)     | 11 ms (0%)        | 19 ms (+1036% 🔺)         | 29 ms      |
| thirdweb/react (minimal + tree-shaking) | 19.47 KB (0%)  | 390 ms (0%)       | 76 ms (+355.75% 🔺)       | 465 ms     |
author_association: CONTRIBUTOR
user: login: codecov[bot]
created_at: 2025-05-06T01:49:41Z
body: ## [Codecov](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?dropdown=coverage&src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev) Report
All modified and coverable lines are covered by tests :white_check_mark:
> Project coverage is 55.01%. Comparing base [(`2c6bd62`)](https://app.codecov.io/gh/thirdweb-dev/js/commit/2c6bd620b508ad50535b0ec44916741a8c0a6a26?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev) to head [(`b282750`)](https://app.codecov.io/gh/thirdweb-dev/js/commit/b282750a30f6a2aca34862a174269140b888088b?dropdown=coverage&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev).
> Report is 1 commits behind head on main.

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main    #6952      +/-   ##
==========================================
- Coverage   55.01%   55.01%   -0.01%     
==========================================
  Files         897      897              
  Lines       57309    57309              
  Branches     3956     3960       +4     
==========================================
- Hits        31531    31530       -1     
- Misses      25681    25682       +1     
  Partials       97       97              
```

| [Flag](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952/flags?src=pr&el=flags&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev) | Coverage Δ | |
|---|---|---|
| [packages](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952/flags?src=pr&el=flag&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev) | `55.01% <ø> (-0.01%)` | :arrow_down: |

| [Files with missing lines](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?dropdown=coverage&src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev) | Coverage Δ | |
|---|---|---|
| [...kages/thirdweb/src/pay/buyWithCrypto/getHistory.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithCrypto%2FgetHistory.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoQ3J5cHRvL2dldEhpc3RvcnkudHM=) | `8.00% <ø> (ø)` | |
| [...ackages/thirdweb/src/pay/buyWithCrypto/getQuote.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithCrypto%2FgetQuote.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoQ3J5cHRvL2dldFF1b3RlLnRz) | `5.47% <ø> (ø)` | |
| [...ckages/thirdweb/src/pay/buyWithCrypto/getStatus.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithCrypto%2FgetStatus.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoQ3J5cHRvL2dldFN0YXR1cy50cw==) | `7.14% <ø> (ø)` | |
| [...ages/thirdweb/src/pay/buyWithCrypto/getTransfer.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithCrypto%2FgetTransfer.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoQ3J5cHRvL2dldFRyYW5zZmVyLnRz) | `7.14% <ø> (ø)` | |
| [...thirdweb/src/pay/buyWithFiat/getPostOnRampQuote.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithFiat%2FgetPostOnRampQuote.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoRmlhdC9nZXRQb3N0T25SYW1wUXVvdGUudHM=) | `5.00% <ø> (ø)` | |
| [packages/thirdweb/src/pay/buyWithFiat/getQuote.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithFiat%2FgetQuote.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoRmlhdC9nZXRRdW90ZS50cw==) | `6.97% <ø> (ø)` | |
| [packages/thirdweb/src/pay/buyWithFiat/getStatus.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithFiat%2FgetStatus.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoRmlhdC9nZXRTdGF0dXMudHM=) | `8.33% <ø> (ø)` | |
| [...eb/src/pay/buyWithFiat/isSwapRequiredPostOnramp.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Fpay%2FbuyWithFiat%2FisSwapRequiredPostOnramp.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3BheS9idXlXaXRoRmlhdC9pc1N3YXBSZXF1aXJlZFBvc3RPbnJhbXAudHM=) | `5.26% <ø> (ø)` | |
| [.../src/react/core/hooks/pay/useBuyWithCryptoQuote.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Freact%2Fcore%2Fhooks%2Fpay%2FuseBuyWithCryptoQuote.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3JlYWN0L2NvcmUvaG9va3MvcGF5L3VzZUJ1eVdpdGhDcnlwdG9RdW90ZS50cw==) | `15.00% <ø> (ø)` | |
| [...src/react/core/hooks/pay/useBuyWithCryptoStatus.ts](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree&filepath=packages%2Fthirdweb%2Fsrc%2Freact%2Fcore%2Fhooks%2Fpay%2FuseBuyWithCryptoStatus.ts&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev#diff-cGFja2FnZXMvdGhpcmR3ZWIvc3JjL3JlYWN0L2NvcmUvaG9va3MvcGF5L3VzZUJ1eVdpdGhDcnlwdG9TdGF0dXMudHM=) | `13.04% <ø> (ø)` | |
| ... and [2 more](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev) | |

... and [1 file with indirect coverage changes](https://app.codecov.io/gh/thirdweb-dev/js/pull/6952/indirect-changes?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=thirdweb-dev)

</details>
<details><summary> :rocket: New features to boost your workflow: </summary>

- :snowflake: [Test Analytics](https://docs.codecov.com/docs/test-analytics): Detect flaky tests, report on failures, and find test suite problems.
- :package: [JS Bundle Analysis](https://docs.codecov.com/docs/javascript-bundle-analysis): Save yourself from yourself by tracking and limiting bundle sizes in JS merges.
</details>
author_association: NONE