Skip to content

[Dashboard] add empty state for Pay analytics #7206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 30, 2025

Conversation

gregfromstl
Copy link
Member

@gregfromstl gregfromstl commented May 29, 2025

Summary

  • implement PayEmbedFTUX with Embed, SDK, and API tabs
  • show new PayEmbedFTUX when analytics have no data

Checklist

  • pnpm biome check apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx --apply
  • pnpm test (fails: spawn anvil ENOENT)

PR-Codex overview

This PR focuses on enhancing the PayAnalytics and PayEmbedFTUX components with new features and improved handling of wallet stats and code examples. It introduces error handling, new props, and additional functionality for embedding payment options.

Detailed summary

  • Replaced return null with return [] in analytics.ts.
  • Added ignoreFormattingErrors prop in CodeServer.
  • Implemented checks for volume and wallet data in PayAnalytics.
  • Introduced PayEmbedFTUX component with tabs for code examples.
  • Added code snippets for embedding and SDK usage with clientId.
  • Included sender and receiver fields in the Buy API options.

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

Summary by CodeRabbit

  • New Features
    • Introduced a first-time user experience (FTUX) interface in the Pay Analytics dashboard, providing integration guides and code examples when no analytics data is available.
  • Improvements
    • Enhanced code example component to support ignoring formatting errors.
    • Updated analytics error handling for more consistent data responses.
  • Documentation
    • Expanded usage examples and parameter descriptions for Pay SDK functions, clarifying required fields and optional parameters.

@gregfromstl gregfromstl requested review from a team as code owners May 29, 2025 20:01
Copy link

changeset-bot bot commented May 29, 2025

⚠️ No Changeset found

Latest commit: e2eda05

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 29, 2025 20:01 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 29, 2025 20:01 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 29, 2025 20:01 Inactive
Copy link

vercel bot commented May 29, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
docs-v2 ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 30, 2025 0:37am
login ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 30, 2025 0:37am
thirdweb_playground ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 30, 2025 0:37am
thirdweb-www ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 30, 2025 0:37am
wallet-ui ✅ Ready (Inspect) Visit Preview 💬 Add feedback May 30, 2025 0:37am

@vercel vercel bot temporarily deployed to Preview – login May 29, 2025 20:01 Inactive
Copy link
Contributor

graphite-app bot commented May 29, 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

coderabbitai bot commented May 29, 2025

## Walkthrough

This update introduces a first-time user experience (FTUX) for the Pay Analytics dashboard by conditionally rendering a new `PayEmbedFTUX` component when no relevant analytics data is present. Supporting changes include the addition of the FTUX component, improved error handling in analytics data fetching, an update to the code display component's props, and expanded documentation for the Buy SDK/API.

## Changes

| File(s)                                                                 | Change Summary                                                                                                    |
|-------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------|
| apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx         | Added conditional rendering for FTUX; displays `PayEmbedFTUX` if no analytics data is available.                 |
| apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx         | Introduced new `PayEmbedFTUX` React component for first-time user onboarding with code samples and documentation. |
| apps/dashboard/src/@/api/analytics.ts                                   | Modified error handling in `getUniversalBridgeWalletUsage` to return `[]` instead of `null` on failure.          |
| apps/dashboard/src/@/components/ui/code/code.server.tsx                 | Added `ignoreFormattingErrors` prop to `CodeProps` and updated `CodeServer` to accept and use this prop.         |
| packages/thirdweb/src/bridge/Buy.ts                                     | Updated documentation to include `sender` and `receiver` in examples and parameter lists; marked `purchaseData` as optional. |

## Sequence Diagram(s)

```mermaid
sequenceDiagram
    participant User
    participant PayAnalytics
    participant AnalyticsAPI
    participant PayEmbedFTUX

    User->>PayAnalytics: Render component
    PayAnalytics->>AnalyticsAPI: Fetch volume and wallet usage data
    AnalyticsAPI-->>PayAnalytics: Return data
    alt Data present (volume > 0 or wallet count > 0)
        PayAnalytics-->>User: Render analytics dashboard
    else No data present
        PayAnalytics->>PayEmbedFTUX: Render FTUX with clientId
        PayEmbedFTUX-->>User: Show onboarding UI with code samples
    end

Suggested reviewers

  • jnsdls
  • joaquim-verges

<!-- walkthrough_end -->


---

<details>
<summary>📜 Recent review details</summary>

**Configuration used: CodeRabbit UI**
**Review profile: CHILL**
**Plan: Pro**


<details>
<summary>📥 Commits</summary>

Reviewing files that changed from the base of the PR and between e7e2beecc64afe351a52101e23e7473a8ba68e07 and e2eda0510f7d1775f1b0692a8805afe2a73a67ac.

</details>

<details>
<summary>📒 Files selected for processing (5)</summary>

* `apps/dashboard/src/@/api/analytics.ts` (1 hunks)
* `apps/dashboard/src/@/components/ui/code/code.server.tsx` (1 hunks)
* `apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx` (2 hunks)
* `apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx` (1 hunks)
* `packages/thirdweb/src/bridge/Buy.ts` (4 hunks)

</details>

<details>
<summary>🚧 Files skipped from review as they are similar to previous changes (5)</summary>

* apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx
* packages/thirdweb/src/bridge/Buy.ts
* apps/dashboard/src/@/api/analytics.ts
* apps/dashboard/src/@/components/ui/code/code.server.tsx
* apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx

</details>

</details>
<!-- internal state start -->


<!-- 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 -->

<!-- internal state end -->
<!-- finishing_touch_checkbox_start -->

<details open="true">
<summary>✨ Finishing Touches</summary>

- [ ] <!-- {"checkboxId": "7962f53c-55bc-4827-bfbf-6a18da830691"} --> 📝 Generate Docstrings

</details>

<!-- finishing_touch_checkbox_end -->
<!-- tips_start -->

---



<details>
<summary>🪧 Tips</summary>

### Chat

There are 3 ways to chat with [CodeRabbit](https://coderabbit.ai?utm_source=oss&utm_medium=github&utm_campaign=thirdweb-dev/js&utm_content=7206):

- Review comments: Directly reply to a review comment made by CodeRabbit. Example:
  - `I pushed a fix in commit <commit_id>, please review it.`
  - `Explain this complex logic.`
  - `Open a follow-up GitHub issue for this discussion.`
- Files and specific lines of code (under the "Files changed" tab): Tag `@coderabbitai` in a new review comment at the desired location with your query. Examples:
  - `@coderabbitai explain this code block.`
  -	`@coderabbitai modularize this function.`
- PR comments: Tag `@coderabbitai` 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:
  - `@coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.`
  - `@coderabbitai read src/utils.ts and explain its main purpose.`
  - `@coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.`
  - `@coderabbitai help me debug CodeRabbit configuration file.`

### Support

Need help? Create a ticket on our [support page](https://www.coderabbit.ai/contact-us/support) for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

### CodeRabbit Commands (Invoked using PR comments)

- `@coderabbitai pause` to pause the reviews on a PR.
- `@coderabbitai resume` to resume the paused reviews.
- `@coderabbitai review` to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
- `@coderabbitai full review` to do a full review from scratch and review all the files again.
- `@coderabbitai summary` to regenerate the summary of the PR.
- `@coderabbitai generate docstrings` to [generate docstrings](https://docs.coderabbit.ai/finishing-touches/docstrings) for this PR.
- `@coderabbitai generate sequence diagram` to generate a sequence diagram of the changes in this PR.
- `@coderabbitai resolve` resolve all the CodeRabbit review comments.
- `@coderabbitai configuration` to show the current CodeRabbit configuration for the repository.
- `@coderabbitai help` to get help.

### Other keywords and placeholders

- Add `@coderabbitai ignore` anywhere in the PR description to prevent this PR from being reviewed.
- Add `@coderabbitai summary` to generate the high-level summary at a specific location in the PR description.
- Add `@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](https://docs.coderabbit.ai/guides/configure-coderabbit) 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`

### Documentation and Community

- Visit our [Documentation](https://docs.coderabbit.ai) for detailed information on how to use CodeRabbit.
- Join our [Discord Community](http://discord.gg/coderabbit) to get help, request features, and share feedback.
- Follow us on [X/Twitter](https://twitter.com/coderabbitai) for updates and announcements.

</details>

<!-- tips_end -->

@github-actions github-actions bot added the Dashboard Involves changes to the Dashboard. label May 29, 2025
Copy link

codecov bot commented May 29, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 55.63%. Comparing base (1f42ad2) to head (b09e4e0).
Report is 5 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7206      +/-   ##
==========================================
+ Coverage   55.62%   55.63%   +0.01%     
==========================================
  Files         908      908              
  Lines       58531    58546      +15     
  Branches     4128     4132       +4     
==========================================
+ Hits        32556    32572      +16     
+ Misses      25869    25868       -1     
  Partials      106      106              
Flag Coverage Δ
packages 55.63% <ø> (+0.01%) ⬆️
Files with missing lines Coverage Δ
packages/thirdweb/src/bridge/Buy.ts 92.18% <ø> (ø)

... and 7 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx (1)

104-109: Consider making the API example more complete.

The API code snippet could benefit from showing the complete response handling to provide users with a more comprehensive example.

Consider adding response handling to make the example more practical:

 const apiCode = (clientId: string) => `
 curl -X POST https://pay.thirdweb.com/v1/buy/quote \
   -H "Content-Type: application/json" \
   -H "x-client-id: ${clientId}" \
   -d '{"originChainId":1,"originTokenAddress":"0x...","destinationChainId":10,"destinationTokenAddress":"0x...","amount":"0.01"}'
+
+# Response example:
+# {
+#   "quote": {
+#     "fromAmount": "0.01",
+#     "toAmount": "0.009",
+#     "estimatedGas": "21000"
+#   }
+# }
 `;
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between cb994dc and 356dee5.

📒 Files selected for processing (2)
  • apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx (2 hunks)
  • apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx (1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx (1)
apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx (1)
  • PayEmbedFTUX (9-76)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Unit Tests
  • GitHub Check: Size
  • GitHub Check: Lint Packages
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: Build Packages
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (4)
apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx (2)

1-8: LGTM! Clean imports and proper client directive.

The imports are well-organized and the "use client" directive is correctly placed for this interactive React component.


9-76: Well-structured FTUX component with good UX patterns.

The component follows React best practices with clear state management and conditional rendering. The tabbed interface provides a good user experience for different integration methods.

apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx (2)

6-6: LGTM! Clean import addition.

The import for PayEmbedFTUX is properly added and follows the existing import pattern.


58-62: Excellent empty state implementation with sound logic.

The conditional rendering logic is well-implemented:

  • Checks for meaningful data in both volume (amountUsdCents > 0) and wallet usage (count > 0)
  • Provides a helpful FTUX experience when no analytics data exists
  • Early return pattern keeps the component clean and readable

This improves the user experience by guiding new users through integration when they don't have data to analyze yet.

Copy link
Contributor

github-actions bot commented May 29, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 62.11 KB (0%) 1.3 s (0%) 252 ms (+126.98% 🔺) 1.5 s
thirdweb (cjs) 345.28 KB (0%) 7 s (0%) 970 ms (+9.45% 🔺) 7.9 s
thirdweb (minimal + tree-shaking) 5.7 KB (0%) 114 ms (0%) 56 ms (+780.99% 🔺) 170 ms
thirdweb/chains (tree-shaking) 531 B (0%) 11 ms (0%) 44 ms (+1545.04% 🔺) 54 ms
thirdweb/react (minimal + tree-shaking) 19.52 KB (0%) 391 ms (0%) 73 ms (+268.61% 🔺) 463 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.

Caution

Inline review comments failed to post. This is likely due to GitHub's limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 6

🔭 Outside diff range comments (1)
packages/thirdweb/src/engine/server-wallet.ts (1)

282-291: 🛠️ Refactor suggestion

sendBatchTransaction waits for a single hash

waitForTransactionHash is invoked with only the first transaction id, leaving the rest of the batch unmanaged. Either:

  1. Loop over all ids and Promise.all, or
  2. Make it explicit in the JSDoc that only the first transaction in the batch is awaited.

Failing to do so may mislead integrators who think the entire batch is mined.

🧹 Nitpick comments (11)
apps/dashboard/src/@/api/analytics.ts (1)

370-370: Consider making all error returns consistent.

For complete consistency across the file, consider updating the getEcosystemWalletUsage function to also return an empty array [] instead of null on error, matching the pattern used by other analytics functions.

-    return null;
+    return [];
packages/thirdweb/src/extensions/erc20/drop20.test.ts (1)

145-145: Fix variable name typo.

The variable name erc20ContractAddres is missing the final 'd'.

-      const erc20ContractAddres = await deployERC20Contract({
+      const erc20ContractAddress = await deployERC20Contract({

Note: You'll also need to update the references to this variable on lines 155 and 183.

packages/thirdweb/src/extensions/erc1155/read/getOwnedNFTs.test.ts (1)

7-24: Good test coverage but consider robustness improvements.

The test cases provide good coverage by testing both with and without indexer. However, consider making the tests more robust:

  1. Dynamic assertions: The hardcoded expectations (3 NFTs, quantity 411n) might be brittle if test data changes
  2. Error cases: Consider adding tests for invalid addresses or contracts
  3. Edge cases: Test scenarios with zero-balance NFTs or empty results

Example improvement:

  it("with indexer", async () => {
    const nfts = await getOwnedNFTs({
      contract: DROP1155_CONTRACT,
      address: "0x00d4da27dedce60f859471d8f595fdb4ae861557",
    });
-   expect(nfts.length).toBe(3);
+   expect(nfts.length).toBeGreaterThan(0);
    expect(nfts.find((nft) => nft.id === 4n)?.quantityOwned).toBe(411n);
+   // Verify all NFTs have valid quantityOwned values
+   nfts.forEach(nft => {
+     expect(nft.quantityOwned).toBeGreaterThan(0n);
+   });
  });
apps/dashboard/src/core-ui/batch-upload/lazy-mint-form/select-option.tsx (1)

30-84: Consider adding accessibility attributes for radio-like behavior.

The component implementation successfully maintains all functionality while migrating to custom components. However, consider enhancing accessibility for the radio button-like behavior.

Add ARIA attributes to improve accessibility:

       <Card
         className={cn(
           "flex flex-col gap-2 rounded-md p-5 md:w-[350px]",
           disabled
             ? "pointer-events-none cursor-not-allowed bg-muted"
             : "cursor-pointer",
           isActive && "border-primary",
           className,
         )}
         onClick={onClick}
+        role="radio"
+        aria-checked={isActive}
+        aria-disabled={disabled}
+        tabIndex={disabled ? -1 : 0}
         {...divProps}
       >

Also consider adding keyboard navigation support:

+        onKeyDown={(e) => {
+          if (e.key === 'Enter' || e.key === ' ') {
+            e.preventDefault();
+            onClick(e as any);
+          }
+        }}
packages/thirdweb/src/engine/list-server-wallets.ts (1)

1-46: LGTM with minor suggestion! Well-implemented server wallet listing function.

The implementation follows the same good practices as the create function. However, consider whether an empty server wallet list should throw an error or return an empty array.

Consider this alternative approach for handling empty results:

- if (!data) {
-   throw new Error("No server wallets found");
- }
- 
- return data;
+ return data || [];

This would treat an empty list as a valid response rather than an error condition.

packages/thirdweb/src/engine/wait-for-tx-hash.ts (1)

36-71: Consider optimizing the polling mechanism and adding exponential backoff.

The current implementation polls every second regardless of how long the transaction has been running. For long-running transactions, this could be inefficient and put unnecessary load on the service.

-        // wait for the transaction to be confirmed
-        await new Promise((resolve) => setTimeout(resolve, 1000));
+        // Exponential backoff: start with 1s, max 10s
+        const elapsed = Date.now() - startTime;
+        const delay = Math.min(1000 * Math.pow(1.5, Math.floor(elapsed / 30000)), 10000);
+        await new Promise((resolve) => setTimeout(resolve, delay));
packages/thirdweb/src/engine/search-transactions.ts (3)

18-23: Correct JSDoc parameter documentation.

The JSDoc comment references args.transactionIds parameter which doesn't exist in the actual function signature. The function uses args.filters instead.

 /**
  * Search for transactions by their ids.
  * @param args - The arguments for the search.
  * @param args.client - The thirdweb client to use.
- * @param args.transactionIds - The ids of the transactions to search for.
+ * @param args.filters - The filters to apply when searching for transactions.
+ * @param args.pageSize - The number of results per page (default: 100).
+ * @param args.page - The page number to retrieve (default: 1).
  * @engine

105-105: Consider zero-based pagination for consistency.

The default page value is set to 1, but most APIs use zero-based pagination. This could cause confusion for developers expecting standard pagination behavior.

-  const { client, filters, pageSize = 100, page = 1 } = args;
+  const { client, filters, pageSize = 100, page = 0 } = args;

If you choose to keep 1-based pagination, please document this clearly in the JSDoc comments to avoid confusion.


117-129: Enhance error messages with more context.

The current error messages could be more helpful by providing guidance on what went wrong and how to fix it.

   if (searchResult.error) {
     throw new Error(
-      `Error searching for transaction with filters ${stringify(filters)}: ${stringify(
+      `Failed to search transactions. Please check your filters and try again. Filters: ${stringify(filters)}, Error: ${stringify(
         searchResult.error,
       )}`,
     );
   }

   const data = searchResult.data?.result;

   if (!data) {
     throw new Error(`No transactions found with filters ${stringify(filters)}`);
   }
packages/engine/src/client/types.gen.ts (1)

120-157: CreateAccount* typings – consider validating label length

label is currently just string; engine’s endpoint limits it to 64 chars. If we surface that in the type (e.g. branded type or a JSDoc note) we can catch issues earlier in the SDK.

packages/thirdweb/src/engine/server-wallet.ts (1)

184-199: Minor: avoid double .toString() on values already strings

value: t.value?.toString() is safe, but when t.value is already a string we pay an unnecessary allocation. Micro-optimisation:

-value: t.value?.toString(),
+value:
+  typeof t.value === "bigint" || typeof t.value === "number"
+    ? t.value.toString()
+    : t.value,
🛑 Comments failed to post (6)
packages/thirdweb/src/engine/wait-for-tx-hash.ts (3)

60-65: 🛠️ Refactor suggestion

Add type validation before casting to Hex.

The code casts executionResult.transactionHash to Hex without validating that it's actually a valid hex string, which could cause runtime issues.

         return {
-          transactionHash: executionResult.transactionHash as Hex,
+          transactionHash: executionResult.transactionHash as Hex, // TODO: Add hex validation
           client: args.client,
           chain: executionResult.chain,
         };

Consider adding proper hex validation:

if (!executionResult.transactionHash || !/^0x[a-fA-F0-9]+$/.test(executionResult.transactionHash)) {
  throw new Error(`Invalid transaction hash format: ${executionResult.transactionHash}`);
}
🤖 Prompt for AI Agents
In packages/thirdweb/src/engine/wait-for-tx-hash.ts around lines 60 to 65, the
code casts executionResult.transactionHash to Hex without validating its format,
which risks runtime errors. Add a validation step before the cast to check that
executionResult.transactionHash exists and matches the hex string pattern
/^0x[a-fA-F0-9]+$/. If the validation fails, throw an error indicating the
invalid transaction hash format. This ensures only valid hex strings are cast to
Hex.

26-30: 🛠️ Refactor suggestion

Add input validation for better error handling.

The function doesn't validate the transactionId parameter, which could lead to unclear error messages if an invalid ID is provided.

 export async function waitForTransactionHash(args: {
   client: ThirdwebClient;
   transactionId: string;
   timeoutInSeconds?: number;
 }): Promise<WaitForReceiptOptions> {
+  if (!args.transactionId?.trim()) {
+    throw new Error("Transaction ID is required and cannot be empty");
+  }
+  
   const startTime = Date.now();
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

export async function waitForTransactionHash(args: {
  client: ThirdwebClient;
  transactionId: string;
  timeoutInSeconds?: number;
}): Promise<WaitForReceiptOptions> {
  if (!args.transactionId?.trim()) {
    throw new Error("Transaction ID is required and cannot be empty");
  }

  const startTime = Date.now();
  // …rest of function…
}
🤖 Prompt for AI Agents
In packages/thirdweb/src/engine/wait-for-tx-hash.ts around lines 26 to 30, add
input validation for the transactionId parameter at the start of the
waitForTransactionHash function. Check if transactionId is a non-empty string
and throw a clear, descriptive error if it is invalid. This will improve error
handling by preventing unclear errors later in the function.

1-1: ⚠️ Potential issue

Incorrect import source for stringify function.

The stringify function is being imported from "viem", but based on the relevant code snippets, it should be imported from the utils module.

-import { stringify } from "viem";
+import { stringify } from "../utils/json.js";
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

import { stringify } from "../utils/json.js";
🤖 Prompt for AI Agents
In packages/thirdweb/src/engine/wait-for-tx-hash.ts at line 1, the stringify
function is incorrectly imported from "viem". Change the import source to the
utils module by updating the import statement to import stringify from the
correct utils path.
packages/thirdweb/src/engine/server-wallet.ts (3)

240-246: 🛠️ Refactor suggestion

enqueueTransaction returns only the first id – API mismatch?

Engine can return one id per transaction even in a single-item array.
Exposing only the first id prevents callers from mapping N → N in future refactors (e.g. multi-send with simulate: true). Consider returning the full string[] and keeping the current helper as a convenience wrapper.

🤖 Prompt for AI Agents
In packages/thirdweb/src/engine/server-wallet.ts around lines 240 to 246, the
current code returns only the first transaction ID from enqueueTx, which returns
an array of IDs for each transaction. To fix this, modify the function to return
the full array of transaction IDs (string[]) instead of just the first one,
allowing callers to map multiple transactions to their IDs. You can keep the
existing single ID return as a separate helper function if needed for
convenience.

247-270: 🛠️ Refactor suggestion

enqueueBatchTransaction should surface all ids

Same rationale as above; callers enqueuing [tx1, tx2] probably expect two IDs so they can poll statuses independently. Returning only the first ID discards information.

-const transactionId = transactionIds[0];
-return { transactionId };
+return { transactionIds };

(And update docs accordingly.)

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In packages/thirdweb/src/engine/server-wallet.ts around lines 247 to 270, the
enqueueBatchTransaction function currently returns only the first transaction ID
after enqueuing multiple transactions, which loses information for callers
expecting all IDs. Modify the function to return all transaction IDs from
enqueueTx instead of just the first one, allowing callers to track each
transaction independently. Also update the function's return type and any
related documentation to reflect that it returns an array of transaction IDs.

167-183: ⚠️ Potential issue

Guard against missing chainId before using it

firstTransaction.chainId can technically be undefined (e.g. if a simulated tx is malformed).
Attempting to call getExecutionOptions(chainId) with undefined will later throw a cryptic error.

-const chainId = firstTransaction.chainId;
+const chainId = firstTransaction.chainId;
+if (chainId === undefined) {
+  throw new Error("chainId is undefined on the first transaction in batch");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

  const enqueueTx = async (transaction: SendTransactionOption[]) => {
    if (transaction.length === 0) {
      throw new Error("No transactions to enqueue");
    }
    const firstTransaction = transaction[0];
    if (!firstTransaction) {
      throw new Error("No transactions to enqueue");
    }
    const chainId = firstTransaction.chainId;
+   if (chainId === undefined) {
+     throw new Error("chainId is undefined on the first transaction in batch");
+   }
    // Validate all transactions are on the same chain
    for (let i = 1; i < transaction.length; i++) {
      if (transaction[i]?.chainId !== chainId) {
        throw new Error(
          `All transactions in batch must be on the same chain. Expected ${chainId}, got ${transaction[i]?.chainId} at index ${i}`,
        );
      }
    }
🤖 Prompt for AI Agents
In packages/thirdweb/src/engine/server-wallet.ts around lines 167 to 183, the
code uses firstTransaction.chainId without checking if it is undefined, which
can cause cryptic errors later. Add a guard to explicitly check if
firstTransaction.chainId is undefined and throw a clear error before proceeding.
This ensures that chainId is always defined before calling getExecutionOptions
or other functions that require it.

@gregfromstl gregfromstl added the merge-queue Adds the pull request to Graphite's merge queue. label May 30, 2025
Copy link
Member Author

gregfromstl commented May 30, 2025

Merge activity

  • May 30, 12:16 AM UTC: The merge label 'merge-queue' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • May 30, 12:16 AM UTC: gregfromstl added this pull request to the Graphite merge queue.
  • May 30, 12:32 AM UTC: The Graphite merge queue couldn't merge this PR because it was not satisfying all requirements (Failed CI: 'Unit Tests').

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground May 30, 2025 00:18 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 May 30, 2025 00:18 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui May 30, 2025 00:18 Inactive
@vercel vercel bot temporarily deployed to Preview – login May 30, 2025 00:18 Inactive
## Summary
- implement PayEmbedFTUX with Embed, SDK, and API tabs
- show new PayEmbedFTUX when analytics have no data

## Checklist
- [x] `pnpm biome check apps/dashboard/src/components/pay/PayAnalytics/PayEmbedFTUX.tsx apps/dashboard/src/components/pay/PayAnalytics/PayAnalytics.tsx --apply`
- [x] `pnpm test` *(fails: spawn anvil ENOENT)*

<!-- start pr-codex -->

---

## PR-Codex overview
This PR primarily focuses on enhancing the `PayAnalytics` and `PayEmbedFTUX` components by adding new features and improving error handling. It also updates the `CodeServer` to support formatting options and modifies the analytics API response handling.

### Detailed summary
- Updated error handling in `analytics.ts` to return an empty array instead of `null`.
- Added `ignoreFormattingErrors` prop to `CodeServer` in `code.server.tsx`.
- Integrated `PayEmbedFTUX` in `PayAnalytics` to display when no volume or wallet data is available.
- Introduced `sender` and `receiver` fields in the bridge purchase options in `Buy.ts`.
- Created `PayEmbedFTUX` component with tabs for "Embed", "SDK", and "API" code examples.
- Added code examples for embedding, SDK usage, and API calls in `PayEmbedFTUX`.

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

<!-- end pr-codex -->

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

- **New Features**
  - Introduced a first-time user experience (FTUX) interface in the Pay Analytics dashboard, providing integration guides and code examples when no analytics data is available.
- **Improvements**
  - Enhanced code example component to support ignoring formatting errors.
  - Updated analytics error handling for more consistent data responses.
- **Documentation**
  - Expanded usage examples and parameter descriptions for Pay SDK functions, clarifying required fields and optional parameters.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
codex Dashboard Involves changes to the Dashboard. packages SDK Involves changes to the thirdweb SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants