Skip to content

Conversation

@joaquim-verges
Copy link
Member

@joaquim-verges joaquim-verges commented Aug 11, 2025


PR-Codex overview

This PR focuses on updating the API documentation and examples for various endpoints related to wallet management and AI chat functionalities, enhancing clarity and usability for developers.

Detailed summary

  • Removed outdated files and references.
  • Updated API endpoint paths and methods for wallet and AI functionalities.
  • Added OpenApiEndpoint components for better documentation.
  • Enhanced descriptions and examples for user authentication processes.
  • Improved formatting and clarity in the documentation for various APIs.
  • Changed navigation links and references to better reflect new structures.

The following files were skipped due to too many changes: apps/portal/src/app/wallets/page.mdx, apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx, apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx

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

Summary by CodeRabbit

  • New Features

    • Dynamic, OpenAPI-powered API docs with support for multiple request examples and structured parameter panels.
  • Documentation

    • Replaced many static HTTP snippets with OpenAPI-driven endpoint blocks across Chat, Contracts, Payments, Transactions, and Wallets.
    • Updated auth flow to use initiate/complete endpoints; added "Going further" links and Deploy Contracts page metadata.
    • Sidebar item renamed to "Streaming Responses"; homepage "AI" section now links to Chat API.
  • Style

    • Minor spacing and typography refinements in expandable details.
  • Chores

    • Added and pinned openapi-types dependency.

@vercel
Copy link

vercel bot commented Aug 11, 2025

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

Project Deployment Preview Comments Updated (UTC)
docs-v2 Ready Preview 💬 Add feedback Aug 12, 2025 4:01am
4 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
nebula ⬜️ Skipped Aug 12, 2025 4:01am
thirdweb_playground ⬜️ Skipped Aug 12, 2025 4:01am
thirdweb-www ⬜️ Skipped Aug 12, 2025 4:01am
wallet-ui ⬜️ Skipped Aug 12, 2025 4:01am

@changeset-bot
Copy link

changeset-bot bot commented Aug 11, 2025

⚠️ No Changeset found

Latest commit: d6c40f9

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 August 11, 2025 11:18 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui August 11, 2025 11:18 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 11, 2025 11:18 Inactive
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 11, 2025

Walkthrough

Adds an OpenAPI-driven documentation flow: introduces OpenApiEndpoint and DynamicRequestExample, extends ApiEndpoint/RequestExample types and rendering (multiple examples, query/path/header params, reference links), replaces many static HTTP examples across portal MDX pages, removes a local EndpointMetadata component, and tweaks dependencies and minor UI text/layout.

Changes

Cohort / File(s) Summary
Dependencies
apps/playground-web/package.json, apps/portal/package.json
Pin openapi-types in playground-web (^12.1.312.1.3); add openapi-types: 12.1.3 to portal dependencies.
Deleted chat metadata
apps/portal/src/app/ai/chat/EndpointMetadata.tsx
Remove EndpointMetadata component and its example/request metadata for POST /ai/chat.
AI chat page
apps/portal/src/app/ai/chat/page.mdx
Replace EndpointMetadata usage with <OpenApiEndpoint path="/ai/chat" method="POST" specUrl="https://api.thirdweb-dev.com/openapi.json" />; import changes and copy edits.
Sidebar label tweak
apps/portal/src/app/ai/sidebar.tsx
Rename “Response Handling” → “Streaming Responses” and update href to /ai/chat/streaming.
Contracts docs → OpenAPI
apps/portal/src/app/contracts/deploy/page.mdx, apps/portal/src/app/contracts/events/page.mdx, apps/portal/src/app/contracts/page.mdx, apps/portal/src/app/contracts/transactions/page.mdx
Import and use OpenApiEndpoint to render contract-related endpoints (deploy, list, events, read, write, transactions); add metadata export on deploy page; remove static HTTP examples.
Transactions docs → OpenAPI & Engine changes
apps/portal/src/app/transactions/page.mdx, apps/portal/src/app/transactions/monitor/page.mdx, apps/portal/src/app/transactions/sponsor/page.mdx
Replace static transaction HTTP docs with OpenApiEndpoint usage; adjust headings/notes; sponsor page updates Engine transactions API example and request format for ERC-4337.
Wallets docs → OpenAPI and SDK examples
apps/portal/src/app/wallets/page.mdx, apps/portal/src/app/wallets/custom-auth/page.mdx, apps/portal/src/app/wallets/get-users/page.mdx, apps/portal/src/app/wallets/pregenerate-wallets/page.mdx, apps/portal/src/app/wallets/server/page.mdx
Add OpenApiEndpoint imports and usages; replace many static HTTP blocks with OpenAPI-driven endpoints; restructure auth flows (initiate/complete), update SDK/Unity/.NET code examples and workflows; add responseExampleOverride for server wallets.
Payments docs → OpenAPI
apps/portal/src/app/payments/page.mdx
Replace static payments reference with OpenApiEndpoint components for create/complete/swap; update external reference URL.
Homepage AI section
apps/portal/src/app/page.tsx
Rename PlaygroundSection → AISection; update first card to “Chat API” linking to /ai/chat, change icon and description.
API docs components: core feature additions
apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx, .../DynamicRequestExample.tsx, .../ApiEndpoint.tsx, .../RequestExample.tsx, .../common.tsx, .../index.ts
Add OpenApiEndpoint (fetches/transforms OpenAPI spec → ApiEndpointMeta); add DynamicRequestExample (multi-example UI with parameters); extend ApiEndpoint to support requestExamples, queryParameters, referenceUrl and parameter sections; enhance RequestExample with format/example-type selection and referenceUrl link; remove exported secretKeyHeaderParameter; export OpenApiEndpoint from Document index.
Doc UI minor tweaks
apps/portal/src/components/Document/Details.tsx, apps/portal/src/components/Document/AuthMethodsTabs.tsx
Reduce Details spacing/typography; update OTP HTTP snippet endpoints to /v1/auth/initiate and /v1/auth/complete.
Nebula API reference metadata additions
apps/portal/src/app/nebula/api-reference/*/EndpointMetadata.tsx
Add referenceUrl and explicit request.queryParameters: [] to multiple nebula chat/session endpoint metadata files (create/get/list/update/delete/clear-session/execute).

Sequence Diagram(s)

sequenceDiagram
  participant Page as MDX Page
  participant OpenApi as OpenApiEndpoint
  participant Fetch as OpenAPI Spec
  participant Transform as Transform Spec
  participant ApiUI as ApiEndpoint
  participant DynEx as DynamicRequestExample
  participant ReqEx as RequestExample

  Page->>OpenApi: render with { path, method, [specUrl], [overrides] }
  OpenApi->>Fetch: fetch(specUrl)
  Fetch-->>OpenApi: OpenAPI JSON
  OpenApi->>Transform: build ApiEndpointMeta
  Transform-->>OpenApi: ApiEndpointMeta
  OpenApi->>ApiUI: <ApiEndpoint metadata />

  alt multiple request examples
    ApiUI->>DynEx: render dynamic examples + params
  else single example
    ApiUI->>ReqEx: render example
  end
Loading
sequenceDiagram
  participant DynEx as DynamicRequestExample
  participant User as User
  participant ReqEx as RequestExample
  participant Params as Parameter Sections

  DynEx->>ReqEx: provide code examples (fetch/curl, types)
  DynEx->>Params: render headers/path/query/body sections
  User->>DynEx: change format or example type
  DynEx->>ReqEx: update selected example
  DynEx->>Params: update shown body parameters
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Warning

Review ran into problems

🔥 Problems

Errors were encountered while retrieving linked issues.

Errors (1)
  • TEAM-0000: Entity not found: Issue - Could not find referenced Issue.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch _Docs_Replace_custom_API_endpoint_with_OpenAPI_component

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

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

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 for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

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

@vercel vercel bot temporarily deployed to Preview – thirdweb-www August 11, 2025 11:18 Inactive
@github-actions github-actions bot added the Portal Involves changes to the Portal (docs) codebase. label Aug 11, 2025
Copy link
Member Author

joaquim-verges commented Aug 11, 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.

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

@joaquim-verges joaquim-verges marked this pull request as ready for review August 11, 2025 11:18
@joaquim-verges joaquim-verges requested review from a team as code owners August 11, 2025 11:18
@codecov
Copy link

codecov bot commented Aug 11, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 56.32%. Comparing base (be28b0c) to head (ea3cb7d).
⚠️ Report is 2 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #7829   +/-   ##
=======================================
  Coverage   56.32%   56.32%           
=======================================
  Files         905      905           
  Lines       58820    58820           
  Branches     4148     4148           
=======================================
  Hits        33133    33133           
  Misses      25581    25581           
  Partials      106      106           
Flag Coverage Δ
packages 56.32% <ø> (ø)
🚀 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.

@github-actions
Copy link
Contributor

github-actions bot commented Aug 11, 2025

size-limit report 📦

Path Size Loading time (3g) Running time (snapdragon) Total time
thirdweb (esm) 64.03 KB (0%) 1.3 s (0%) 97 ms (+141.76% 🔺) 1.4 s
thirdweb (cjs) 357.38 KB (0%) 7.2 s (0%) 149 ms (+8.29% 🔺) 7.3 s
thirdweb (minimal + tree-shaking) 5.72 KB (0%) 115 ms (0%) 78 ms (+1371.52% 🔺) 192 ms
thirdweb/chains (tree-shaking) 526 B (0%) 11 ms (0%) 65 ms (+3161.08% 🔺) 76 ms
thirdweb/react (minimal + tree-shaking) 19.16 KB (0%) 384 ms (0%) 71 ms (+460.48% 🔺) 454 ms

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 11, 2025 22:51 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 11, 2025 22:51 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui August 11, 2025 22:51 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb-www August 11, 2025 22:51 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 12, 2025 01:28 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 12, 2025 01:28 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui August 12, 2025 01:28 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb-www August 12, 2025 01:28 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 12, 2025 01:34 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 12, 2025 01:34 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb-www August 12, 2025 01:34 Inactive
@github-actions github-actions bot added the Playground Changes involving the Playground codebase. label Aug 12, 2025
Base automatically changed from _Docs_Add_AI_Chat_API_documentation_and_endpoint_metadata to main August 12, 2025 02:45
joaquim-verges and others added 10 commits August 12, 2025 14:47
Updated wallet and payments documentation to reflect new authentication and user management endpoints, including /v1/auth/initiate and /v1/auth/complete. Improved API reference sections, added OpenApiEndpoint usage, clarified pregeneration and user listing flows, and enhanced code samples for Unity and .NET SDKs. Refactored APIEndpoint component to show query parameters and examples, and updated AuthMethodsTabs to use new auth endpoints.
@joaquim-verges joaquim-verges force-pushed the _Docs_Replace_custom_API_endpoint_with_OpenAPI_component branch from 9014fb8 to 61a12fb Compare August 12, 2025 02:49
@vercel vercel bot temporarily deployed to Preview – thirdweb-www August 12, 2025 02:51 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 12, 2025 02:51 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui August 12, 2025 02:51 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 12, 2025 02:51 Inactive
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: 10

🔭 Outside diff range comments (2)
apps/portal/src/components/Document/AuthMethodsTabs.tsx (1)

125-146: Fix endpoint domain to match PR intent and OpenAPI migration (thirdweb-dev.com).

The HTTP snippets still point to api.thirdweb.com, but PR objectives and the high-level summary indicate moving OTP/auth routes to api.thirdweb-dev.com. Update both initiate and complete endpoints for email and phone flows.

Apply this diff:

-POST https://api.thirdweb.com/v1/auth/initiate
+POST https://api.thirdweb-dev.com/v1/auth/initiate
-POST https://api.thirdweb.com/v1/auth/complete
+POST https://api.thirdweb-dev.com/v1/auth/complete

Also applies to: 151-172

apps/portal/src/app/contracts/page.mdx (1)

23-23: Remove or fix lucide-react import to satisfy lint rule

Per repository rule, icons must use the Icon suffix; also this symbol isn’t used. Remove it to avoid lint errors.

Apply this diff:

-import { ExternalLink } from "lucide-react";
🧹 Nitpick comments (22)
apps/portal/src/components/Document/AuthMethodsTabs.tsx (1)

120-177: Optional: DRY the base URL to prevent future drift.

Both email and phone snippets duplicate the auth base URL. Centralizing it reduces the risk of future mismatches.

Add near the top-level (outside the snippet builders):

const AUTH_BASE = "https://api.thirdweb-dev.com/v1/auth";

Then interpolate in the HTTP snippet strings:

  • POST ${AUTH_BASE}/initiate
  • POST ${AUTH_BASE}/complete
apps/portal/src/app/payments/page.mdx (1)

185-206: Update wording in “Complete Payment” section

In apps/portal/src/app/payments/page.mdx (around line 197), the description uses “product ID” but should reference the payment ID. Apply:

-    Complete a payment using the product ID:
+    Complete a payment using the payment ID:

Please also verify that the following <OpenApiEndpoint> entries match your published OpenAPI spec:

  • POST /v1/payments
  • POST /v1/payments/{id}
  • POST /v1/payments/swap
apps/portal/src/components/Document/Details.tsx (2)

6-17: Add an explicit return type to match TS guidelines.

Be explicit about the component’s return type.

Apply this diff:

-export function Details(props: {
+export function Details(props: {
   summary: React.ReactNode;
   children: React.ReactNode;
   level?: number;
   headingClassName?: string;
   anchorId?: string;
   tags?: string[];
   noIndex?: boolean;
   startExpanded?: boolean;
   accordionItemClassName?: string;
   accordionTriggerClassName?: string;
-}) {
+}): React.ReactElement | null {

25-26: Confirm the named Tailwind group is intended; otherwise simplify.

You have both a named group on the container (group/details) and a default group on the trigger container. If the named group isn’t used by any variant (e.g., group-hover/details:), you can simplify to just group to reduce class noise.

Apply this diff if the named group is unused:

-        "group/details border-b-0 border-l transition-colors hover:border-active-border my-2",
+        "group border-b-0 border-l transition-colors hover:border-active-border my-2",
apps/portal/src/app/wallets/get-users/page.mdx (1)

31-47: Avoid duplicating params/headers; rely on OpenAPI rendering to prevent drift

Maintaining manual “Query Parameters” and “Authentication” sections alongside OpenApiEndpoint invites inconsistencies. The OpenAPI-driven component should be the single source of truth.

Apply this diff to remove the duplicated sections:

-### Query Parameters
-
-You can query by any of these user identifiers:
-
-- `address`: The user's wallet address that thirdweb generated
-- `email`: The user's email address
-- `phone`: The user's phone number
-- `externalWalletAddress`: The user's external wallet address (SIWE login)
-- `id`: The user's ID (for custom auth)
-
-### Authentication
-
-Required headers:
-- `x-secret-key`: Your secret key for authentication
-- `x-ecosystem-id` (optional): Your ecosystem ID
-- `x-ecosystem-partner-id` (optional): Your ecosystem partner ID
apps/portal/src/app/wallets/server/page.mdx (1)

46-67: Minimize manual example overrides to avoid spec drift

The responseExampleOverride is helpful, but it can diverge from the actual schema over time (e.g., field names/types). Prefer relying on the spec’s examples unless there’s a temporary gap.

If not strictly needed, apply this diff to defer to OpenAPI examples:

-<OpenApiEndpoint path="/v1/wallets/server" method="GET" responseExampleOverride={{
-    result: {
-      pagination: {
-        hasMore: false,
-        limit: 20,
-        page: 1,
-      },
-      wallets: [
-        {
-          address: "string",
-          profiles: [
-            {
-              type: "server",
-              identifier: "string",
-            },
-          ],
-          createdAt: "string",
-          smartWalletAddress: "string",
-        },
-      ],
-    }
-}} />
+<OpenApiEndpoint path="/v1/wallets/server" method="GET" />
apps/portal/src/app/wallets/custom-auth/page.mdx (1)

33-33: Fix typo: OIDC (not OICD)

Update the tab label.

Apply this diff:

-    <TabsTrigger value="jwt">JWT (OICD)</TabsTrigger>
+    <TabsTrigger value="jwt">JWT (OIDC)</TabsTrigger>
apps/portal/src/app/contracts/deploy/page.mdx (1)

37-47: Clarify the optional salt in SDK snippet

Using property shorthand for an undefined variable may confuse readers. Explicitly show the value or mark it optional inline.

Apply this diff:

-    constructorParams: {
-        param1: "value1",
-        param2: 123,
-    },
-    salt, // optional: salt enables deterministic deploys
+    constructorParams: {
+        param1: "value1",
+        param2: 123,
+    },
+    // optional: salt enables deterministic deploys
+    salt: "0x...optional-salt",
apps/portal/src/app/page.tsx (1)

28-39: Add explicit return types and consider extracting subcomponents

Per repository TypeScript guidelines, add explicit return types (e.g., JSX.Element) and consider extracting subcomponents to keep one stateless, single-responsibility function per file (especially for larger pages).

Example for one function:

-export default function Page() {
+export default function Page(): JSX.Element {

Repeat for Hero, AISection, ReferenceSection, LearningResourcesSection, SectionTitle, ArticleCardIndex, and SDKCard.

Also applies to: 41-77, 78-105, 106-171, 172-216, 218-224, 229-255, 257-285

apps/portal/src/app/wallets/pregenerate-wallets/page.mdx (1)

27-27: Consider specifying specUrl explicitly for consistency and resiliency

Other pages (e.g., AI Chat) pass specUrl to OpenApiEndpoint. Adding it here avoids relying on implicit defaults and protects against environment drift.

Apply this diff:

-<OpenApiEndpoint path="/v1/wallets/user" method="POST" />
+<OpenApiEndpoint path="/v1/wallets/user" method="POST" specUrl="https://api.thirdweb-dev.com/openapi.json" />
apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx (4)

28-70: Add explicit return types to align with TS guidelines

Annotate component return types for clarity and safer refactors.

Apply this diff:

-function InlineParameterItem({ param }: { param: APIParameter }) {
+function InlineParameterItem({ param }: { param: APIParameter }): React.ReactElement {
-function ParameterSection(props: {
+function ParameterSection(props: {
   title: string;
   parameters: APIParameter[];
-}) {
+}): React.ReactElement | null {
-export function DynamicRequestExample(props: DynamicRequestExampleProps) {
+export function DynamicRequestExample(props: DynamicRequestExampleProps): React.ReactElement {

51-66: Improve readability of example JSON and handle objects robustly

Pretty-print JSON for object/array examples to improve legibility.

Apply this diff:

-            code={
-              typeof param.example === "object"
-                ? JSON.stringify(param.example)
-                : String(param.example)
-            }
+            code={
+              typeof param.example === "object"
+                ? JSON.stringify(param.example, null, 2)
+                : String(param.example)
+            }

10-26: Prefer a type alias over interface for props per project conventions

This aligns with the repo guideline to favor type aliases except for nominal types.

Apply this diff:

-interface DynamicRequestExampleProps {
+type DynamicRequestExampleProps = {
   requestExamples: Array<{
     lang: "javascript" | "bash";
     code: string;
     label: string;
     format: "fetch" | "curl";
     exampleType?: string;
     bodyParameters?: APIParameter[];
   }>;
   endpointUrl: string;
   referenceUrl: string;
   method: string;
   pathParameters: APIParameter[];
   headers: APIParameter[];
   queryParameters: APIParameter[];
   hasMultipleExamples: boolean;
-}
+};

28-108: Optional: co-locate smaller components or split file to meet single-responsibility guideline

File currently defines three components. Consider nesting InlineParameterItem and ParameterSection inside DynamicRequestExample or moving them to their own files for clearer separation.

apps/portal/src/app/contracts/page.mdx (1)

72-83: Consider specifying specUrl on OpenApiEndpoint (consistency with other pages)

AI Chat page passes specUrl explicitly. Aligning here improves clarity and avoids relying on hidden defaults.

Apply this diff:

-    <OpenApiEndpoint path="/v1/contracts/read" method="POST" />
+    <OpenApiEndpoint path="/v1/contracts/read" method="POST" specUrl="https://api.thirdweb-dev.com/openapi.json" />
...
-	<OpenApiEndpoint path="/v1/contracts/write" method="POST" />
+	<OpenApiEndpoint path="/v1/contracts/write" method="POST" specUrl="https://api.thirdweb-dev.com/openapi.json" />
apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx (1)

14-31: Add explicit return type to RequestExample

Aligns with the guideline to declare explicit return types for TS components.

Apply this diff:

-export function RequestExample(props: {
+export function RequestExample(props: {
   codeExamples: Array<{
     label: string;
     code: React.ReactElement;
     format?: "fetch" | "curl";
     exampleType?: string;
   }>;
   method: string;
   endpointUrl: string;
   referenceUrl: string;
   onExampleChange?: (label: string) => void;
   onFormatChange?: (format: "fetch" | "curl") => void;
   onExampleTypeChange?: (exampleType: string) => void;
   hasSeparateDropdowns?: boolean;
   selectedExample?: (typeof props.codeExamples)[0];
   selectedFormat?: "fetch" | "curl";
   selectedExampleType?: string;
-}) {
+}): React.ReactElement {
apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx (4)

32-192: Consider simplifying the circular reference detection logic

The current implementation adds and deletes from the visited set multiple times. You can simplify this by cloning the set for recursive calls instead of using try/finally blocks.

Consider this simpler approach:

-function generateExampleFromSchema(schema: any, visited = new Set()): any {
+function generateExampleFromSchema(schema: any, visited = new Set<any>()): any {
   // Prevent infinite recursion with circular references
   if (visited.has(schema)) {
     return {};
   }
 
   if (!schema || typeof schema !== "object") {
     return null;
   }
 
   // If there's an explicit example, use it
   if (schema.example !== undefined) {
     return schema.example;
   }
 
   // If there are examples array, use the first one
   if (
     schema.examples &&
     Array.isArray(schema.examples) &&
     schema.examples.length > 0
   ) {
     return schema.examples[0];
   }
 
   // If there's a default value, use it
   if (schema.default !== undefined) {
     return schema.default;
   }
 
-  visited.add(schema);
+  const newVisited = new Set(visited);
+  newVisited.add(schema);
 
-  try {
     switch (schema.type) {
       // ... rest of the switch cases, passing newVisited instead of visited
       case "array":
         if (schema.items) {
-          const itemExample = generateExampleFromSchema(schema.items, visited);
+          const itemExample = generateExampleFromSchema(schema.items, newVisited);
           return [itemExample];
         }
         return [];
       // ... continue pattern for other recursive calls
     }
-  } finally {
-    visited.delete(schema);
-  }

246-276: Consider extracting hardcoded headers to a configuration object

The hardcoded headers and their properties should be extracted to a configuration object for better maintainability and reusability across different parts of the application.

+const DEFAULT_HEADERS: APIParameter[] = [
+  {
+    name: "x-secret-key",
+    type: "backend",
+    description:
+      "Project secret key - for backend usage only. Should not be used in frontend code.",
+    required: false,
+    example: undefined,
+  },
+  {
+    name: "x-client-id",
+    type: "frontend",
+    description:
+      "Project client ID - for frontend usage on authorized domains.",
+    required: false,
+    example: undefined,
+  },
+  {
+    name: "x-ecosystem-id",
+    type: "optional",
+    description: "Ecosystem ID - for ecosystem wallets.",
+    required: false,
+    example: undefined,
+  },
+  {
+    name: "x-ecosystem-partner-id",
+    type: "optional",
+    description: "Ecosystem partner ID - for ecosystem wallets.",
+    required: false,
+    example: undefined,
+  },
+];

 function transformOpenApiToApiEndpointMeta(
   spec: OpenApiSpec,
   path: string,
   method: string,
   requestBodyOverride?: Record<string, any>,
   responseExampleOverride?: Record<string, string>,
 ): ApiEndpointMeta {
   // ... existing code ...

   // push default headers hardcoded for now
-  headers.push({
-    name: "x-secret-key",
-    type: "backend",
-    description:
-      "Project secret key - for backend usage only. Should not be used in frontend code.",
-    required: false,
-    example: undefined,
-  });
-  headers.push({
-    name: "x-client-id",
-    type: "frontend",
-    description:
-      "Project client ID - for frontend usage on authorized domains.",
-    required: false,
-    example: undefined,
-  });
-  headers.push({
-    name: "x-ecosystem-id",
-    type: "optional",
-    description: "Ecosystem ID - for ecosystem wallets.",
-    required: false,
-    example: undefined,
-  });
-  headers.push({
-    name: "x-ecosystem-partner-id",
-    type: "optional",
-    description: "Ecosystem partner ID - for ecosystem wallets.",
-    required: false,
-    example: undefined,
-  });
+  headers.push(...DEFAULT_HEADERS);

278-290: Extract authentication logic to improve maintainability

The authentication header logic should be extracted to make it clearer and easier to maintain when authentication requirements change.

+function shouldAddAuthorizationHeader(method: string, path: string): boolean {
+  return (
+    method === "POST" &&
+    !path.includes("/v1/contracts/read") &&
+    !path.includes("/v1/auth")
+  );
+}

 // In transformOpenApiToApiEndpointMeta function:
-  if (
-    method === "POST" &&
-    !path.includes("/v1/contracts/read") &&
-    !path.includes("/v1/auth")
-  ) {
+  if (shouldAddAuthorizationHeader(method, path)) {
     headers.push({
       name: "Authorization",
       type: "frontend",
       description: "Bearer token (JWT) for user wallet authentication",
       required: false,
       example: undefined,
     });
   }

474-501: Improve error handling specificity

The error message could be more helpful by including the specific path and method that failed to load.

 async function OpenApiEndpointInner({
   specUrl = "https://api.thirdweb.com/openapi.json",
   path,
   method = "GET",
   requestBodyOverride,
   responseExampleOverride,
 }: OpenApiEndpointProps) {
   try {
     const spec = await fetchOpenApiSpec(specUrl);
     const metadata = transformOpenApiToApiEndpointMeta(
       spec,
       path,
       method,
       requestBodyOverride,
       responseExampleOverride,
     );
     return <ApiEndpoint metadata={metadata} key={specUrl + path + method} />;
   } catch (error) {
     return (
       <div className="rounded-lg border border-red-200 bg-red-50 p-4">
         <div className="text-sm text-red-800">
-          Failed to load OpenAPI specification:{" "}
+          Failed to load OpenAPI specification for {method} {path}:{" "}
           {error instanceof Error ? error.message : "Unknown error"}
         </div>
       </div>
     );
   }
 }
apps/portal/src/app/wallets/page.mdx (1)

443-447: Update code comment to match the actual implementation

The comment mentions "fetch the otp" but the SendOTP method appears to send rather than fetch the OTP.

 ```csharp
 var wallet = await InAppWallet.Create(client: client, email: "userEmail");
-await wallet.SendOTP(); // and fetch the otp
+await wallet.SendOTP(); // sends OTP to the user's email
 var address = await wallet.LoginWithOtp("userEnteredOTP"); // try catch and retry if needed
apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx (1)

407-409: Fallback value for body parameters without examples may cause confusion

When a body parameter lacks an example, the code falls back to using the parameter type as the value (Line 409). This could generate confusing examples like {"name": "string"} instead of realistic values.

Consider providing more meaningful fallback values based on the parameter type:

   for (const param of request.bodyParameters) {
     if (param.example !== undefined) {
       bodyObj[param.name] = param.example;
     } else {
-      bodyObj[param.name] = param.type || "";
+      // Provide more meaningful fallback values
+      switch (param.type) {
+        case "string":
+          bodyObj[param.name] = `<${param.name}>`;
+          break;
+        case "number":
+        case "integer":
+          bodyObj[param.name] = 0;
+          break;
+        case "boolean":
+          bodyObj[param.name] = false;
+          break;
+        case "array":
+          bodyObj[param.name] = [];
+          break;
+        case "object":
+          bodyObj[param.name] = {};
+          break;
+        default:
+          bodyObj[param.name] = `<${param.name}>`;
+      }
     }
   }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between be28b0c and ea3cb7d.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (27)
  • apps/playground-web/package.json (1 hunks)
  • apps/portal/package.json (1 hunks)
  • apps/portal/src/app/ai/chat/EndpointMetadata.tsx (0 hunks)
  • apps/portal/src/app/ai/chat/page.mdx (2 hunks)
  • apps/portal/src/app/ai/sidebar.tsx (1 hunks)
  • apps/portal/src/app/contracts/deploy/page.mdx (3 hunks)
  • apps/portal/src/app/contracts/events/page.mdx (2 hunks)
  • apps/portal/src/app/contracts/page.mdx (2 hunks)
  • apps/portal/src/app/contracts/transactions/page.mdx (2 hunks)
  • apps/portal/src/app/page.tsx (3 hunks)
  • apps/portal/src/app/payments/page.mdx (2 hunks)
  • apps/portal/src/app/transactions/monitor/page.mdx (2 hunks)
  • apps/portal/src/app/transactions/page.mdx (2 hunks)
  • apps/portal/src/app/transactions/sponsor/page.mdx (3 hunks)
  • apps/portal/src/app/wallets/custom-auth/page.mdx (3 hunks)
  • apps/portal/src/app/wallets/get-users/page.mdx (2 hunks)
  • apps/portal/src/app/wallets/page.mdx (7 hunks)
  • apps/portal/src/app/wallets/pregenerate-wallets/page.mdx (2 hunks)
  • apps/portal/src/app/wallets/server/page.mdx (2 hunks)
  • apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx (5 hunks)
  • apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx (1 hunks)
  • apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx (1 hunks)
  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx (3 hunks)
  • apps/portal/src/components/Document/APIEndpointMeta/common.tsx (0 hunks)
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx (4 hunks)
  • apps/portal/src/components/Document/Details.tsx (2 hunks)
  • apps/portal/src/components/Document/index.ts (1 hunks)
💤 Files with no reviewable changes (2)
  • apps/portal/src/components/Document/APIEndpointMeta/common.tsx
  • apps/portal/src/app/ai/chat/EndpointMetadata.tsx
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

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

Files:

  • apps/portal/src/app/ai/sidebar.tsx
  • apps/portal/src/components/Document/Details.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx
  • apps/portal/src/components/Document/index.ts
  • apps/portal/src/app/page.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

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

Files:

  • apps/portal/src/app/ai/sidebar.tsx
  • apps/portal/src/components/Document/Details.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
  • apps/portal/src/components/Document/AuthMethodsTabs.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx
  • apps/portal/src/components/Document/index.ts
  • apps/portal/src/app/page.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx
🧠 Learnings (9)
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*client.tsx : Use React Query (`tanstack/react-query`) for all client data fetching.

Applied to files:

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

Applied to files:

  • apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to apps/{dashboard,playground-web}/**/*.{ts,tsx} : Import UI primitives from `@/components/ui/*` (Button, Input, Select, Tabs, Card, Sidebar, Badge, Separator) in dashboard and playground apps

Applied to files:

  • apps/portal/src/components/Document/index.ts
📚 Learning: 2025-07-07T21:21:47.488Z
Learnt from: saminacodes
PR: thirdweb-dev/js#7543
File: apps/portal/src/app/pay/page.mdx:4-4
Timestamp: 2025-07-07T21:21:47.488Z
Learning: In the thirdweb-dev/js repository, lucide-react icons must be imported with the "Icon" suffix (e.g., ExternalLinkIcon, RocketIcon) as required by the new linting rule, contrary to the typical lucide-react convention of importing without the suffix.

Applied to files:

  • apps/portal/src/app/page.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
📚 Learning: 2025-07-18T19:20:32.530Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: .cursor/rules/dashboard.mdc:0-0
Timestamp: 2025-07-18T19:20:32.530Z
Learning: Applies to dashboard/**/*.{tsx,jsx} : Icons come from `lucide-react` or the project-specific `…/icons` exports – never embed raw SVG.

Applied to files:

  • apps/portal/src/app/page.tsx
  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
📚 Learning: 2025-07-31T16:17:42.753Z
Learnt from: MananTank
PR: thirdweb-dev/js#7768
File: apps/playground-web/src/app/navLinks.ts:1-1
Timestamp: 2025-07-31T16:17:42.753Z
Learning: Configuration files that import and reference React components (like icon components from lucide-react) need the "use client" directive, even if they primarily export static data, because the referenced components need to be executed in a client context when used by other client components.

Applied to files:

  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
📚 Learning: 2025-06-18T04:27:16.172Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7365
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx:16-17
Timestamp: 2025-06-18T04:27:16.172Z
Learning: Next.js Link component supports external URLs without throwing errors. When used with absolute URLs (like https://...), it behaves like a regular anchor tag without client-side routing, but does not cause runtime crashes or errors as previously believed.

Applied to files:

  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
📚 Learning: 2025-06-18T04:30:04.326Z
Learnt from: jnsdls
PR: thirdweb-dev/js#7365
File: apps/dashboard/src/app/(app)/team/[team_slug]/[project_slug]/(sidebar)/components/ProjectFTUX/ProjectFTUX.tsx:16-17
Timestamp: 2025-06-18T04:30:04.326Z
Learning: Next.js Link component fully supports both internal and external URLs and works appropriately with all standard anchor attributes including target="_blank", rel="noopener noreferrer", etc. Using Link for external URLs is completely appropriate and recommended.

Applied to files:

  • apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx
📚 Learning: 2025-07-18T19:19:55.613Z
Learnt from: CR
PR: thirdweb-dev/js#0
File: CLAUDE.md:0-0
Timestamp: 2025-07-18T19:19:55.613Z
Learning: Applies to packages/thirdweb/src/wallets/** : Support for in-app wallets (social/email login)

Applied to files:

  • apps/portal/src/app/wallets/page.mdx
🧬 Code Graph Analysis (5)
apps/portal/src/components/Document/Details.tsx (1)
apps/playground-web/src/lib/utils.ts (1)
  • cn (5-7)
apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx (4)
apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx (1)
  • APIParameter (9-20)
apps/portal/src/components/code/code.client.tsx (2)
  • CodeClient (27-54)
  • CodeLoading (19-25)
apps/portal/src/components/Document/Details.tsx (1)
  • Details (6-64)
apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx (1)
  • RequestExample (14-188)
apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx (2)
apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx (3)
  • ApiEndpointMeta (27-43)
  • APIParameter (9-20)
  • ApiEndpoint (45-229)
apps/portal/src/components/Document/index.ts (1)
  • OpenApiEndpoint (6-6)
apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx (1)
apps/portal/src/icons/index.ts (1)
  • ExternalLinkIcon (4-4)
apps/portal/src/components/Document/APIEndpointMeta/ApiEndpoint.tsx (3)
apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx (1)
  • DynamicRequestExample (112-209)
apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx (1)
  • RequestExample (14-188)
apps/portal/src/components/Document/Details.tsx (1)
  • Details (6-64)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Size
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (22)
apps/portal/src/components/Document/AuthMethodsTabs.tsx (1)

120-177: No lingering auth endpoint references outside AuthMethodsTabs.tsx

A global search for /v1/auth/initiate and /v1/auth/complete matches only in
apps/portal/src/components/Document/AuthMethodsTabs.tsx (lines 125, 134, 151, 160).
No occurrences found in MDX pages, ApiEndpoint.tsx, or OpenApiEndpoint.tsx.

apps/portal/src/components/Document/index.ts (1)

6-6: OpenApiEndpoint named export verified

The OpenApiEndpoint export in apps/portal/src/components/Document/index.ts correctly surfaces the named OpenApiEndpoint function from APIEndpointMeta/OpenApiEndpoint.tsx (line 466). MDX pages can now import it via @doc. LGTM.

apps/portal/src/app/transactions/monitor/page.mdx (3)

9-10: Importing OpenApiEndpoint into this page matches the new docs architecture.


48-53: Nice addition of “List transactions” endpoint for completeness.


42-47: OpenApiEndpoint “GET” support and spec path confirmed

No changes required.

apps/portal/src/app/contracts/events/page.mdx (2)

6-7: Importing OpenApiEndpoint aligns this page with OpenAPI-driven rendering.


35-35: No stale query-param references remain in docs
Searches for /v1/contracts/{address}/events?chainId= across apps/portal returned no matches—all links now use the {chainId} path parameter.

apps/portal/src/app/contracts/transactions/page.mdx (1)

6-7: Verify OpenAPI path and parameter rendering for contracts transactions

Swapping to OpenApiEndpoint looks good. Please confirm the OpenAPI spec exposes path params (chainId, address) and any relevant query params (e.g., decode/filters) so we don’t lose detail that the old inline docs provided.

Also applies to: 25-25

apps/portal/src/app/wallets/get-users/page.mdx (1)

56-83: Confirm the correct endpoint for “Get All Users”

Both “Single” and “All” tabs point to GET /v1/wallets/user. If listing is served by a separate endpoint (e.g., /v1/wallets/users or a different path), update the All Users tab accordingly. If the same endpoint lists when no identifier is provided, consider clarifying that behavior in the text.

apps/portal/src/app/wallets/server/page.mdx (1)

36-41: LGTM on switching to OpenApiEndpoint for server wallet creation

This succinctly replaces the static docs and centralizes details in the OpenAPI spec.

apps/portal/src/app/wallets/custom-auth/page.mdx (1)

71-75: Confirm /v1/auth/complete request shapes

Both examples target POST /v1/auth/complete with requestBodyOverride types "jwt" and "auth-payload". Please verify these discriminator values and the payload structure align with the OpenAPI schema, and that any required headers are rendered by OpenApiEndpoint.

Also applies to: 194-198

apps/portal/src/app/contracts/deploy/page.mdx (2)

1-10: Metadata export and OpenAPI-powered sections look good

Consistent with the overall migration to OpenApiEndpoint.


68-79: LGTM on adding API sections via OpenApiEndpoint

Endpoints for creating and listing contracts are now driven by the spec, reducing duplication.

apps/portal/src/app/page.tsx (1)

1-7: Icon import style complies with repo convention

lucide-react icons are imported with the Icon suffix, matching the enforced lint rule.

apps/portal/src/app/transactions/page.mdx (1)

72-82: Good move to OpenApiEndpoint for raw transaction sending

Centralizes request/response details and keeps the docs consistent with the API spec.

apps/portal/src/app/transactions/sponsor/page.mdx (1)

134-156: Engine (ERC-4337) example reads clearly

Using the Engine write endpoint with executionOptions is appropriate for ERC-4337 and clearly differentiated from the high-level API.

apps/portal/src/app/wallets/pregenerate-wallets/page.mdx (1)

27-27: No action needed: endpoint confirmed
The POST /v1/wallets/user operation is present in the OpenAPI spec, so this component can be merged as is.

apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx (1)

140-189: No additional guard needed for empty requestExamples in DynamicRequestExample

The ApiEndpoint component already only renders DynamicRequestExample when request.requestExamples.length > 0, so inside DynamicRequestExample you’re guaranteed a non-empty array. Adding {props.requestExamples.length > 0 && ...} is therefore unnecessary.

Likely an incorrect or invalid review comment.

apps/portal/src/app/contracts/page.mdx (1)

72-83: Endpoints Verified in OpenAPI Spec

Both /v1/contracts/read and /v1/contracts/write POST operations are present in the published OpenAPI spec, so no further action is needed here.

apps/portal/src/app/ai/chat/page.mdx (2)

25-25: LGTM on OpenAPI integration

Using OpenApiEndpoint with an explicit specUrl is clear and consistent. Nice.


36-45: Verified production API base URL consistency

I’ve confirmed that both the dev (https://api.thirdweb-dev.com/openapi.json) and prod (https://api.thirdweb.com/openapi.json) OpenAPI specs include the /ai/chat endpoint. Using https://api.thirdweb.com/ai as the base_url is correct for targeting the production API. No changes required.

apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx (1)

82-91: Nice touch: link to external reference with icon

Clear affordance and correct rel/target usage. Looks good.

"next-themes": "^0.4.6",
"nextjs-toploader": "^1.6.12",
"openapi-types": "^12.1.3",
"openapi-types": "12.1.3",
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Pinning openapi-types is fine; verify if it should be a devDependency and align versions workspace-wide.

If openapi-types is only used for TypeScript types, prefer moving it to devDependencies to keep production/runtime deps lean. Also ensure all packages pin the same version to avoid duplication.

Run this script to (a) find all imports/usages of openapi-types and (b) report every package.json that declares it and where (dependencies vs devDependencies):


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Usages of 'openapi-types' across the repo =="
rg -n --hidden --no-ignore -g '!**/node_modules/**' -e "from ['\"]openapi-types['\"]|require\(['\"]openapi-types['\"]\)" || true

echo
echo "== package.json declarations of 'openapi-types' =="
fd -H -t f package.json | while read -r f; do
  dep_ver=$(jq -r '.dependencies["openapi-types"] // empty' "$f")
  dev_ver=$(jq -r '.devDependencies["openapi-types"] // empty' "$f")
  if [[ -n "$dep_ver" || -n "$dev_ver" ]]; then
    echo "$f"
    if [[ -n "$dep_ver" ]]; then echo "  dependencies: $dep_ver"; fi
    if [[ -n "$dev_ver" ]]; then echo "  devDependencies: $dev_ver"; fi
  fi
done

Length of output: 4572


Move openapi-types to devDependencies and align versions

All imports of openapi-types in the repo are type‐only (import type { OpenAPIV3[_1] }…), so it does not need to ship at runtime. Currently it’s declared in dependencies in two spots:

• apps/playground-web/package.json (v12.1.3)
• apps/portal/package.json (v12.1.3)

Please:

  • Remove "openapi-types": "12.1.3" from dependencies in both package.json files
  • Add "openapi-types": "12.1.3" under devDependencies in both
  • Confirm no other packages declare it (all should use v12.1.3)
🤖 Prompt for AI Agents
In apps/playground-web/package.json (around line 25) and
apps/portal/package.json (search for the same dependency), move "openapi-types":
"12.1.3" out of "dependencies" and add it under "devDependencies" with the same
version string; remove the entry from dependencies in both files, add it to
devDependencies in both, and run a quick repo-wide search to confirm no other
package.json declares "openapi-types" at a different version (update any found
to 12.1.3 or remove if unnecessary).

"nextjs-toploader": "^1.6.12",
"node-html-markdown": "^1.3.0",
"node-html-parser": "^6.1.13",
"openapi-types": "12.1.3",
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Confirm openapi-types needs to be a runtime dependency; otherwise move to devDependencies.

If only used for typing, keep it in devDependencies to avoid bloating prod lockfiles and potential client bundles.

Run the same verification script from the playground package review or this package-local check:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Usages of 'openapi-types' in portal =="
rg -n --hidden --no-ignore -g 'apps/portal/**' -e "from ['\"]openapi-types['\"]|require\(['\"]openapi-types['\"]\)" || true

echo
echo "== portal/package.json declaration =="
jq '{dependencies: .dependencies["openapi-types"], devDependencies: .devDependencies["openapi-types"]}' apps/portal/package.json

Length of output: 650


Move openapi-types to devDependencies

openapi-types is only imported as a TypeScript type in apps/portal/src/components/Document/APIEndpointMeta/OpenApiEndpoint.tsx and isn’t used at runtime. Keeping it in dependencies bloats production installs and client bundles.

Please update apps/portal/package.json:

• Remove from dependencies
• Add under devDependencies

Example diff:

--- apps/portal/package.json
@@ dependencies:
-   "openapi-types": "12.1.3",
@@ devDependencies:
+  "openapi-types": "12.1.3",
📝 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.

Suggested change
"openapi-types": "12.1.3",
--- apps/portal/package.json
@@ "dependencies": {
- "openapi-types": "12.1.3",
@@ "devDependencies": {
+ "openapi-types": "12.1.3",
🤖 Prompt for AI Agents
In apps/portal/package.json around line 27, move "openapi-types": "12.1.3" out
of dependencies and add the same entry under devDependencies; remove the
key/value from the dependencies object, insert it into devDependencies, then run
your package manager (npm/yarn/pnpm) to update lockfiles so production installs
no longer include this type-only package.

Comment on lines +16 to 18
name: "Streaming Responses",
href: "/ai/chat/streaming",
},
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Rename to “Streaming Responses” looks good; verify route exists and unify API reference domain.

  • Ensure /ai/chat/streaming page exists to avoid dead links.
  • The API Reference link below uses api.thirdweb-dev.com while other pages in this PR use api.thirdweb.com. Consider switching to the canonical domain or centralizing as a constant.

Script to check the page exists and to find any lingering api.thirdweb-dev.com references:

Apply this diff to normalize the API Reference domain in this file:

-          href: "https://api.thirdweb-dev.com/reference#tag/ai/post/ai/chat",
+          href: "https://api.thirdweb.com/reference#tag/ai/post/ai/chat",

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify streaming page exists (any of TSX/MDX)
if test -d "apps/portal/src/app/ai/chat/streaming"; then
  fd -t f . apps/portal/src/app/ai/chat/streaming
else
  echo "Missing: apps/portal/src/app/ai/chat/streaming"
  exit 1
fi

# Find dev-domain API references across repo
echo
echo "Occurrences of api.thirdweb-dev.com/reference:"
rg -n --hidden --no-ignore -e "api\.thirdweb-dev\.com/reference" || true

Length of output: 581


Confirm /ai/chat/streaming route exists and normalize API Reference domain

  • Verified that apps/portal/src/app/ai/chat/streaming/page.mdx implements the /ai/chat/streaming route.
  • Update all remaining api.thirdweb-dev.com references to the canonical api.thirdweb.com:

• apps/portal/src/app/ai/sidebar.tsx (around line 21):

-          href: "https://api.thirdweb-dev.com/reference#tag/ai/post/ai/chat",
+          href: "https://api.thirdweb.com/reference#tag/ai/post/ai/chat",

• apps/portal/src/app/ai/chat/page.mdx (around line 55):

- [Full API Reference](https://api.thirdweb-dev.com/reference#tag/ai/post/ai/chat)
+ [Full API Reference](https://api.thirdweb.com/reference#tag/ai/post/ai/chat)

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

🤖 Prompt for AI Agents
In apps/portal/src/app/ai/sidebar.tsx around lines 16 to 18, the sidebar link
points to /ai/chat/streaming (confirming the route exists is already done) and
you must also normalize the API domain across the project: replace any remaining
occurrences of api.thirdweb-dev.com with api.thirdweb.com (specifically update
apps/portal/src/app/ai/sidebar.tsx near line 21 and
apps/portal/src/app/ai/chat/page.mdx near line 55) so all references use the
canonical api.thirdweb.com domain.

Comment on lines +60 to 63
Example sponsored contract write request:

{
"from": "0x...", // your user or server wallet **EOA address** address
"chainId": "1", // your chain id
"calls": [{
"contractAddress": "0x...",
"method": "function transfer(address to, uint256 amount)",
"params": ["0x...", "1000000000000000000"],
}],
}
```
<OpenApiEndpoint path="/v1/contracts/write" method="POST" />

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Align EIP-7702 example with the standard transactions endpoint

Other docs use POST /v1/transactions for thirdweb API. Using /v1/contracts/write here may be legacy/inconsistent and could confuse readers.

Apply this diff to align the endpoint:

-Example sponsored contract write request:
-
-<OpenApiEndpoint path="/v1/contracts/write" method="POST" />
+Example sponsored transaction request:
+
+<OpenApiEndpoint path="/v1/transactions" method="POST" />
📝 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.

Suggested change
Example sponsored contract write request:
{
"from": "0x...", // your user or server wallet **EOA address** address
"chainId": "1", // your chain id
"calls": [{
"contractAddress": "0x...",
"method": "function transfer(address to, uint256 amount)",
"params": ["0x...", "1000000000000000000"],
}],
}
```
<OpenApiEndpoint path="/v1/contracts/write" method="POST" />
Example sponsored transaction request:
<OpenApiEndpoint path="/v1/transactions" method="POST" />
🤖 Prompt for AI Agents
In apps/portal/src/app/transactions/sponsor/page.mdx around lines 60 to 63, the
example uses the legacy/incorrect endpoint POST /v1/contracts/write; update it
to use the standard thirdweb transactions endpoint POST /v1/transactions so it
matches other docs. Replace the OpenApiEndpoint path value from
"/v1/contracts/write" to "/v1/transactions" (keeping method="POST") and verify
any surrounding text or examples reference the transactions endpoint
consistently.


import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { useEffect, useState } from "react";
import CodeClient, { CodeLoading } from "../../code/code.client";
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect import: CodeClient is a named export, not default

code.client.tsx exports CodeClient as a named export. The default import will be undefined at runtime.

Apply this diff:

-import CodeClient, { CodeLoading } from "../../code/code.client";
+import { CodeClient, CodeLoading } from "../../code/code.client";
📝 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.

Suggested change
import CodeClient, { CodeLoading } from "../../code/code.client";
import { CodeClient, CodeLoading } from "../../code/code.client";
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
around line 5, the file currently does a default import of CodeClient which is
actually exported as a named export; replace the default import with a named
import so both symbols are imported correctly (e.g. import { CodeClient,
CodeLoading } from "../../code/code.client";), then save and run the app to
verify the runtime error is resolved.

Comment on lines +95 to +104
.sort((a, b) => {
if (a.required === b.required) {
return 0;
}
return a.required ? -1 : 1;
})
.map((param) => (
<InlineParameterItem key={param.name} param={param} />
))}
</div>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid mutating props when sorting parameters

Array.prototype.sort mutates in place; this mutates props.parameters. Copy before sorting.

Apply this diff:

-          {props.parameters
-            .sort((a, b) => {
+          {[...props.parameters]
+            .sort((a, b) => {
               if (a.required === b.required) {
                 return 0;
               }
               return a.required ? -1 : 1;
             })
             .map((param) => (
               <InlineParameterItem key={param.name} param={param} />
             ))}
📝 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.

Suggested change
.sort((a, b) => {
if (a.required === b.required) {
return 0;
}
return a.required ? -1 : 1;
})
.map((param) => (
<InlineParameterItem key={param.name} param={param} />
))}
</div>
{[...props.parameters]
.sort((a, b) => {
if (a.required === b.required) {
return 0;
}
return a.required ? -1 : 1;
})
.map((param) => (
<InlineParameterItem key={param.name} param={param} />
))}
</div>
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
around lines 95 to 104, the code calls .sort() directly on props.parameters
which mutates the original array; create a non-mutating copy (e.g., spread or
slice) of the parameters before sorting and then map over that sorted copy so
props.parameters are not mutated.

Comment on lines +113 to +116
const [selectedFormat, setSelectedFormat] = useState<"fetch" | "curl">(
"fetch",
);
const [selectedExampleType, setSelectedExampleType] = useState<string>("");
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Initialize selectedFormat based on available examples to avoid mismatched UI

Defaulting to "fetch" when no fetch example exists causes a mismatch (dropdown shows Fetch but code shows Curl). Initialize from props.requestExamples.

Apply this diff:

-  const [selectedFormat, setSelectedFormat] = useState<"fetch" | "curl">(
-    "fetch",
-  );
+  const [selectedFormat, setSelectedFormat] = useState<"fetch" | "curl">(() => {
+    if (props.requestExamples.some((ex) => ex.format === "fetch")) {
+      return "fetch";
+    }
+    return (props.requestExamples[0]?.format as "fetch" | "curl") ?? "fetch";
+  });
📝 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.

Suggested change
const [selectedFormat, setSelectedFormat] = useState<"fetch" | "curl">(
"fetch",
);
const [selectedExampleType, setSelectedExampleType] = useState<string>("");
const [selectedFormat, setSelectedFormat] = useState<"fetch" | "curl">(() => {
if (props.requestExamples.some((ex) => ex.format === "fetch")) {
return "fetch";
}
return (props.requestExamples[0]?.format as "fetch" | "curl") ?? "fetch";
});
const [selectedExampleType, setSelectedExampleType] = useState<string>("");
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
around lines 113 to 116, the state initializes selectedFormat to "fetch" and
selectedExampleType to an empty string which can mismatch UI when a fetch
example is not provided. Change the initialization to derive selectedFormat from
props.requestExamples (pick "fetch" if a fetch example exists, otherwise "curl"
or the first available format) and initialize selectedExampleType to a valid key
from requestExamples (e.g., first example type) so the dropdown and displayed
code always match the available examples.

Comment on lines +118 to +126
// Initialize selected example type from first available example
useEffect(() => {
if (props.requestExamples.length > 0) {
const firstExampleType =
props.requestExamples.find((ex) => ex.format === "fetch")
?.exampleType || "";
setSelectedExampleType(firstExampleType);
}
}, [props.requestExamples]);
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Initialize exampleType using the currently selected format, not hardcoded "fetch"

This avoids empty selections when fetch isn’t available.

Apply this diff:

-      const firstExampleType =
-        props.requestExamples.find((ex) => ex.format === "fetch")
-          ?.exampleType || "";
+      const firstExampleType =
+        props.requestExamples.find((ex) => ex.format === selectedFormat)
+          ?.exampleType || props.requestExamples[0]?.exampleType || "";
📝 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.

Suggested change
// Initialize selected example type from first available example
useEffect(() => {
if (props.requestExamples.length > 0) {
const firstExampleType =
props.requestExamples.find((ex) => ex.format === "fetch")
?.exampleType || "";
setSelectedExampleType(firstExampleType);
}
}, [props.requestExamples]);
// Initialize selected example type from first available example
useEffect(() => {
if (props.requestExamples.length > 0) {
const firstExampleType =
props.requestExamples.find((ex) => ex.format === selectedFormat)
?.exampleType || props.requestExamples[0]?.exampleType || "";
setSelectedExampleType(firstExampleType);
}
}, [props.requestExamples]);
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/APIEndpointMeta/DynamicRequestExample.tsx
around lines 118-126, the useEffect initializes the selected exampleType by
searching for an example with format === "fetch"; change it to search for the
example whose format matches the currently selected format (props.selectedFormat
or the component's selectedFormat prop/state) instead of the hardcoded "fetch",
and if no example matches that format fall back to the first available example's
exampleType (or empty string if none), then call setSelectedExampleType with
that resolved value.

Comment on lines +32 to +40
const [internalSelectedExample, setInternalSelectedExample] = useState(
props.codeExamples[0],
);
const [internalSelectedFormat, setInternalSelectedFormat] = useState<
"fetch" | "curl"
>("fetch");
const [internalSelectedExampleType, setInternalSelectedExampleType] =
useState<string>("");

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Initialize internal state safely when codeExamples updates

If codeExamples changes (or initially loads), ensure the internal state tracks the first available example to prevent undefined selection.

Apply this diff:

   const [internalSelectedExample, setInternalSelectedExample] = useState(
     props.codeExamples[0],
   );
@@
   const [internalSelectedExampleType, setInternalSelectedExampleType] =
     useState<string>("");
+
+  // Keep internal selection in sync if codeExamples change (uncontrolled mode)
+  useEffect(() => {
+    if (!props.selectedExample && props.codeExamples[0]) {
+      setInternalSelectedExample((prev) => prev ?? props.codeExamples[0]);
+    }
+  }, [props.codeExamples, props.selectedExample]);
📝 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.

Suggested change
const [internalSelectedExample, setInternalSelectedExample] = useState(
props.codeExamples[0],
);
const [internalSelectedFormat, setInternalSelectedFormat] = useState<
"fetch" | "curl"
>("fetch");
const [internalSelectedExampleType, setInternalSelectedExampleType] =
useState<string>("");
const [internalSelectedExample, setInternalSelectedExample] = useState(
props.codeExamples[0],
);
const [internalSelectedFormat, setInternalSelectedFormat] = useState<
"fetch" | "curl"
>("fetch");
const [internalSelectedExampleType, setInternalSelectedExampleType] =
useState<string>("");
// Keep internal selection in sync if codeExamples change (uncontrolled mode)
useEffect(() => {
if (!props.selectedExample && props.codeExamples[0]) {
setInternalSelectedExample((prev) => prev ?? props.codeExamples[0]);
}
}, [props.codeExamples, props.selectedExample]);
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/APIEndpointMeta/RequestExample.tsx around
lines 32-40, the initial internal state is set from props.codeExamples but it
won't update when codeExamples loads/changes; add a useEffect that watches
props.codeExamples and, if the array has at least one element, sets
internalSelectedExample to props.codeExamples[0] and sets
internalSelectedExampleType to the first example's type (or "" if missing),
otherwise clear internalSelectedExample and internalSelectedExampleType; keep
internalSelectedFormat default as "fetch".

Comment on lines +31 to 40
<span
className={cn(
"break-all font-bold text-foreground text-lg tracking-tight",
"break-all font-bold text-foreground text-sm tracking-tight",
"flex w-full gap-3 text-left font-semibold text-foreground group-hover:underline",
props.headingClassName,
)}
>
{props.summary}
</h4>
</span>
{props.tags && props.tags.length > 0 && (
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Restore heading semantics for accessibility (role/level) after switching from h4 to span.

Using a span drops heading semantics. Either use a heading tag or add ARIA attributes.

Apply this diff to add a11y attributes without changing layout:

-          <span
+          <span
+            role="heading"
+            aria-level={props.level ?? 4}
             className={cn(
               "break-all font-bold text-foreground text-sm tracking-tight",
               "flex w-full gap-3 text-left font-semibold text-foreground group-hover:underline",
               props.headingClassName,
             )}
           >
             {props.summary}
           </span>

Additionally, consider reinstating an actual heading tag (e.g., h4) if possible to improve document outline.

📝 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.

Suggested change
<span
className={cn(
"break-all font-bold text-foreground text-lg tracking-tight",
"break-all font-bold text-foreground text-sm tracking-tight",
"flex w-full gap-3 text-left font-semibold text-foreground group-hover:underline",
props.headingClassName,
)}
>
{props.summary}
</h4>
</span>
{props.tags && props.tags.length > 0 && (
<span
role="heading"
aria-level={props.level ?? 4}
className={cn(
"break-all font-bold text-foreground text-sm tracking-tight",
"flex w-full gap-3 text-left font-semibold text-foreground group-hover:underline",
props.headingClassName,
)}
>
{props.summary}
</span>
{props.tags && props.tags.length > 0 && (
🤖 Prompt for AI Agents
In apps/portal/src/components/Document/Details.tsx around lines 31 to 40, the
span that was used for the document heading removed native heading semantics;
update the element to restore accessibility by adding role="heading" and
aria-level="4" (or another appropriate level) to the span so it acts as a
heading without changing layout, keeping the existing className and content;
alternatively, replace the span with an actual heading tag (e.g., h4) if that
does not break styling.

@vercel vercel bot temporarily deployed to Preview – thirdweb-www August 12, 2025 03:33 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula August 12, 2025 03:33 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground August 12, 2025 03:33 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui August 12, 2025 03:33 Inactive
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

♻️ Duplicate comments (7)
apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx (1)

39-39: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Line 39) and request.queryParameters (Line 41).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 41-41

apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx (1)

18-19: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Lines 18-19) and request.queryParameters (Line 24).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 24-24

apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx (1)

33-33: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Line 33) and request.queryParameters (Line 35).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 35-35

apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx (1)

27-28: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Lines 27-28) and request.queryParameters (Line 33).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 33-33

apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx (1)

18-19: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Lines 18-19) and request.queryParameters (Line 21).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 21-21

apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx (1)

25-26: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Lines 25-26) and request.queryParameters (Line 28).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 28-28

apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx (1)

18-19: Same verification and nit as noted in update-session EndpointMetadata

  • Verify ApiEndpoint type compatibility for referenceUrl (Lines 18-19) and request.queryParameters (Line 21).
  • Consider centralizing the docs base URL to avoid drift.
  • Nit: add explicit return type to EndpointMetadata().

Also applies to: 21-21

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ea3cb7d and d6c40f9.

📒 Files selected for processing (8)
  • apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx (1 hunks)
  • apps/portal/src/app/nebula/api-reference/update-session/EndpointMetadata.tsx (2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

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

Files:

  • apps/portal/src/app/nebula/api-reference/update-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit Inference Engine (CLAUDE.md)

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

Files:

  • apps/portal/src/app/nebula/api-reference/update-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/execute/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/list-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/get-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/clear-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/chat/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/delete-session/EndpointMetadata.tsx
  • apps/portal/src/app/nebula/api-reference/create-session/EndpointMetadata.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Size
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)

Comment on lines +19 to +20
referenceUrl:
"https://api.thirdweb.com/reference#tag/ai/ai/update-session",
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Verification agent

🧩 Analysis chain

Reference URL anchor and empty queryParameters: verify compatibility and consider centralizing

  • Good call adding a direct referenceUrl (Lines 19-20) and explicit request.queryParameters: [] (Line 33) for consistency across endpoints.
  • Please verify that ApiEndpoint’s prop/types accept these new fields (referenceUrl, request.queryParameters) to avoid TS breakage in the skipped component files.
  • Suggest centralizing the docs base URL to avoid drift/typos across files. Example: const NEBULA_REF_BASE = "https://api.thirdweb.com/reference#tag/ai/ai"; then use ${NEBULA_REF_BASE}/update-session.

Nit (applies to all EndpointMetadata.* files in this PR): add an explicit return type to comply with our TS guideline.
Outside-selected-range change example:

export function EndpointMetadata(): JSX.Element {
  return (
    <ApiEndpoint
      metadata={{ /* ... */ }}
    />
  );
}

Run this to confirm type support and spot any mismatches:

Also applies to: 33-33


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching ApiEndpoint component/type for 'referenceUrl' and 'queryParameters'..."
fd -a 'ApiEndpoint.tsx' | while read -r f; do
  echo "== $f =="
  rg -n -A 5 -B 5 -e 'referenceUrl' -e 'queryParameters' -e 'ApiEndpoint' "$f" || true
done

echo
echo "Searching for metadata type definitions possibly used by ApiEndpoint..."
rg -n -A 5 -B 5 -S -e 'ApiEndpoint.*Props' -e 'ApiEndpointMetadata' -e 'OpenApiEndpoint'

echo
echo "Verifying all Nebula EndpointMetadata files set referenceUrl and queryParameters consistently..."
fd -a 'EndpointMetadata.tsx' apps/portal/src/app/nebula/api-reference | while read -r f; do
  echo "--- $f ---"
  rg -n 'referenceUrl|queryParameters' "$f" || true
done

Length of output: 42194


ApiEndpointMeta supports referenceUrl and queryParameters — centralize URL and add return types

  • We’ve confirmed in src/components/Document/APIEndpointMeta/ApiEndpoint.tsx that
    export type ApiEndpointMeta = {
      referenceUrl: string;
      request: { queryParameters: APIParameter[];  }
      
    }
    so adding referenceUrl and an empty queryParameters: [] will not break TS.
  • Extract the common docs base URL to avoid drift/typos. For example, in apps/portal/src/app/nebula/api-reference:
    // nebulaConstants.ts
    export const NEBULA_REF_BASE = "https://api.thirdweb.com/reference#tag/ai/ai";
    then in each EndpointMetadata.tsx:
    referenceUrl: `${NEBULA_REF_BASE}/update-session`,
  • Nit: add explicit return types to all EndpointMetadata functions:

-export function EndpointMetadata() {
+export function EndpointMetadata(): JSX.Element {
return (
<ApiEndpoint metadata={{ /* … */ }} />
);
}

- Affected files:
• apps/portal/src/app/nebula/api-reference/**/EndpointMetadata.tsx  
(chat, clear-session, create-session, delete-session, execute, get-session, list-session, update-session)

<!-- fingerprinting:phantom:poseidon:chinchilla -->

<!-- This is an auto-generated comment by CodeRabbit -->

@joaquim-verges joaquim-verges merged commit 438027a into main Aug 12, 2025
21 of 22 checks passed
@joaquim-verges joaquim-verges deleted the _Docs_Replace_custom_API_endpoint_with_OpenAPI_component branch August 12, 2025 04:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Playground Changes involving the Playground codebase. Portal Involves changes to the Portal (docs) codebase.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants