Skip to content

[SDK] Feature: update hey-api version to 0.76.0 #7431

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 14 commits into from
Jun 25, 2025

Conversation

PaoloRollo
Copy link
Contributor

@PaoloRollo PaoloRollo commented Jun 24, 2025

This PR updates the version of the @hey-api/openapi-ts package to 0.76.0 in the @thirdweb-dev/engine, @thirdweb-dev/insight and @thirdweb-dev/nebula packages. Also, it adds a check in the chain_id in the thirdweb package in case it gets returned as a string and not as a number.


PR-Codex overview

This PR focuses on updating the @hey-api dependencies, enhancing type definitions, and refining client configurations across multiple packages, including thirdweb, engine, and insight.

Detailed summary

  • Increased limit in .size-limit.json from 65 kB to 68 kB.
  • Updated @hey-api/openapi-ts version to 0.76.0 in package.json files.
  • Added new type definitions and improved existing ones in various client files.
  • Refined the handling of request and response in createClient functions.
  • Introduced new types related to agent tools and API tools in types.gen.ts.

The following files were skipped due to too many changes: packages/nebula/src/client/types.gen.ts, packages/engine/src/client/client/types.ts, packages/nebula/src/client/client/types.ts, packages/insight/src/client/client/types.ts, packages/insight/src/client/client/utils.ts, packages/engine/src/client/client/utils.ts, packages/nebula/src/client/client/utils.ts, packages/insight/src/client/sdk.gen.ts, pnpm-lock.yaml, packages/insight/src/client/types.gen.ts

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

Summary by CodeRabbit

  • New Features

    • Introduced fully configurable HTTP client modules with request/response interceptors, authentication, serialization, and flexible response parsing across multiple packages.
    • Added centralized utility modules for body and query serialization, URL construction, and middleware/interceptor management.
    • Expanded comprehensive type definitions for client configuration, request options, response handling, and parameter mapping.
    • Enhanced agent and tool management types with new API and builtin tool configurations and media support.
  • Enhancements

    • Improved API type safety with extended filtering options, detailed address documentation, and enriched price data in responses.
    • Added support for new response styles and configurable error handling.
    • Updated default API endpoints and enhanced type documentation.
    • Refined numeric type consistency for blockchain-related fields and improved response data structures.
  • Bug Fixes

    • Ensured consistent numeric types for fields like chain_id, block_number, and transaction values across APIs.
    • Fixed transaction history mapping to guarantee numeric chainId.
  • Chores

    • Upgraded dependencies including "hey-api" and related packages; removed deprecated fields and cleaned type definitions.
    • Updated TypeScript configurations to include iterable DOM interfaces for better typings.
    • Standardized code formatting and indentation in configuration files.

@PaoloRollo PaoloRollo requested review from a team as code owners June 24, 2025 18:10
@PaoloRollo PaoloRollo added merge-queue Adds the pull request to Graphite's merge queue. SDK Involves changes to the thirdweb SDK labels Jun 24, 2025
Copy link

changeset-bot bot commented Jun 24, 2025

🦋 Changeset detected

Latest commit: a036969

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

This PR includes changesets to release 5 packages
Name Type
thirdweb Minor
@thirdweb-dev/insight Minor
@thirdweb-dev/engine Minor
@thirdweb-dev/nebula Minor
@thirdweb-dev/wagmi-adapter Patch

Not sure what this means? Click here to learn what changesets are.

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

Copy link

vercel bot commented Jun 24, 2025

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

5 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Skipped (Inspect) Jun 25, 2025 2:55pm
nebula ⬜️ Skipped (Inspect) Jun 25, 2025 2:55pm
thirdweb_playground ⬜️ Skipped (Inspect) Jun 25, 2025 2:55pm
thirdweb-www ⬜️ Skipped (Inspect) Jun 25, 2025 2:55pm
wallet-ui ⬜️ Skipped (Inspect) Jun 25, 2025 2:55pm

Copy link
Contributor Author

PaoloRollo commented Jun 24, 2025

Merge activity

  • Jun 24, 6:10 PM UTC: The merge label 'merge-queue' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jun 25, 5:41 AM UTC: This pull request can not be added to the Graphite merge queue. Please try rebasing and resubmitting to merge when ready.
  • Jun 25, 5:41 AM UTC: Graphite disabled "merge when ready" on this PR due to: a merge conflict with the target branch; resolve the conflict and try again..
  • Jun 25, 5:41 AM UTC: The merge label 'merge-queue' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jun 25, 2:02 PM UTC: This pull request can not be added to the Graphite merge queue. Please try rebasing and resubmitting to merge when ready.
  • Jun 25, 2:02 PM UTC: Graphite disabled "merge when ready" on this PR due to: a merge conflict with the target branch; resolve the conflict and try again..
  • Jun 25, 2:02 PM UTC: The merge label 'merge-queue' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jun 25, 2:03 PM UTC: This pull request can not be added to the Graphite merge queue. Please try rebasing and resubmitting to merge when ready.
  • Jun 25, 2:03 PM UTC: Graphite disabled "merge when ready" on this PR due to: a merge conflict with the target branch; resolve the conflict and try again..
  • Jun 25, 2:03 PM UTC: The merge label 'merge-queue' was detected. This PR will be added to the Graphite merge queue once it meets the requirements.
  • Jun 25, 2:23 PM UTC: PaoloRollo added this pull request to the Graphite merge queue.
  • Jun 25, 2:28 PM UTC: The Graphite merge queue couldn't merge this PR because it was not satisfying all requirements (Failed CI: 'codecov/patch/packages').

Copy link
Contributor

coderabbitai bot commented Jun 24, 2025

## Walkthrough

This update replaces the dependency on `@hey-api/client-fetch` with new, locally implemented HTTP client modules in the `engine`, `insight`, and `nebula` packages. It introduces comprehensive, type-safe client libraries with utilities for serialization, authentication, interceptors, and configuration management. Type definitions for API responses and requests are updated and extended, including improved documentation, support for new fields, and more accurate typing for numeric and address fields. TypeScript configurations are updated to support iterable DOM interfaces. Minor logic adjustments ensure consistent handling of data types, such as `chainId`.

## Changes

| File(s) / Path(s)                                                                 | Change Summary                                                                                                         |
|-----------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|
| `.changeset/little-items-allow.md`                                                | Adds changeset documenting the hey-api update and affected packages.                                                  |
| `packages/engine/package.json`, `packages/insight/package.json`,<br>`packages/nebula/package.json` | Remove `@hey-api/client-fetch` dependency; update `@hey-api/openapi-ts` version.                                      |
| `packages/engine/src/client/client.gen.ts`,<br>`packages/insight/src/client/client.gen.ts`,<br>`packages/nebula/src/client/client.gen.ts` | Update import sources for client creation and config from external to local modules.                                  |
| `packages/engine/src/client/sdk.gen.ts`,<br>`packages/insight/src/client/sdk.gen.ts`,<br>`packages/nebula/src/client/sdk.gen.ts` | Update type imports from external to local, and pluralize response/error type names.                                  |
| `packages/engine/src/client/types.gen.ts`,<br>`packages/insight/src/client/types.gen.ts`,<br>`packages/nebula/src/client/types.gen.ts` | Extend and update API type definitions: add fields, adjust numeric/address types, improve documentation.              |
| `packages/engine/src/client/client/client.ts`,<br>`packages/insight/src/client/client/client.ts`,<br>`packages/nebula/src/client/client/client.ts` | New: Implement local, fully featured HTTP client with interceptors, serialization, config, and error handling.         |
| `packages/engine/src/client/client/index.ts`,<br>`packages/insight/src/client/client/index.ts`,<br>`packages/nebula/src/client/client/index.ts` | New: Centralized index modules re-exporting types and utilities for client packages.                                  |
| `packages/engine/src/client/client/types.ts`,<br>`packages/insight/src/client/client/types.ts`,<br>`packages/nebula/src/client/client/types.ts` | New: Comprehensive TypeScript types/interfaces for client config, options, and response handling.                     |
| `packages/engine/src/client/client/utils.ts`,<br>`packages/insight/src/client/client/utils.ts`,<br>`packages/nebula/src/client/client/utils.ts` | New: Utility modules for URL/query serialization, header merging, config, and interceptors.                           |
| `packages/engine/src/client/core/auth.ts`,<br>`packages/insight/src/client/core/auth.ts`,<br>`packages/nebula/src/client/core/auth.ts` | New: Auth token types and async utility for formatting/injecting authentication.                                      |
| `packages/engine/src/client/core/bodySerializer.ts`,<br>`packages/insight/src/client/core/bodySerializer.ts`,<br>`packages/nebula/src/client/core/bodySerializer.ts` | New: Utilities for serializing request bodies (JSON, form data, URL-encoded).                                         |
| `packages/engine/src/client/core/params.ts`,<br>`packages/insight/src/client/core/params.ts`,<br>`packages/nebula/src/client/core/params.ts` | New: Utilities for mapping input arguments to structured HTTP request parameters.                                     |
| `packages/engine/src/client/core/pathSerializer.ts`,<br>`packages/insight/src/client/core/pathSerializer.ts`,<br>`packages/nebula/src/client/core/pathSerializer.ts` | New: Utilities for serializing path/query parameters according to OpenAPI styles.                                     |
| `packages/engine/src/client/core/types.ts`,<br>`packages/insight/src/client/core/types.ts`,<br>`packages/nebula/src/client/core/types.ts` | New: Core client and config TypeScript interfaces for HTTP abstraction.                                               |
| `packages/engine/src/configure.ts`,<br>`packages/insight/src/configure.ts`,<br>`packages/nebula/src/configure.ts` | Update import source for `Config` and client utilities from external to local modules.                                |
| `packages/engine/tsconfig.base.json`,<br>`packages/insight/tsconfig.base.json`,<br>`packages/nebula/tsconfig.base.json` | Add `"DOM.Iterable"` to TypeScript `lib` for iterable DOM types; minor comment updates.                               |
| `packages/nebula/openapi-ts.config.ts`                                            | Formatting: Adjust indentation of config object.                                                                      |
| `packages/thirdweb/src/transaction/transaction-store.ts`                          | Ensure `chainId` is always a number by converting string values.                                                      |

## Sequence Diagram(s)

### High-Level HTTP Client Request Flow

```mermaid
sequenceDiagram
    participant UserApp
    participant Client
    participant Interceptors
    participant AuthUtil
    participant Fetch
    participant ResponseParser

    UserApp->>Client: request(options)
    Client->>Client: Merge config/options
    Client->>AuthUtil: setAuthParams()
    AuthUtil-->>Client: (auth headers/params)
    Client->>Interceptors: Apply request interceptors
    Interceptors-->>Client: (modified Request)
    Client->>Fetch: fetch(Request)
    Fetch-->>Client: Response
    Client->>Interceptors: Apply response interceptors
    Interceptors-->>Client: (modified Response)
    Client->>ResponseParser: Parse response (json/text/blob/etc)
    ResponseParser-->>Client: Parsed data/error
    Client-->>UserApp: Return data or error (per responseStyle/throwOnError)

Parameter Mapping Utility

sequenceDiagram
    participant SDK
    participant ParamsUtil

    SDK->>ParamsUtil: buildClientParams(args, fieldsConfig)
    ParamsUtil->>ParamsUtil: Map args to body/headers/path/query
    ParamsUtil-->>SDK: Params { body, headers, path, query }
Loading

Possibly related PRs

Suggested reviewers

  • jnsdls

<!-- walkthrough_end -->

<!-- This is an auto-generated comment: resource warnings by coderabbit.ai -->

> [!WARNING]
> ## Review ran into problems
> 
> <details>
> <summary>🔥 Problems</summary>
> 
> Errors were encountered while retrieving linked issues.
> 
> <details>
> <summary>Errors (1)</summary>
> 
> * TEAM-0000: Entity not found: Issue - Could not find referenced Issue.
> 
> </details>
> 
> </details>

<!-- end of auto-generated comment: resource warnings by coderabbit.ai -->
<!-- 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=7431):

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

Copy link
Contributor

graphite-app bot commented Jun 24, 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

socket-security bot commented Jun 24, 2025

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Updated@​hey-api/​openapi-ts@​0.72.1 ⏵ 0.76.097100100 +196 +1100

View full report

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: 15

🔭 Outside diff range comments (3)
packages/engine/src/configure.ts (1)

22-38: Improve custom stringify for full BigInt & replacer support

  1. JSON.stringify throws when the root value is a BigInt; convert it beforehand.
  2. Array-form replacers are silently ignored.
  3. Current wrapper allocates an extra closure on every call.

Suggested change:

-  const res = JSON.stringify(
-    value,
-    (key, value_) => {
-      const value__ = typeof value_ === "bigint" ? value_.toString() : value_;
-      return typeof replacer === "function" ? replacer(key, value__) : value__;
-    },
-    space,
-  );
+  const valueToSerialize =
+    typeof value === "bigint" ? value.toString() : value;
+  const res = JSON.stringify(
+    valueToSerialize,
+    typeof replacer === "function"
+      ? (key, v) => replacer(key, typeof v === "bigint" ? v.toString() : v)
+      : (key, v) => (typeof v === "bigint" ? v.toString() : v),
+    space,
+  );

This handles top-level BigInt, preserves array replacers, and avoids unnecessary allocations.

packages/nebula/src/client/core/pathSerializer.ts (1)

1-180: Consider extracting shared serialization logic to avoid duplication.

This file is identical to packages/insight/src/client/core/pathSerializer.ts. The same type safety issues exist here.

Consider creating a shared internal package (e.g., @thirdweb-dev/client-core) to house common utilities like this path serializer. This would:

  • Eliminate code duplication
  • Ensure consistency across packages
  • Simplify maintenance and bug fixes
  • Reduce bundle size for users who import multiple packages
packages/nebula/src/client/client/types.ts (1)

1-223: Eliminate code duplication across packages.

This file is an exact duplicate of packages/engine/src/client/client/types.ts. Having identical type definitions across multiple packages violates the DRY principle and makes maintenance difficult.

Consider creating a shared package or module for common client types that can be imported by engine, nebula, and insight packages. This would ensure consistency and reduce maintenance overhead.

Options:

  1. Create a @thirdweb-dev/client-core package with shared types
  2. Move common types to an existing shared package
  3. Use workspace references to share types from a single source
♻️ Duplicate comments (7)
packages/nebula/src/client/core/types.ts (1)

77-85: Same outdated documentation reference as in engine package.

The same Axios reference issue exists here. Since this is duplicated code, fixing the duplication would also resolve this documentation inconsistency.

packages/nebula/src/client/core/params.ts (1)

1-141: Critical: Identical complex logic duplicated across packages.

This file is identical to packages/engine/src/client/core/params.ts. Duplicating complex parameter building logic across multiple packages creates significant maintenance overhead and increases the risk of bugs due to inconsistent updates.

The same technical issues identified in the engine package apply here:

  • Line 100: Non-null assertion risk
  • Lines 66-72: Incomplete empty slot detection

Recommended approach:

  1. Extract this logic to a shared client utilities package
  2. Have all packages import from the shared implementation
  3. This ensures consistency and reduces maintenance burden
// Create packages/client-core/src/params.ts with this logic
// Then import in each package:
+import { buildClientParams } from "@thirdweb-dev/client-core";
packages/nebula/src/client/client/client.ts (1)

1-189: Identical implementation to insight package client.

This file is identical to packages/insight/src/client/client/client.ts. While this might be intentional for package independence, consider extracting shared client logic to a common package to reduce maintenance burden and ensure consistency.

The same error handling type safety issues identified in the insight package apply here (lines 142-171).

packages/engine/src/client/client/client.ts (1)

1-189: Third identical client implementation across packages.

This is the third identical copy of the client implementation (also in insight and nebula packages). The duplication pattern strongly suggests extracting this to a shared internal package.

Consider creating a shared @thirdweb-dev/internal-http-client package to house this common implementation, reducing the maintenance burden of keeping three copies in sync.

packages/engine/src/client/core/pathSerializer.ts (1)

1-180: Third instance of duplicated path serializer code.

This file is identical to both packages/insight/src/client/core/pathSerializer.ts and packages/nebula/src/client/core/pathSerializer.ts.

The code duplication across three packages significantly increases maintenance burden. Please consolidate these into a shared module.

packages/engine/src/client/client/utils.ts (1)

1-418: Similar utilities file with duplicated code and same issues.

This file is very similar to packages/nebula/src/client/client/utils.ts with minor differences (e.g., explicit "header" case on line 216).

The same issues exist here:

  1. Label style encoding issue (line 86-88)
  2. Return type mismatch in getParseAs (line 160)
  3. Interceptor index bug (line 339)

Consider consolidating these utility functions into a shared package to avoid maintaining multiple versions.

packages/insight/src/client/client/types.ts (1)

1-223: Code duplication across packages.

This file is another duplicate of the client types, identical to both packages/engine/src/client/client/types.ts and packages/nebula/src/client/client/types.ts.

Please see the previous comment about eliminating code duplication and creating a shared types module.

🧹 Nitpick comments (18)
.changeset/little-items-allow.md (1)

8-8: Consider a more descriptive changelog note
“update hey-api version to 0.76.0” is accurate but omits the larger context (internal client migration, removal of @hey-api/client-fetch). A one-liner such as “Upgrade to hey-api 0.76.0 and migrate to in-house HTTP client” gives consumers better insight when scanning the changelog.

packages/nebula/src/configure.ts (2)

2-6: Path looks correct but consider re-exporting to avoid “client/client”

"./client/client/index.js" is accurate relative to this file, yet it leaks the generated folder structure into public imports.
A tiny re-export stub at src/client/index.ts (already present in Engine/Insight) would let you import "./client/index.js" everywhere and keep future refactors internal.

-} from "./client/client/index.js";
+} from "./client/index.js";

You’d just need to add:

// src/client/index.ts
export * from "./client/index.js";

64-80: stringify could use stronger typing

Using any circumvents the benefit of strict TS. Swap to unknown and cast inside; it keeps the BigInt logic intact without disabling lint rules.

-function stringify(
-  // biome-ignore lint/suspicious/noExplicitAny: JSON.stringify signature
-  value: any,
+function stringify(
+  value: unknown,
   replacer?: (this: unknown, key: string, value: unknown) => unknown | null,
   space?: string | number,
 ) {
packages/engine/src/client/core/auth.ts (1)

35-37: Consider Node.js compatibility for base64 encoding.

The btoa() function is not available in Node.js environments without a polyfill. For better cross-platform compatibility, consider using a more universal approach.

-  if (auth.scheme === "basic") {
-    return `Basic ${btoa(token)}`;
-  }
+  if (auth.scheme === "basic") {
+    return `Basic ${typeof btoa !== 'undefined' ? btoa(token) : Buffer.from(token).toString('base64')}`;
+  }

Alternatively, consider using a dedicated base64 encoding utility that handles both browser and Node.js environments.

packages/nebula/src/client/core/auth.ts (1)

1-41: Consider consolidating duplicate authentication logic.

This authentication module is identical to packages/engine/src/client/core/auth.ts. Code duplication across packages increases maintenance burden and risk of inconsistencies.

Consider one of these approaches:

  1. Create a shared utility package for common client functionality
  2. Extract authentication logic to a common internal module
  3. Ensure any changes to auth logic are consistently applied across all packages

The same Node.js compatibility concern with btoa() applies here as well (see comment on engine auth module).

packages/nebula/src/client/client/index.ts (1)

1-23: LGTM! Clean barrel export pattern.

The centralized export approach provides a clean API surface and good separation of concerns. The use of .js extensions ensures proper ESM compatibility.

Minor suggestion: Consider grouping exports more logically for better readability:

+// Core types and utilities
 export type { Auth } from "../core/auth.js";
 export type { QuerySerializerOptions } from "../core/bodySerializer.js";
 export {
   formDataBodySerializer,
   jsonBodySerializer,
   urlSearchParamsBodySerializer,
 } from "../core/bodySerializer.js";
 export { buildClientParams } from "../core/params.js";
+
+// Client types and functions
 export { createClient } from "./client.js";
 export type {
   Client,
   ClientOptions,
   Config,
   CreateClientConfig,
   Options,
   OptionsLegacyParser,
   RequestOptions,
   RequestResult,
   ResponseStyle,
   TDataShape,
 } from "./types.js";
 export { createConfig, mergeHeaders } from "./utils.js";
packages/insight/src/client/core/types.ts (2)

49-60: Consider tightening headers type for better type safety.

The headers type is very permissive, allowing any value type including arrays and unknown. This could lead to runtime errors if invalid header values are passed.

Consider constraining to valid header value types:

  headers?:
    | RequestInit["headers"]
    | Record<
        string,
-        | string
-        | number
-        | boolean
-        | (string | number | boolean)[]
-        | null
-        | undefined
-        | unknown
+        string | string[] | undefined
      >;

HTTP headers should typically be strings or string arrays for multi-value headers.


81-83: Update outdated documentation reference.

The comment references "Axios API function" but this appears to be a custom HTTP client implementation, not Axios-based.

-   * This method will have no effect if the native `paramsSerializer()` Axios
-   * API function is used.
+   * This method will have no effect if a native `paramsSerializer()` 
+   * function is used.
packages/engine/src/client/core/types.ts (1)

77-85: Update outdated documentation reference.

The comment references "native paramsSerializer() Axios API function" which is misleading since this is a custom HTTP client implementation, not Axios.

   * A function for serializing request query parameters. By default, arrays
   * will be exploded in form style, objects will be exploded in deepObject
   * style, and reserved characters are percent-encoded.
   *
-  * This method will have no effect if the native `paramsSerializer()` Axios
-  * API function is used.
+  * This method provides custom query parameter serialization behavior.
   *
   * {@link https://swagger.io/docs/specification/serialization/#query View examples}
packages/insight/src/client/core/bodySerializer.ts (2)

17-23: Consider type safety improvement for FormData serialization.

The serializeFormDataPair function uses unknown type for the value parameter, but only handles string and Blob types explicitly. Consider adding more specific type guards or error handling for unsupported types.

const serializeFormDataPair = (data: FormData, key: string, value: unknown) => {
  if (typeof value === "string" || value instanceof Blob) {
    data.append(key, value);
+  } else if (value instanceof File) {
+    data.append(key, value);
  } else {
    data.append(key, JSON.stringify(value));
  }
};

37-84: Consider consolidating duplicate serialization logic.

The FormData and URLSearchParams serializers share very similar iteration and null-checking logic. Consider extracting a common utility function to reduce code duplication.

+const processEntries = <T>(
+  body: Record<string, any> | Array<Record<string, any>>,
+  processor: (key: string, value: unknown) => void
+) => {
+  Object.entries(body).forEach(([key, value]) => {
+    if (value === undefined || value === null) {
+      return;
+    }
+    if (Array.isArray(value)) {
+      value.forEach((v) => processor(key, v));
+    } else {
+      processor(key, value);
+    }
+  });
+};

export const formDataBodySerializer = {
  bodySerializer: <T extends Record<string, any> | Array<Record<string, any>>>(
    body: T,
  ) => {
    const data = new FormData();
-    Object.entries(body).forEach(([key, value]) => {
-      if (value === undefined || value === null) {
-        return;
-      }
-      if (Array.isArray(value)) {
-        value.forEach((v) => serializeFormDataPair(data, key, v));
-      } else {
-        serializeFormDataPair(data, key, value);
-      }
-    });
+    processEntries(body, (key, value) => serializeFormDataPair(data, key, value));
    return data;
  },
};
packages/engine/src/client/core/params.ts (1)

66-72: Consider edge case in empty slot detection.

The stripEmptySlots function only removes objects with no keys, but doesn't handle other "empty" values like empty arrays or null values that might be assigned to slots.

const stripEmptySlots = (params: Params) => {
  for (const [slot, value] of Object.entries(params)) {
-    if (value && typeof value === "object" && !Object.keys(value).length) {
+    if (
+      (value && typeof value === "object" && !Array.isArray(value) && !Object.keys(value).length) ||
+      (Array.isArray(value) && value.length === 0) ||
+      value === null ||
+      value === undefined
+    ) {
      delete params[slot as Slot];
    }
  }
};
packages/nebula/src/client/core/bodySerializer.ts (1)

65-84: URLSearchParams serializer maintains consistency with FormData implementation.

The implementation correctly mirrors the FormData serializer's logic and properly returns the string representation.

Consider extracting the common iteration logic (lines 71-80) shared with formDataBodySerializer into a reusable helper function to reduce code duplication:

+const iterateBodyEntries = <T>(
+  body: T,
+  callback: (key: string, value: unknown) => void
+) => {
+  Object.entries(body).forEach(([key, value]) => {
+    if (value === undefined || value === null) {
+      return;
+    }
+    if (Array.isArray(value)) {
+      value.forEach((v) => callback(key, v));
+    } else {
+      callback(key, value);
+    }
+  });
+};
packages/insight/src/client/core/params.ts (1)

98-105: Consider adding runtime safety for map access.

The non-null assertion on line 100 assumes the key exists in the map. While buildKeyMap should guarantee this, consider adding a runtime check for safety:

 if (config.key) {
-  const field = map.get(config.key)!;
+  const field = map.get(config.key);
+  if (!field) {
+    throw new Error(`Field configuration error: key "${config.key}" not found in map`);
+  }
   const name = field.map || config.key;
   (params[field.in] as Record<string, unknown>)[name] = arg;
 }
packages/nebula/src/client/client/utils.ts (1)

205-219: Add explicit "header" case for clarity.

While the default case handles header authentication, being explicit improves code clarity.

     switch (auth.in) {
       case "query":
         if (!options.query) {
           options.query = {};
         }
         options.query[name] = token;
         break;
       case "cookie":
         options.headers.append("Cookie", `${name}=${token}`);
         break;
+      case "header":
       default:
         options.headers.set(name, token);
         break;
     }
packages/engine/src/client/client/types.ts (1)

201-222: Add documentation for complex legacy parser type.

This conditional type handles various legacy parsing scenarios but lacks documentation explaining its purpose and behavior.

Consider adding a JSDoc comment:

+/**
+ * Utility type for legacy parsing that conditionally includes or omits
+ * body and headers based on the shape of TData. This ensures backward
+ * compatibility with different request data formats.
+ */
 export type OptionsLegacyParser<
packages/insight/src/client/client/utils.ts (1)

295-300: Consider making header object serialization configurable.

The function assumes all object headers should be JSON stringified, which might not always be appropriate for all APIs.

Consider accepting a serialization function as an optional parameter:

 export const mergeHeaders = (
+  options?: { objectSerializer?: (value: unknown) => string },
   ...headers: Array<Required<Config>["headers"] | undefined>
 ): Headers => {

Then use it for object serialization:

-        typeof value === "object" ? JSON.stringify(value) : (value as string),
+        typeof value === "object" 
+          ? (options?.objectSerializer?.(value) ?? JSON.stringify(value))
+          : (value as string),
packages/insight/src/client/types.gen.ts (1)

3233-3237: Clarify the input parameter documentation

The comment "hash" on line 3234 is potentially misleading since the full description indicates the input can be various types including block numbers, addresses, and signatures - not just hashes.

Consider removing the "hash" comment or expanding it to better reflect the parameter's versatility:

    /**
-     * hash
      * Can be a block number, transaction or block hash, address, event signature or function selector
      */
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bbff67d and a48d1cc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (48)
  • .changeset/little-items-allow.md (1 hunks)
  • packages/engine/package.json (1 hunks)
  • packages/engine/src/client/client.gen.ts (1 hunks)
  • packages/engine/src/client/client/client.ts (1 hunks)
  • packages/engine/src/client/client/index.ts (1 hunks)
  • packages/engine/src/client/client/types.ts (1 hunks)
  • packages/engine/src/client/client/utils.ts (1 hunks)
  • packages/engine/src/client/core/auth.ts (1 hunks)
  • packages/engine/src/client/core/bodySerializer.ts (1 hunks)
  • packages/engine/src/client/core/params.ts (1 hunks)
  • packages/engine/src/client/core/pathSerializer.ts (1 hunks)
  • packages/engine/src/client/core/types.ts (1 hunks)
  • packages/engine/src/client/sdk.gen.ts (14 hunks)
  • packages/engine/src/client/types.gen.ts (5 hunks)
  • packages/engine/src/configure.ts (1 hunks)
  • packages/engine/tsconfig.base.json (1 hunks)
  • packages/insight/package.json (1 hunks)
  • packages/insight/src/client/client.gen.ts (1 hunks)
  • packages/insight/src/client/client/client.ts (1 hunks)
  • packages/insight/src/client/client/index.ts (1 hunks)
  • packages/insight/src/client/client/types.ts (1 hunks)
  • packages/insight/src/client/client/utils.ts (1 hunks)
  • packages/insight/src/client/core/auth.ts (1 hunks)
  • packages/insight/src/client/core/bodySerializer.ts (1 hunks)
  • packages/insight/src/client/core/params.ts (1 hunks)
  • packages/insight/src/client/core/pathSerializer.ts (1 hunks)
  • packages/insight/src/client/core/types.ts (1 hunks)
  • packages/insight/src/client/sdk.gen.ts (44 hunks)
  • packages/insight/src/client/types.gen.ts (70 hunks)
  • packages/insight/src/configure.ts (1 hunks)
  • packages/insight/tsconfig.base.json (1 hunks)
  • packages/nebula/openapi-ts.config.ts (1 hunks)
  • packages/nebula/package.json (1 hunks)
  • packages/nebula/src/client/client.gen.ts (1 hunks)
  • packages/nebula/src/client/client/client.ts (1 hunks)
  • packages/nebula/src/client/client/index.ts (1 hunks)
  • packages/nebula/src/client/client/types.ts (1 hunks)
  • packages/nebula/src/client/client/utils.ts (1 hunks)
  • packages/nebula/src/client/core/auth.ts (1 hunks)
  • packages/nebula/src/client/core/bodySerializer.ts (1 hunks)
  • packages/nebula/src/client/core/params.ts (1 hunks)
  • packages/nebula/src/client/core/pathSerializer.ts (1 hunks)
  • packages/nebula/src/client/core/types.ts (1 hunks)
  • packages/nebula/src/client/sdk.gen.ts (1 hunks)
  • packages/nebula/src/client/types.gen.ts (3 hunks)
  • packages/nebula/src/configure.ts (1 hunks)
  • packages/nebula/tsconfig.base.json (1 hunks)
  • packages/thirdweb/src/transaction/transaction-store.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.@(ts|tsx)`: Accept a typed 'props' object and export a named function (e.g., export function MyComponent()). Combine class names via 'cn', expose 'className' prop if useful. ...

**/*.@(ts|tsx): Accept a typed 'props' object and export a named function (e.g., export function MyComponent()).
Combine class names via 'cn', expose 'className' prop if useful.
Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Local state or effects live inside; data fetching happens in hooks.
Merge class names with 'cn' from '@/lib/utils' to keep conditional logic readable.
Stick to design-tokens: background ('bg-card'), borders ('border-border'), muted text ('text-muted-foreground') etc.
Use the 'container' class with a 'max-w-7xl' cap for page width consistency.
Spacing utilities ('px-', 'py-', 'gap-*') are preferred over custom margins.
Responsive helpers follow mobile-first ('max-sm', 'md', 'lg', 'xl').
Never hard-code colors – always go through Tailwind variables.
Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Prefix files with 'import "server-only";' so they never end up in the client bundle (for server-only code).

  • packages/insight/src/configure.ts
  • packages/insight/src/client/client.gen.ts
  • packages/nebula/src/configure.ts
  • packages/engine/src/configure.ts
  • packages/engine/src/client/client.gen.ts
  • packages/nebula/src/client/client.gen.ts
  • packages/nebula/src/client/sdk.gen.ts
  • packages/nebula/openapi-ts.config.ts
  • packages/thirdweb/src/transaction/transaction-store.ts
  • packages/engine/src/client/core/auth.ts
  • packages/engine/src/client/types.gen.ts
  • packages/nebula/src/client/client/index.ts
  • packages/engine/src/client/client/index.ts
  • packages/insight/src/client/sdk.gen.ts
  • packages/engine/src/client/core/types.ts
  • packages/insight/src/client/core/auth.ts
  • packages/nebula/src/client/types.gen.ts
  • packages/engine/src/client/core/params.ts
  • packages/insight/src/client/core/types.ts
  • packages/nebula/src/client/core/auth.ts
  • packages/nebula/src/client/core/types.ts
  • packages/insight/src/client/core/bodySerializer.ts
  • packages/nebula/src/client/core/params.ts
  • packages/insight/src/client/client/index.ts
  • packages/engine/src/client/core/bodySerializer.ts
  • packages/nebula/src/client/core/bodySerializer.ts
  • packages/engine/src/client/sdk.gen.ts
  • packages/nebula/src/client/client/utils.ts
  • packages/engine/src/client/client/client.ts
  • packages/insight/src/client/core/pathSerializer.ts
  • packages/insight/src/client/client/client.ts
  • packages/insight/src/client/core/params.ts
  • packages/nebula/src/client/core/pathSerializer.ts
  • packages/nebula/src/client/client/client.ts
  • packages/engine/src/client/core/pathSerializer.ts
  • packages/insight/src/client/client/utils.ts
  • packages/engine/src/client/client/types.ts
  • packages/engine/src/client/client/utils.ts
  • packages/nebula/src/client/client/types.ts
  • packages/insight/src/client/client/types.ts
  • packages/insight/src/client/types.gen.ts
🧬 Code Graph Analysis (7)
packages/engine/src/client/core/types.ts (3)
packages/insight/src/client/core/types.ts (2)
  • Client (8-30)
  • Config (32-98)
packages/engine/src/client/core/auth.ts (2)
  • Auth (3-18)
  • AuthToken (1-1)
packages/engine/src/client/core/bodySerializer.ts (3)
  • BodySerializer (9-9)
  • QuerySerializer (7-7)
  • QuerySerializerOptions (11-15)
packages/nebula/src/client/core/bodySerializer.ts (3)
packages/nebula/src/client/client/index.ts (4)
  • QuerySerializerOptions (2-2)
  • formDataBodySerializer (4-4)
  • jsonBodySerializer (5-5)
  • urlSearchParamsBodySerializer (6-6)
packages/nebula/src/client/core/pathSerializer.ts (3)
  • SerializerOptions (10-16)
  • ArrayStyle (18-18)
  • ObjectStyle (21-21)
packages/vault-sdk/src/transaction-types.ts (1)
  • Blob (135-135)
packages/nebula/src/client/client/utils.ts (6)
packages/nebula/src/client/core/pathSerializer.ts (5)
  • ArrayStyle (18-18)
  • ArraySeparatorStyle (19-19)
  • serializeArrayParam (67-109)
  • serializeObjectParam (129-179)
  • serializePrimitiveParam (111-127)
packages/nebula/src/client/client/index.ts (7)
  • QuerySerializerOptions (2-2)
  • Config (13-13)
  • RequestOptions (17-17)
  • Client (11-11)
  • Options (15-15)
  • ClientOptions (12-12)
  • jsonBodySerializer (5-5)
packages/nebula/src/client/core/bodySerializer.ts (3)
  • QuerySerializerOptions (11-15)
  • QuerySerializer (7-7)
  • jsonBodySerializer (58-63)
packages/nebula/src/client/client/types.ts (5)
  • Config (10-59)
  • RequestOptions (61-82)
  • Client (165-167)
  • Options (191-199)
  • ClientOptions (129-133)
packages/nebula/src/client/core/types.ts (2)
  • Config (32-98)
  • Client (8-30)
packages/nebula/src/client/core/auth.ts (1)
  • getAuthToken (20-40)
packages/insight/src/client/client/client.ts (3)
packages/insight/src/client/client/utils.ts (7)
  • mergeHeaders (275-305)
  • mergeConfigs (266-273)
  • createConfig (408-416)
  • createInterceptors (386-390)
  • setAuthParams (189-222)
  • buildUrl (224-236)
  • getParseAs (148-187)
packages/insight/src/client/client/types.ts (3)
  • Config (10-59)
  • Client (165-167)
  • RequestOptions (61-82)
packages/insight/src/client/core/types.ts (2)
  • Config (32-98)
  • Client (8-30)
packages/insight/src/client/core/params.ts (1)
packages/engine/src/client/core/params.ts (4)
  • Field (3-13)
  • Fields (15-18)
  • FieldsConfig (20-20)
  • buildClientParams (74-141)
packages/engine/src/client/core/pathSerializer.ts (1)
packages/insight/src/client/core/pathSerializer.ts (10)
  • SerializerOptions (10-16)
  • ArrayStyle (18-18)
  • ArraySeparatorStyle (19-19)
  • ObjectStyle (21-21)
  • separatorArrayExplode (28-39)
  • separatorArrayNoExplode (41-52)
  • separatorObjectExplode (54-65)
  • serializeArrayParam (67-109)
  • serializePrimitiveParam (111-127)
  • serializeObjectParam (129-179)
packages/nebula/src/client/client/types.ts (3)
packages/nebula/src/client/core/types.ts (2)
  • Config (32-98)
  • Client (8-30)
packages/nebula/src/client/core/auth.ts (1)
  • Auth (3-18)
packages/nebula/src/client/client/utils.ts (1)
  • Middleware (373-383)
⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: Socket Security: Pull Request Alerts
🔇 Additional comments (50)
packages/nebula/tsconfig.base.json (1)

23-25: LGTM – iterable DOM typings enabled
Adding DOM.Iterable resolves missing iterator methods (e.g. Headers.entries()); no issues spotted.

packages/insight/src/configure.ts (1)

1-3: Verify post-build path resolution
The type-only import points to ./client/client/index.js, which is correct for NodeNext ESM provided the compiled file ends up at the same relative path. After the build, confirm that
dist/client/client/index.js (or your outDir equivalent) exists to avoid runtime resolution errors.

#!/bin/bash
# Ensure the built file exists (adjust OUT_DIR if different)
OUT_DIR=packages/insight/dist
test -f "$OUT_DIR/client/client/index.js" && echo "✓ path ok" || { echo "✗ missing"; exit 1; }
packages/engine/src/configure.ts (1)

1-3: Same path concern as in Insight
Double-check that ./client/client/index.js exists in the emitted output; otherwise consumers will hit a module-not-found at runtime.

packages/nebula/src/client/sdk.gen.ts (1)

3-8: Generated file – path update looks correct
Import now targets the new local client. No issues noted; leaving as generated.

packages/insight/package.json (1)

30-35: Ensure the external @hey-api/client-fetch code path is truly gone

Bumping @hey-api/openapi-ts is fine, but removal of @hey-api/client-fetch only pays off if no residual import remains in the Insight package (including tests and generated code).

#!/bin/bash
# List all occurrences of the old client inside the insight package
rg --line-number --pretty '@hey-api/client-fetch' packages/insight || true
packages/engine/src/client/client.gen.ts (1)

3-9: Import path swap LGTM

Generated code now consumes the in-house client (./client/index.js). No issues spotted.

packages/insight/src/client/client.gen.ts (1)

3-9: Consistent with Engine ‑ good

The generator was updated to the new local client path and compiles cleanly.

packages/engine/package.json (1)

30-35: Mirror the verification done for Insight

Same comment as for Insight: double-check that no code in engine still references @hey-api/client-fetch.

#!/bin/bash
rg --line-number --pretty '@hey-api/client-fetch' packages/engine || true
packages/nebula/src/client/client.gen.ts (1)

8-8: Import path looks correct – just verify build output location

"./client/index.js" resolves to src/client/client/index.tsdist/.../client/index.js, which matches the new folder layout.
No issues spotted here.

packages/insight/tsconfig.base.json (1)

22-25: Good addition of DOM.Iterable

This unblocks typing for Headers.entries() and similar APIs required by the new HTTP client. 👍

packages/engine/tsconfig.base.json (1)

22-25: Consistent lib targets

Adding "DOM.Iterable" keeps engine in sync with the other packages and prevents type mismatches. Looks good.

packages/thirdweb/src/transaction/transaction-store.ts (1)

88-89: LGTM! Good defensive programming.

The type conversion ensures chainId is consistently a number, handling cases where the API might return it as a string. This enhances type safety and prevents potential runtime issues.

packages/nebula/src/client/types.gen.ts (3)

547-550: LGTM! Consistent API evolution.

The addition of the optional summary field follows proper TypeScript conventions and maintains backward compatibility.


278-281: LGTM! Consistent field addition.

The summary field is consistently added across related response types, maintaining API coherence.


4277-4277: Verify the production baseUrl is correct.

The baseUrl has been updated from localhost to production. Ensure this URL is correct and accessible.

#!/bin/bash
# Description: Verify the production API endpoint is accessible
# Expected: HTTP response indicating the API is reachable

curl -I "https://nebula-api.thirdweb-dev.com" --connect-timeout 10 --max-time 30
packages/insight/src/client/sdk.gen.ts (2)

7-7: LGTM! Client migration to internal implementation.

The import path change from external @hey-api/client-fetch to internal ./client/index.js aligns with the PR's goal of reducing external dependencies.


11-133: Verify type name consistency across the codebase.

The type names have been systematically changed from singular to plural forms (e.g., GetV1WebhooksResponseGetV1WebhooksResponses). This could be a breaking change for external consumers.

#!/bin/bash
# Description: Check for any remaining references to the old singular type names
# Expected: No results if migration is complete

echo "Checking for old singular type names..."
rg -i "GetV1WebhooksResponse[^s]|GetV1BlocksResponse[^s]|GetV1EventsResponse[^s]" --type ts --type js
packages/engine/src/client/types.gen.ts (2)

20-23: LGTM! Improved documentation clarity.

The descriptive JSDoc comments clearly explain the purpose of each execution option type, making the API more self-documenting and developer-friendly.

Also applies to: 43-45, 79-82


139-139: LGTM! Enhanced account labeling support.

The optional label property addition provides better UX by allowing human-readable identifiers alongside addresses, which is valuable for account management interfaces.

Also applies to: 176-176

packages/engine/src/client/core/auth.ts (1)

20-40: LGTM! Well-designed authentication token handler.

The function elegantly handles both callback and direct token patterns with proper type safety. The scheme-based formatting (bearer/basic) follows standard HTTP authentication practices.

packages/insight/src/client/core/types.ts (1)

8-30: LGTM! Well-designed client interfaces.

The generic Client interface provides comprehensive HTTP method coverage with flexible type parameters. The Config interface is well-documented and supports both synchronous and asynchronous authentication patterns.

Also applies to: 32-98

packages/engine/src/client/client/index.ts (1)

1-22: Well-structured barrel export module.

The export organization is clean and follows good practices with proper separation of types vs. values and logical grouping of related functionality. The consistent use of .js extensions supports ESM compatibility.

packages/insight/src/client/core/auth.ts (1)

1-40: Solid authentication implementation.

The auth types and token handling function are well-designed. The getAuthToken function correctly handles both synchronous and asynchronous token resolution, and the authentication schemes (bearer/basic) are implemented according to standards.

packages/engine/src/client/core/types.ts (2)

8-30: Well-designed Client interface with proper generics.

The Client interface is well-structured with appropriate generic parameters that provide flexibility for different implementations while maintaining type safety.


32-98: Comprehensive Config interface with good type safety.

The Config interface covers all necessary HTTP client configuration options with appropriate type definitions and helpful documentation.

packages/insight/src/client/client/index.ts (1)

1-22: Consistent barrel export structure across packages.

The export organization matches the engine package structure, maintaining consistency in the modular design. This promotes predictable imports and good developer experience across the codebase.

packages/engine/src/client/sdk.gen.ts (3)

7-7: LGTM: Clean transition to internal client implementation.

The import path update from the external @hey-api/client-fetch package to the local ./client/index.js module is consistent with the PR's objective to internalize the HTTP client implementation.


15-16: LGTM: Enhanced error handling with specific error types.

The addition of specific error types (GetNativeBalanceErrors, GetTransactionAnalyticsSummaryErrors) for certain endpoints improves type safety and error handling capabilities.

Also applies to: 20-21, 277-278, 387-388


11-37: Verify the pluralized type naming convention is intentional.

The type names have been updated from singular to plural forms (e.g., CreateAccountResponseCreateAccountResponses). While this appears consistent across all imports, please confirm this naming change aligns with the new type definitions.

#!/bin/bash
# Description: Verify the pluralized response type naming convention in types.gen.ts
# Expected: All response types should follow the plural naming pattern

rg -A 2 "export.*Response(s|Error).*=" packages/engine/src/client/types.gen.ts
packages/insight/src/client/core/bodySerializer.ts (1)

58-63: LGTM: Proper bigint handling in JSON serialization.

The JSON serializer correctly handles bigint values by converting them to strings, which is necessary since JSON doesn't natively support bigint values.

packages/engine/src/client/core/params.ts (1)

22-28: LGTM: Clean special prefix handling for flexible parameter assignment.

The extraPrefixesMap provides a nice way to handle special prefixed keys that need to be assigned to specific slots, enhancing the flexibility of the parameter building system.

packages/nebula/src/client/core/bodySerializer.ts (4)

1-15: Well-structured type definitions and imports.

The type definitions for serializers are clean and the QuerySerializerOptions interface properly leverages the imported types from pathSerializer.


17-35: Helper functions properly handle type-specific serialization.

The separation between FormData and URLSearchParams serialization is well-designed, with appropriate handling of native vs. complex types.


37-56: FormData serializer correctly handles arrays and null values.

The implementation properly skips null/undefined values and supports multiple values per key through array handling, which aligns with standard form data behavior.


58-63: JSON serializer handles BigInt correctly.

Good implementation with proper BigInt handling through string conversion.

packages/insight/src/client/client/client.ts (4)

17-25: Config management properly encapsulates state.

The implementation correctly uses shallow copying to prevent external mutations and maintains clean config merging behavior.


42-56: Proper handling of authentication and empty request bodies.

The code correctly handles conditional authentication, body serialization, and prevents invalid requests by removing Content-Type headers for empty bodies.


64-81: Interceptor implementation and fetch handling are well-designed.

The sequential interceptor execution and the fetch assignment pattern (with explanatory comment) properly prevent the 'Illegal invocation' error. The non-null assertion is safe due to the fallback chain in line 38.


88-122: Comprehensive response parsing with proper empty response handling.

The implementation correctly handles all standard response types and appropriately manages empty responses and streams.

packages/insight/src/client/core/params.ts (2)

1-28: Well-designed type system for parameter configuration.

The discriminated union for Field types and the extra prefix mechanism provide good flexibility for parameter mapping.


38-57: Recursive key mapping is well-implemented.

The function correctly handles nested field configurations and properly guards against missing keys.

packages/engine/src/client/client/types.ts (2)

10-59: Well-structured configuration interface with good type safety.

The use of next?: never to explicitly disallow Next.js options in the Fetch client is a clever pattern for preventing configuration mistakes.


84-127: I’d like to verify how ResponseStyle and RequestResult are defined and used to understand if the value‐extraction is intentional.

#!/bin/bash
# Show the definition of ResponseStyle
rg "export type ResponseStyle" -n packages/engine/src

# Locate where ResponseStyle is documented or commented
rg "ResponseStyle" -C2 -n packages/engine/src

# Find all usages of RequestResult to see expected shapes
rg "RequestResult<" -C2 -n packages/engine/src
packages/insight/src/client/client/utils.ts (1)

189-222: Verify early return behavior in auth processing.

The function returns after processing the first valid auth token (line 220), ignoring any subsequent tokens in the security array. This behavior should be documented if intentional.

If this is the intended behavior, add a comment explaining why only the first valid token is used:

+    // Only the first valid auth token is used; subsequent tokens are ignored
     return;

If multiple auth tokens should be processed, remove the early return.

packages/insight/src/client/types.gen.ts (6)

1-1: Caution: Manual modifications to auto-generated file

This file is auto-generated by @hey-api/openapi-ts. Any manual changes will be overwritten on the next generation. Ensure all type modifications are made in the source OpenAPI specification.


1221-1231: Transaction value fields changed to string type

The change from number to string for transaction-related numeric fields (value, gas_price, etc.) is appropriate for handling large blockchain values that exceed JavaScript's safe integer range. This prevents precision loss.

Also applies to: 1237-1239, 1485-1495, 1501-1503, 1739-1749, 1755-1757


1233-1233: New optional field for transaction authorization

The addition of authorization_list_json?: string field appears to support transaction authorization features. This is a non-breaking change as the field is optional.

Also applies to: 1497-1497, 1751-1751, 3325-3325, 5446-5446


504-507: Improved documentation for address fields

The addition of JSDoc comments clarifying that address fields accept "address (hex or ENS)" improves API usability by making it clear that both formats are supported.

Also applies to: 580-583, 794-797, 1106-1107, 1175-1176, 1269-1272, 1375-1376, 1526-1529, 1633-1634


1921-1951: Enhanced token responses with comprehensive pricing data

The addition of the price_data object provides valuable market information including price, volume, market cap, and supply metrics. This enhancement improves the API's utility for token-related queries.

Also applies to: 2011-2041, 2142-2171, 2232-2261, 2394-2423, 2484-2513, 2702-2731, 3193-3222


2336-2359: Enhanced filtering capabilities for transfers

The addition of timestamp ranges, owner/contract filters, sorting options, and transfer type filters significantly improves the API's querying capabilities for both token and NFT transfers.

Also applies to: 4197-4227

Comment on lines 34 to 37
"devDependencies": {
"@biomejs/biome": "2.0.4",
"@hey-api/openapi-ts": "0.72.1",
"@hey-api/openapi-ts": "0.76.0",
"rimraf": "6.0.1",
"tslib": "^2.8.1"
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

Generation plugin removed from devDependencies

openapi-ts.config.ts still references the @hey-api/client-fetch plugin, yet the package has been removed from devDependencies.
The code-gen step (pnpm build:generate) will now fail with Cannot find module '@hey-api/client-fetch'.

Either:

  1. add it back under devDependencies, or
  2. delete it from the plugins array if it is no longer required.
🤖 Prompt for AI Agents
In packages/nebula/package.json around lines 34 to 38, the package
@hey-api/client-fetch was removed from devDependencies but is still referenced
in openapi-ts.config.ts plugins array. To fix this, either add
@hey-api/client-fetch back to devDependencies or remove it from the plugins
array in openapi-ts.config.ts if it is no longer needed, ensuring the code-gen
step does not fail due to missing module.

Comment on lines +4 to 7
input: "https://nebula-api.thirdweb-dev.com/openapi.json",
output: { format: "biome", lint: "biome", path: "src/client" },
plugins: ["@hey-api/client-fetch"],
});
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

Stale plugin reference

The plugins array still declares "@hey-api/client-fetch", contradicting the new in-house client strategy and the removed dependency.
Leaving it here causes runtime require() errors during code generation.

Action: remove the plugin or point to the new local client generator if one exists.

-  plugins: ["@hey-api/client-fetch"],
+  // plugins: ["@hey-api/client-fetch"], // ← delete or replace
📝 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
input: "https://nebula-api.thirdweb-dev.com/openapi.json",
output: { format: "biome", lint: "biome", path: "src/client" },
plugins: ["@hey-api/client-fetch"],
});
input: "https://nebula-api.thirdweb-dev.com/openapi.json",
output: { format: "biome", lint: "biome", path: "src/client" },
- plugins: ["@hey-api/client-fetch"],
+ // plugins: ["@hey-api/client-fetch"], // ← delete or replace
});
🤖 Prompt for AI Agents
In packages/nebula/openapi-ts.config.ts around lines 4 to 7, the plugins array
includes the outdated "@hey-api/client-fetch" plugin, which conflicts with the
new in-house client strategy and causes runtime require() errors. Remove the
"@hey-api/client-fetch" entry from the plugins array or replace it with the
correct new local client generator plugin if available to resolve these errors.

@@ -240,7 +248,7 @@ export const patchV1WebhooksByWebhookId = <
...options,
headers: {
"Content-Type": "application/json",
...options?.headers,
...options.headers,
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 potential runtime error from removing optional chaining.

The optional chaining has been removed from options?.headersoptions.headers. This could cause runtime errors if options is undefined or doesn't have a headers property.

Apply this diff to restore safe property access:

-      ...options.headers,
+      ...options?.headers,
-      ...options.headers,
+      ...options?.headers,

Also applies to: 821-821

🤖 Prompt for AI Agents
In packages/insight/src/client/sdk.gen.ts at lines 251 and 821, the optional
chaining was removed from accessing options.headers, which can cause runtime
errors if options is undefined. To fix this, restore the optional chaining by
changing options.headers back to options?.headers to safely access headers only
when options is defined.

Comment on lines +1 to +98
import type { Auth, AuthToken } from "./auth.js";
import type {
BodySerializer,
QuerySerializer,
QuerySerializerOptions,
} from "./bodySerializer.js";

export interface Client<
RequestFn = never,
Config = unknown,
MethodFn = never,
BuildUrlFn = never,
> {
/**
* Returns the final request URL.
*/
buildUrl: BuildUrlFn;
connect: MethodFn;
delete: MethodFn;
get: MethodFn;
getConfig: () => Config;
head: MethodFn;
options: MethodFn;
patch: MethodFn;
post: MethodFn;
put: MethodFn;
request: RequestFn;
setConfig: (config: Config) => Config;
trace: MethodFn;
}

export interface Config {
/**
* Auth token or a function returning auth token. The resolved value will be
* added to the request payload as defined by its `security` array.
*/
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
/**
* A function for serializing request body parameter. By default,
* {@link JSON.stringify()} will be used.
*/
bodySerializer?: BodySerializer | null;
/**
* An object containing any HTTP headers that you want to pre-populate your
* `Headers` object with.
*
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
*/
headers?:
| RequestInit["headers"]
| Record<
string,
| string
| number
| boolean
| (string | number | boolean)[]
| null
| undefined
| unknown
>;
/**
* The request method.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
*/
method?:
| "CONNECT"
| "DELETE"
| "GET"
| "HEAD"
| "OPTIONS"
| "PATCH"
| "POST"
| "PUT"
| "TRACE";
/**
* A function for serializing request query parameters. By default, arrays
* will be exploded in form style, objects will be exploded in deepObject
* style, and reserved characters are percent-encoded.
*
* This method will have no effect if the native `paramsSerializer()` Axios
* API function is used.
*
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
*/
querySerializer?: QuerySerializer | QuerySerializerOptions;
/**
* A function transforming response data before it's returned. This is useful
* for post-processing data, e.g. converting ISO strings into Date objects.
*/
responseTransformer?: (data: unknown) => Promise<unknown>;
/**
* A function validating response data. This is useful if you want to ensure
* the response conforms to the desired shape, so it can be safely passed to
* the transformers and returned to the user.
*/
responseValidator?: (data: unknown) => Promise<unknown>;
}
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

Address code duplication across packages.

This file is identical to packages/engine/src/client/core/types.ts. Consider consolidating these shared type definitions to reduce maintenance burden and prevent inconsistencies.

Options to address this:

  1. Create a shared types package that both engine and nebula can import from
  2. Move common types to a shared location and re-export them
  3. Use a code generation approach from a single source

This would improve maintainability and ensure consistency across packages.

🤖 Prompt for AI Agents
In packages/nebula/src/client/core/types.ts lines 1 to 98, the type definitions
are duplicated in packages/engine/src/client/core/types.ts. To fix this,
refactor by extracting these shared type definitions into a common shared
package or module that both nebula and engine can import from. Alternatively,
move the common types to a shared location and re-export them in each package.
This consolidation will reduce duplication and improve maintainability.

Comment on lines +86 to +88
const replaceValue = encodeURIComponent(
style === "label" ? `.${value as string}` : (value as string),
);
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 label style encoding to exclude the prefix from URL encoding.

The dot prefix for label style should not be URL-encoded.

Apply this fix:

       const replaceValue = encodeURIComponent(
-        style === "label" ? `.${value as string}` : (value as string),
+        value as string
       );
-      url = url.replace(match, replaceValue);
+      url = url.replace(match, style === "label" ? `.${replaceValue}` : replaceValue);
📝 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 replaceValue = encodeURIComponent(
style === "label" ? `.${value as string}` : (value as string),
);
const replaceValue = encodeURIComponent(
value as string
);
url = url.replace(match, style === "label" ? `.${replaceValue}` : replaceValue);
🤖 Prompt for AI Agents
In packages/nebula/src/client/client/utils.ts around lines 86 to 88, the dot
prefix for the "label" style is currently included inside the encodeURIComponent
call, causing it to be URL-encoded. To fix this, move the dot prefix outside of
the encodeURIComponent function so that only the value is encoded, and then
concatenate the dot prefix before the encoded value.

Comment on lines +337 to +343
if (typeof id === "number") {
return this._fns[id] ? id : -1;
} else {
return this._fns.indexOf(id);
}
}
exists(id: number | Interceptor) {
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 potential bug with interceptor index 0.

The check this._fns[id] will fail when id is 0 and could return incorrect results.

   getInterceptorIndex(id: number | Interceptor): number {
     if (typeof id === "number") {
-      return this._fns[id] ? id : -1;
+      return id >= 0 && id < this._fns.length ? id : -1;
     } else {
       return this._fns.indexOf(id);
     }
   }
📝 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
if (typeof id === "number") {
return this._fns[id] ? id : -1;
} else {
return this._fns.indexOf(id);
}
}
exists(id: number | Interceptor) {
getInterceptorIndex(id: number | Interceptor): number {
if (typeof id === "number") {
- return this._fns[id] ? id : -1;
+ return id >= 0 && id < this._fns.length ? id : -1;
} else {
return this._fns.indexOf(id);
}
}
🤖 Prompt for AI Agents
In packages/nebula/src/client/client/utils.ts around lines 337 to 343, the
condition this._fns[id] incorrectly treats index 0 as falsy, causing wrong
results. Replace the check with a condition that explicitly verifies if
this._fns[id] is not undefined, such as using this._fns[id] !== undefined, to
correctly handle index 0 and avoid returning -1 incorrectly.

Comment on lines +148 to +187
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}

const cleanContent = contentType.split(";")[0]?.trim();

if (!cleanContent) {
return;
}

if (
cleanContent.startsWith("application/json") ||
cleanContent.endsWith("+json")
) {
return "json";
}

if (cleanContent === "multipart/form-data") {
return "formData";
}

if (
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}

if (cleanContent.startsWith("text/")) {
return "text";
}

return;
};
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 return type inconsistency in getParseAs function.

The function returns undefined on line 160 and 186, but the return type doesn't include it.

Either update the return type or provide a default return value:

 export const getParseAs = (
   contentType: string | null,
-): Exclude<Config["parseAs"], "auto"> => {
+): Exclude<Config["parseAs"], "auto"> | undefined => {

Or return a default value like "stream" in all cases where you currently return undefined.

📝 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
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}
const cleanContent = contentType.split(";")[0]?.trim();
if (!cleanContent) {
return;
}
if (
cleanContent.startsWith("application/json") ||
cleanContent.endsWith("+json")
) {
return "json";
}
if (cleanContent === "multipart/form-data") {
return "formData";
}
if (
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}
if (cleanContent.startsWith("text/")) {
return "text";
}
return;
};
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> | undefined => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}
const cleanContent = contentType.split(";")[0]?.trim();
if (!cleanContent) {
return;
}
if (
cleanContent.startsWith("application/json") ||
cleanContent.endsWith("+json")
) {
return "json";
}
if (cleanContent === "multipart/form-data") {
return "formData";
}
if (
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}
if (cleanContent.startsWith("text/")) {
return "text";
}
return;
};
🤖 Prompt for AI Agents
In packages/nebula/src/client/client/utils.ts between lines 148 and 187, the
getParseAs function sometimes returns undefined, but its return type excludes
undefined. To fix this, ensure the function always returns a valid value of the
declared return type by replacing any return statements that currently return
undefined with a default value like "stream". This guarantees consistency with
the declared return type and avoids returning undefined.

Comment on lines +145 to +187
/**
* Infers parseAs value from provided Content-Type header.
*/
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}

const cleanContent = contentType.split(";")[0]?.trim();

if (!cleanContent) {
return;
}

if (
cleanContent.startsWith("application/json") ||
cleanContent.endsWith("+json")
) {
return "json";
}

if (cleanContent === "multipart/form-data") {
return "formData";
}

if (
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}

if (cleanContent.startsWith("text/")) {
return "text";
}

return;
};
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 return type to include undefined.

The function can return undefined at lines 160 and 186, but the return type Exclude<Config["parseAs"], "auto"> doesn't include undefined. This will cause type errors with strict null checks.

Update the return type:

 export const getParseAs = (
   contentType: string | null,
-): Exclude<Config["parseAs"], "auto"> => {
+): Exclude<Config["parseAs"], "auto"> | undefined => {
📝 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
/**
* Infers parseAs value from provided Content-Type header.
*/
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}
const cleanContent = contentType.split(";")[0]?.trim();
if (!cleanContent) {
return;
}
if (
cleanContent.startsWith("application/json") ||
cleanContent.endsWith("+json")
) {
return "json";
}
if (cleanContent === "multipart/form-data") {
return "formData";
}
if (
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}
if (cleanContent.startsWith("text/")) {
return "text";
}
return;
};
/**
* Infers parseAs value from provided Content-Type header.
*/
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> | undefined => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}
const cleanContent = contentType.split(";")[0]?.trim();
if (!cleanContent) {
return;
}
if (
cleanContent.startsWith("application/json") ||
cleanContent.endsWith("+json")
) {
return "json";
}
if (cleanContent === "multipart/form-data") {
return "formData";
}
if (
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}
if (cleanContent.startsWith("text/")) {
return "text";
}
return;
};
🤖 Prompt for AI Agents
In packages/insight/src/client/client/utils.ts around lines 145 to 187, the
function getParseAs can return undefined at lines 160 and 186, but the declared
return type Exclude<Config["parseAs"], "auto"> does not include undefined,
causing type errors. Update the return type to explicitly include undefined by
changing it to Exclude<Config["parseAs"], "auto"> | undefined to match all
possible return values.

@@ -536,10 +537,10 @@ export type GetV1EventsResponses = {
*/
200: {
data?: Array<{
chain_id: number;
block_number: string;
chain_id: string;
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

Type inconsistency for chain_id field

The chain_id field is typed as string in response data objects but as number in meta objects and query parameters. This inconsistency will cause TypeScript errors when working with chain IDs across different parts of the API.

For example:

  • Response: chain_id: string (lines 540, 754, 965, 1212)
  • Meta: chain_ids: Array<number> (lines 563, 777, 988, 1252)
  • Query: chain_id?: Array<number> (lines 378, 596, 811)

Also applies to: 563-563, 754-754, 777-777, 965-965, 988-988, 1212-1212, 1252-1252

🤖 Prompt for AI Agents
In packages/insight/src/client/types.gen.ts around lines 378, 540, 563, 596,
754, 777, 811, 965, 988, 1212, and 1252, the `chain_id` field is inconsistently
typed as string in response objects but as number or array of numbers in meta
and query objects. To fix this, unify the type of `chain_id` across all these
locations by changing all instances to use the same type, preferably `number` or
`Array<number>` as appropriate, ensuring consistency and preventing TypeScript
errors.

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: 11

🔭 Outside diff range comments (3)
packages/engine/src/client/core/params.ts (1)

1-142: Address code duplication across packages.

This file is identical to packages/nebula/src/client/core/params.ts. Consider extracting shared logic to a common utility package to avoid maintenance overhead.

The same issues from the nebula version apply here:

  • Line 100: Non-null assertion risk
  • Lines 87-96: Config variable persistence across iterations
  • Lines 66-72: Mutation behavior should be documented
packages/engine/src/client/core/bodySerializer.ts (1)

1-85: Consolidate identical implementations across packages.

This is the third identical copy of the bodySerializer implementation (also in insight and nebula packages). While the code quality is excellent, maintaining identical copies across multiple packages creates maintenance overhead.

Consider:

  1. Creating a shared utilities package for common serialization logic
  2. Or documenting why separate copies are necessary (e.g., packaging constraints)

The implementation itself is robust with proper type safety and edge case handling.

packages/insight/src/client/client/utils.ts (1)

1-417: Extract duplicated utility functions to a shared module.

This entire file is duplicated across the engine, insight, and nebula packages. This violates the DRY principle and will make maintenance difficult.

Consider creating a shared package (e.g., @thirdweb-dev/client-utils) to house these common utilities.

♻️ Duplicate comments (11)
packages/insight/src/client/client.gen.ts (1)

8-8: Same note as Engine: verify file exists & consider centralising client

See previous comments; duplication applies here as well.

packages/nebula/src/client/core/types.ts (1)

81-82: Fix documentation reference inconsistency.

The comment mentions "native paramsSerializer() Axios API function" but this is a fetch-based HTTP client, not Axios-based. This could confuse developers.

packages/nebula/src/client/client/client.ts (2)

158-158: Fix type casting issue with error fallback.

Same issue as in the engine package - incorrect type casting of empty object as string.

Apply this diff to fix:

-    finalError = finalError || ({} as string);
+    finalError = finalError || "";

1-189: Duplicate implementation detected.

This entire file is identical to packages/engine/src/client/client/client.ts. Consider extracting to a shared module.

packages/engine/src/client/core/pathSerializer.ts (1)

1-179: Duplicate implementation of pathSerializer.

This file is identical to packages/insight/src/client/core/pathSerializer.ts. Consider extracting to a shared module to maintain DRY principles.

packages/nebula/src/client/core/pathSerializer.ts (1)

1-179: Duplicate implementation of pathSerializer.

This file is identical to the pathSerializer in both insight and engine packages. Strong recommendation to extract to a shared module.

packages/insight/src/client/client/utils.ts (2)

148-162: Fix inconsistent return type in getParseAs function.

Same issue as in the engine package - the function can return undefined but the return type excludes it.


175-187: Fix missing return value at the end of getParseAs function.

Same issue as in the engine package - the function returns undefined which doesn't match the declared return type.

packages/nebula/src/client/client/utils.ts (2)

1-417: Another instance of duplicated utility functions.

This file is identical to the utils files in both engine and insight packages. As mentioned before, these utilities should be extracted to a shared module.


148-187: Same getParseAs function issues as in other packages.

The return type inconsistencies exist here as well.

packages/insight/src/client/client/types.ts (1)

1-223: Extract duplicated type definitions to a shared module.

This file is identical to packages/nebula/src/client/client/types.ts. Similar to the utility functions, these type definitions should be in a shared package to avoid duplication and ensure consistency across all client implementations.

🧹 Nitpick comments (13)
packages/nebula/src/configure.ts (2)

54-58: Minor TS-strictness: stay on the safe side when options is optional

Inside the spread you dereference options.authToken even though options is typed as possibly undefined.
Although control-flow narrowing usually saves you here, using the optional chain keeps the compiler silent under strictNullChecks + exactOptionalPropertyTypes.

-      ...(options?.authToken && {
-        authorization: `Bearer ${options.authToken}`,
+      ...(options?.authToken && {
+        authorization: `Bearer ${options?.authToken}`,
       }),

64-80: Same stringify helper duplicated in three packages

stringify is now present verbatim in engine, nebula, and insight. Extracting it to a small shared util (e.g. @thirdweb-dev/internal-json) avoids copy-pasta and keeps future fixes DRY.

packages/engine/src/client/client.gen.ts (1)

8-8: Import path updated – good, but duplication spotted

The generator now targets ./client/index.js, consistent with the new local client.
However, identical client code has been generated into every package. A single shared internal package would cut bundle size and maintenance cost.

packages/insight/src/client/client/client.ts (1)

12-15: Consider more specific typing for body parameter.

The body?: any type could be more specific to improve type safety.

-type ReqInit = Omit<RequestInit, "body" | "headers"> & {
-  body?: any;
-  headers: ReturnType<typeof mergeHeaders>;
-};
+type ReqInit = Omit<RequestInit, "body" | "headers"> & {
+  body?: BodyInit | null | Record<string, unknown>;
+  headers: ReturnType<typeof mergeHeaders>;
+};
packages/insight/src/client/core/types.ts (1)

81-82: Fix documentation reference inconsistency.

The comment mentions "native paramsSerializer() Axios API function" but this is a fetch-based HTTP client, not Axios-based. This could confuse developers.

-   * This method will have no effect if the native `paramsSerializer()` Axios
-   * API function is used.
+   * This method will have no effect if a native query parameter serializer
+   * is used.
packages/nebula/src/client/core/auth.ts (1)

35-37: Clarify basic auth token format expectations.

The basic auth implementation uses btoa(token) directly, which assumes the token is already in "username:password" format. Consider adding documentation to clarify this expectation or provide a helper function for combining username and password.

   if (auth.scheme === "basic") {
+    // Token should be in "username:password" format
     return `Basic ${btoa(token)}`;
   }
packages/nebula/src/client/core/params.ts (2)

87-96: Consider resetting config variable for clarity.

The config variable persists across iterations and may carry state from previous iterations. While this might be intentional behavior, it could be confusing.

   for (const [index, arg] of args.entries()) {
+    config = undefined;
     if (fields[index]) {
       config = fields[index];
     }

66-72: Document the mutation behavior.

The function mutates the input parameter object directly, which might be unexpected for callers.

+/**
+ * Removes empty slot objects from params in-place.
+ * @param params - The params object to modify
+ */
 const stripEmptySlots = (params: Params) => {
packages/nebula/src/client/core/bodySerializer.ts (1)

1-85: Address code duplication and approve implementation.

This file is identical to packages/insight/src/client/core/bodySerializer.ts. While the implementation is excellent with proper type handling, BigInt support, and array serialization, consider consolidating duplicate code across packages.

The serialization logic is well-implemented:

  • Proper type checking for FormData (string/Blob)
  • BigInt handling for JSON compatibility
  • Correct array element serialization
  • Appropriate null/undefined filtering
packages/engine/src/client/client/client.ts (2)

164-170: Address TODO: Improve error handling and types.

The TODO comment indicates that error handling and type definitions need improvement. Consider returning a consistent error structure.

Would you like me to generate an improved error handling implementation with better type safety?


17-189: Consider extracting shared client implementation.

The client implementation appears to be duplicated across multiple packages (engine, nebula, insight). Consider extracting this to a shared package to follow DRY principles.

This would:

  • Reduce maintenance burden
  • Ensure consistency across packages
  • Make updates easier to propagate
packages/engine/src/client/client/utils.ts (1)

205-219: Consider explicit case for "header" authentication.

The switch statement handles "header" authentication through the default case. Consider making it explicit for clarity.

Apply this diff for better readability:

       case "cookie":
         options.headers.append("Cookie", `${name}=${token}`);
         break;
+      case "header":
       default:
         options.headers.set(name, token);
         break;
packages/engine/src/client/client/types.ts (1)

201-222: Overly complex legacy parser type may impact maintainability

The OptionsLegacyParser type uses deeply nested conditional logic that could be difficult to maintain and debug. Consider breaking this into smaller, more focused utility types.

Example refactor:

type HasBody<T> = T extends { body?: any } ? true : false;
type HasHeaders<T> = T extends { headers?: any } ? true : false;

type OptionsLegacyParser<
  TData = unknown,
  ThrowOnError extends boolean = boolean,
  TResponseStyle extends ResponseStyle = "fields",
> = 
  HasBody<TData> extends true
    ? HasHeaders<TData> extends true
      ? // both body and headers case
      : // only body case
    : HasHeaders<TData> extends true
      ? // only headers case  
      : // neither case
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bbff67d and a48d1cc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (48)
  • .changeset/little-items-allow.md (1 hunks)
  • packages/engine/package.json (1 hunks)
  • packages/engine/src/client/client.gen.ts (1 hunks)
  • packages/engine/src/client/client/client.ts (1 hunks)
  • packages/engine/src/client/client/index.ts (1 hunks)
  • packages/engine/src/client/client/types.ts (1 hunks)
  • packages/engine/src/client/client/utils.ts (1 hunks)
  • packages/engine/src/client/core/auth.ts (1 hunks)
  • packages/engine/src/client/core/bodySerializer.ts (1 hunks)
  • packages/engine/src/client/core/params.ts (1 hunks)
  • packages/engine/src/client/core/pathSerializer.ts (1 hunks)
  • packages/engine/src/client/core/types.ts (1 hunks)
  • packages/engine/src/client/sdk.gen.ts (14 hunks)
  • packages/engine/src/client/types.gen.ts (5 hunks)
  • packages/engine/src/configure.ts (1 hunks)
  • packages/engine/tsconfig.base.json (1 hunks)
  • packages/insight/package.json (1 hunks)
  • packages/insight/src/client/client.gen.ts (1 hunks)
  • packages/insight/src/client/client/client.ts (1 hunks)
  • packages/insight/src/client/client/index.ts (1 hunks)
  • packages/insight/src/client/client/types.ts (1 hunks)
  • packages/insight/src/client/client/utils.ts (1 hunks)
  • packages/insight/src/client/core/auth.ts (1 hunks)
  • packages/insight/src/client/core/bodySerializer.ts (1 hunks)
  • packages/insight/src/client/core/params.ts (1 hunks)
  • packages/insight/src/client/core/pathSerializer.ts (1 hunks)
  • packages/insight/src/client/core/types.ts (1 hunks)
  • packages/insight/src/client/sdk.gen.ts (44 hunks)
  • packages/insight/src/client/types.gen.ts (70 hunks)
  • packages/insight/src/configure.ts (1 hunks)
  • packages/insight/tsconfig.base.json (1 hunks)
  • packages/nebula/openapi-ts.config.ts (1 hunks)
  • packages/nebula/package.json (1 hunks)
  • packages/nebula/src/client/client.gen.ts (1 hunks)
  • packages/nebula/src/client/client/client.ts (1 hunks)
  • packages/nebula/src/client/client/index.ts (1 hunks)
  • packages/nebula/src/client/client/types.ts (1 hunks)
  • packages/nebula/src/client/client/utils.ts (1 hunks)
  • packages/nebula/src/client/core/auth.ts (1 hunks)
  • packages/nebula/src/client/core/bodySerializer.ts (1 hunks)
  • packages/nebula/src/client/core/params.ts (1 hunks)
  • packages/nebula/src/client/core/pathSerializer.ts (1 hunks)
  • packages/nebula/src/client/core/types.ts (1 hunks)
  • packages/nebula/src/client/sdk.gen.ts (1 hunks)
  • packages/nebula/src/client/types.gen.ts (3 hunks)
  • packages/nebula/src/configure.ts (1 hunks)
  • packages/nebula/tsconfig.base.json (1 hunks)
  • packages/thirdweb/src/transaction/transaction-store.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.@(ts|tsx)`: Accept a typed 'props' object and export a named function (e.g., export function MyComponent()). Combine class names via 'cn', expose 'className' prop if useful. ...

**/*.@(ts|tsx): Accept a typed 'props' object and export a named function (e.g., export function MyComponent()).
Combine class names via 'cn', expose 'className' prop if useful.
Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Local state or effects live inside; data fetching happens in hooks.
Merge class names with 'cn' from '@/lib/utils' to keep conditional logic readable.
Stick to design-tokens: background ('bg-card'), borders ('border-border'), muted text ('text-muted-foreground') etc.
Use the 'container' class with a 'max-w-7xl' cap for page width consistency.
Spacing utilities ('px-', 'py-', 'gap-*') are preferred over custom margins.
Responsive helpers follow mobile-first ('max-sm', 'md', 'lg', 'xl').
Never hard-code colors – always go through Tailwind variables.
Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Prefix files with 'import "server-only";' so they never end up in the client bundle (for server-only code).

  • packages/engine/src/configure.ts
  • packages/engine/src/client/client.gen.ts
  • packages/nebula/src/client/client.gen.ts
  • packages/insight/src/client/client.gen.ts
  • packages/nebula/src/configure.ts
  • packages/nebula/openapi-ts.config.ts
  • packages/insight/src/configure.ts
  • packages/nebula/src/client/sdk.gen.ts
  • packages/thirdweb/src/transaction/transaction-store.ts
  • packages/nebula/src/client/core/types.ts
  • packages/insight/src/client/client/client.ts
  • packages/insight/src/client/client/index.ts
  • packages/engine/src/client/core/types.ts
  • packages/engine/src/client/types.gen.ts
  • packages/insight/src/client/core/params.ts
  • packages/engine/src/client/core/auth.ts
  • packages/nebula/src/client/core/auth.ts
  • packages/insight/src/client/core/types.ts
  • packages/engine/src/client/sdk.gen.ts
  • packages/insight/src/client/core/auth.ts
  • packages/engine/src/client/core/params.ts
  • packages/nebula/src/client/core/bodySerializer.ts
  • packages/engine/src/client/client/index.ts
  • packages/nebula/src/client/types.gen.ts
  • packages/nebula/src/client/core/params.ts
  • packages/insight/src/client/core/pathSerializer.ts
  • packages/nebula/src/client/client/client.ts
  • packages/nebula/src/client/client/index.ts
  • packages/nebula/src/client/core/pathSerializer.ts
  • packages/engine/src/client/core/bodySerializer.ts
  • packages/engine/src/client/core/pathSerializer.ts
  • packages/insight/src/client/core/bodySerializer.ts
  • packages/nebula/src/client/client/utils.ts
  • packages/nebula/src/client/client/types.ts
  • packages/engine/src/client/client/utils.ts
  • packages/insight/src/client/client/utils.ts
  • packages/insight/src/client/client/types.ts
  • packages/engine/src/client/client/client.ts
  • packages/engine/src/client/client/types.ts
  • packages/insight/src/client/types.gen.ts
  • packages/insight/src/client/sdk.gen.ts
🧬 Code Graph Analysis (9)
packages/engine/src/client/core/types.ts (3)
packages/insight/src/client/core/types.ts (2)
  • Client (8-30)
  • Config (32-98)
packages/engine/src/client/core/auth.ts (2)
  • Auth (3-18)
  • AuthToken (1-1)
packages/engine/src/client/core/bodySerializer.ts (3)
  • BodySerializer (9-9)
  • QuerySerializer (7-7)
  • QuerySerializerOptions (11-15)
packages/insight/src/client/core/params.ts (4)
packages/engine/src/client/core/params.ts (4)
  • Field (3-13)
  • Fields (15-18)
  • FieldsConfig (20-20)
  • buildClientParams (74-141)
apps/dashboard/src/middleware.ts (1)
  • config (11-24)
packages/engine/src/client/client/index.ts (1)
  • buildClientParams (8-8)
packages/insight/src/client/client/index.ts (1)
  • buildClientParams (8-8)
packages/engine/src/client/sdk.gen.ts (1)
packages/engine/src/client/types.gen.ts (15)
  • ListAccountsResponses (129-146)
  • CreateAccountResponses (166-183)
  • WriteContractResponses (232-323)
  • SendTransactionResponses (364-455)
  • SignTransactionResponses (567-607)
  • SignMessageResponses (644-684)
  • SignTypedDataResponses (730-770)
  • ReadContractResponses (815-827)
  • GetNativeBalanceResponses (859-871)
  • GetNativeBalanceErrors (848-857)
  • EncodeFunctionDataResponses (912-953)
  • SearchTransactionsResponses (972-1023)
  • GetTransactionAnalyticsResponses (1041-1059)
  • GetTransactionAnalyticsSummaryResponses (1087-1113)
  • GetTransactionAnalyticsSummaryErrors (1076-1085)
packages/nebula/src/client/core/bodySerializer.ts (3)
packages/nebula/src/client/client/index.ts (4)
  • QuerySerializerOptions (2-2)
  • formDataBodySerializer (4-4)
  • jsonBodySerializer (5-5)
  • urlSearchParamsBodySerializer (6-6)
packages/nebula/src/client/core/pathSerializer.ts (3)
  • SerializerOptions (10-16)
  • ArrayStyle (18-18)
  • ObjectStyle (21-21)
packages/vault-sdk/src/transaction-types.ts (1)
  • Blob (135-135)
packages/nebula/src/client/core/params.ts (2)
apps/dashboard/src/middleware.ts (1)
  • config (11-24)
packages/nebula/src/client/client/index.ts (1)
  • buildClientParams (8-8)
packages/engine/src/client/core/pathSerializer.ts (1)
packages/insight/src/client/core/pathSerializer.ts (10)
  • SerializerOptions (10-16)
  • ArrayStyle (18-18)
  • ArraySeparatorStyle (19-19)
  • ObjectStyle (21-21)
  • separatorArrayExplode (28-39)
  • separatorArrayNoExplode (41-52)
  • separatorObjectExplode (54-65)
  • serializeArrayParam (67-109)
  • serializePrimitiveParam (111-127)
  • serializeObjectParam (129-179)
packages/insight/src/client/core/bodySerializer.ts (5)
packages/engine/src/client/core/bodySerializer.ts (6)
  • QuerySerializer (7-7)
  • BodySerializer (9-9)
  • QuerySerializerOptions (11-15)
  • formDataBodySerializer (37-56)
  • jsonBodySerializer (58-63)
  • urlSearchParamsBodySerializer (65-84)
packages/engine/src/client/client/index.ts (4)
  • QuerySerializerOptions (2-2)
  • formDataBodySerializer (4-4)
  • jsonBodySerializer (5-5)
  • urlSearchParamsBodySerializer (6-6)
packages/insight/src/client/client/index.ts (4)
  • QuerySerializerOptions (2-2)
  • formDataBodySerializer (4-4)
  • jsonBodySerializer (5-5)
  • urlSearchParamsBodySerializer (6-6)
packages/engine/src/client/core/pathSerializer.ts (3)
  • SerializerOptions (10-16)
  • ArrayStyle (18-18)
  • ObjectStyle (21-21)
packages/vault-sdk/src/transaction-types.ts (1)
  • Blob (135-135)
packages/engine/src/client/client/utils.ts (5)
packages/engine/src/client/core/pathSerializer.ts (5)
  • ArrayStyle (18-18)
  • ArraySeparatorStyle (19-19)
  • serializeArrayParam (67-109)
  • serializeObjectParam (129-179)
  • serializePrimitiveParam (111-127)
packages/engine/src/client/client/index.ts (9)
  • QuerySerializerOptions (2-2)
  • Config (13-13)
  • RequestOptions (17-17)
  • Client (11-11)
  • mergeHeaders (22-22)
  • Options (15-15)
  • createConfig (22-22)
  • ClientOptions (12-12)
  • jsonBodySerializer (5-5)
packages/engine/src/client/core/bodySerializer.ts (3)
  • QuerySerializerOptions (11-15)
  • QuerySerializer (7-7)
  • jsonBodySerializer (58-63)
packages/engine/src/client/client/types.ts (5)
  • Config (10-59)
  • RequestOptions (61-82)
  • Client (165-167)
  • Options (191-199)
  • ClientOptions (129-133)
packages/engine/src/client/core/auth.ts (1)
  • getAuthToken (20-40)
packages/insight/src/client/sdk.gen.ts (2)
packages/insight/src/client/types.gen.ts (6)
  • GetV1WebhooksResponses (32-60)
  • GetV1WebhooksErrors (15-28)
  • PostV1WebhooksResponses (124-152)
  • PostV1WebhooksErrors (100-119)
  • DeleteV1WebhooksByWebhookIdResponses (190-218)
  • DeleteV1WebhooksByWebhookIdErrors (166-185)
packages/insight/src/client/client/types.ts (1)
  • Options (191-199)
🪛 GitHub Actions: CI
packages/thirdweb/src/transaction/transaction-store.ts

[error] 87-87: TypeScript error TS2322: Type '{ chainId: string; receipt: { status: "success" | "failed"; to: string; }; transactionHash: 0x${string}; }[]' is not assignable to type 'StoredTransaction[]'.

🔇 Additional comments (58)
packages/insight/tsconfig.base.json (1)

24-24: LGTM: Necessary DOM.Iterable support added.

The addition of "DOM.Iterable" to the lib array is essential for supporting iterable DOM interfaces like Headers.entries() which are commonly used in HTTP client implementations. This change is consistent across all packages and aligns with the local client implementation effort.

packages/engine/tsconfig.base.json (1)

24-24: LGTM: Consistent DOM.Iterable support added.

The addition of "DOM.Iterable" maintains consistency with other packages and provides necessary type support for iterable DOM interfaces used in the new HTTP client implementation.

packages/nebula/tsconfig.base.json (1)

24-24: LGTM: Consistent DOM.Iterable support maintained.

The addition of "DOM.Iterable" is consistent across all packages and provides necessary type support for DOM iterable interfaces.

packages/engine/src/client/core/types.ts (3)

1-6: LGTM: Well-structured imports for core dependencies.

The imports correctly reference local modules for authentication and serialization types, aligning with the PR's objective to replace external dependencies with local implementations.


8-30: LGTM: Comprehensive Client interface with proper generics.

The Client interface is well-designed with appropriate generic type parameters that allow for flexible implementations while maintaining type safety. The HTTP method coverage is complete and includes utility methods like buildUrl, getConfig, and setConfig.


32-98: LGTM: Comprehensive Config interface with excellent documentation.

The Config interface provides excellent coverage of HTTP client configuration options including:

  • Authentication with flexible token or function-based auth
  • Request/response serialization and transformation
  • Headers with flexible typing
  • HTTP methods with proper constraints
  • Query parameter serialization options

The JSDoc documentation is thorough and includes helpful links to MDN references.

packages/insight/src/configure.ts (1)

1-1: LGTM: Import path updated to use local client implementation.

The change from external package @hey-api/client-fetch to local module ./client/client/index.js aligns perfectly with the PR's objective to replace external dependencies with local implementations. This maintains the same functionality while providing better control over the client implementation.

packages/engine/src/configure.ts (1)

1-1: ```shell
#!/bin/bash

List all index.ts files under packages/engine/src/client

fd index.ts packages/engine/src/client


</details>
<details>
<summary>packages/nebula/src/configure.ts (1)</summary>

`2-6`: **Local client import mirrors Engine – LGTM**

Same rationale as the Engine package: the external dependency is gone and the local re-export keeps API parity.

</details>
<details>
<summary>packages/insight/package.json (1)</summary>

`32-32`: ```shell
#!/bin/bash
# Verify that pnpm-lock.yaml has been updated to 0.76.0 for @hey-api/openapi-ts
rg -n '@hey-api/openapi-ts@' -g 'pnpm-lock.yaml' | grep -v '0.76.0'
packages/nebula/src/client/client.gen.ts (1)

8-8: Verify local client implementation compatibility.

The import has been successfully redirected from the external @hey-api/client-fetch package to a local client implementation. Ensure that the local ./client/index.js module exports all the required types and functions (Config, createClient, createConfig, ClientOptions) with compatible interfaces.

#!/bin/bash
# Description: Verify that the local client module exports the required types and functions
# Expected: Find the local client implementation with compatible exports

# Check if the local client index file exists
fd "index.js" --type f --full-path packages/nebula/src/client/client/

# Search for the exported functions and types in the local client implementation
rg -A 5 "export.*createClient|export.*createConfig|export.*Config|export.*ClientOptions" packages/nebula/src/client/client/
packages/engine/package.json (1)

32-32: Verify compatibility of hey-api version update.

The update to @hey-api/openapi-ts version 0.76.0 should be verified for any breaking changes or compatibility issues with the current codebase generation.

What are the breaking changes and new features in @hey-api/openapi-ts version 0.76.0 compared to 0.72.1?
.changeset/little-items-allow.md (1)

1-8: Well-structured changeset documentation.

The changeset properly documents the version updates across all affected packages with appropriate minor version bumps. The description clearly summarizes the hey-api version update.

packages/nebula/openapi-ts.config.ts (1)

4-6: Formatting improvement for consistency.

The indentation standardization improves code consistency and readability without affecting functionality.

packages/nebula/src/client/sdk.gen.ts (1)

7-7: Consistent import redirection to local client.

The import change aligns with the broader refactoring effort to replace external @hey-api/client-fetch dependencies with local client implementations. This ensures consistency across the nebula package.

packages/nebula/package.json (1)

36-36: LGTM: hey-api version upgrade aligns with PR objectives.

The upgrade to @hey-api/openapi-ts version 0.76.0 is consistent with the PR goals.

packages/nebula/src/client/types.gen.ts (3)

547-550: LGTM: Enhanced AgentResponse with summary field.

The addition of the optional summary field improves the API response structure while maintaining backward compatibility.


2277-2281: LGTM: Enhanced RegistryAgentListResponse with summary field.

Consistent addition of the optional summary field across response types is good for API consistency.


2277-2277: LGTM: Updated baseUrl to production endpoint.

Changing the default baseUrl from localhost to the production endpoint "https://nebula-api.thirdweb-dev.com" is appropriate for production usage.

packages/engine/src/client/sdk.gen.ts (3)

7-7: LGTM: Migrated to local client implementation.

The import change from the external @hey-api/client-fetch package to the local ./client/index.js module aligns with the PR objective to replace external dependencies with local implementations.


11-37: LGTM: Updated type imports to use pluralized forms.

The systematic change from singular response type names (e.g., CreateAccountResponse) to plural forms (e.g., CreateAccountResponses) is consistent with the new local client implementation. The addition of error types for some functions also improves error handling capabilities.


65-403: LGTM: Updated generic type parameters consistently.

All HTTP client method calls have been updated to use the new pluralized response types and error types where applicable. The changes are systematic and maintain the same function signatures and behavior.

packages/engine/src/client/core/auth.ts (1)

1-41: LGTM: Well-structured authentication module.

This new authentication module provides comprehensive support for different authentication schemes and token retrieval methods:

  • Flexible auth configuration with support for headers, query params, and cookies
  • Proper handling of bearer and basic authentication schemes
  • Async token retrieval support through callbacks
  • Clean separation of concerns for authentication logic

The implementation correctly handles token encoding for basic auth using btoa() and proper formatting for bearer tokens.

packages/engine/src/client/types.gen.ts (5)

21-23: LGTM! Excellent documentation addition.

The JSDoc comment clearly explains the auto-execution behavior and provides guidance on when to use other execution options.


43-45: LGTM! Clear documentation for ERC4337 execution.

The JSDoc comment properly identifies this as the Smart Account execution option.


80-82: LGTM! Well-documented zkSync execution options.

The JSDoc comment clearly explains the zkSync native AA execution and its chain-specific limitations.


139-139: LGTM! Useful addition of optional label property.

The optional label property enhances account management by allowing human-readable identifiers alongside addresses.


176-176: LGTM! Consistent label property addition.

The optional label property in CreateAccountResponses maintains consistency with ListAccountsResponses.

packages/insight/src/client/core/auth.ts (1)

1-41: LGTM! Well-designed authentication module.

The auth module provides a clean, flexible interface for handling different authentication schemes:

  • Comprehensive Auth interface with sensible defaults
  • Proper token formatting for bearer and basic schemes
  • Correct use of btoa() for basic auth encoding
  • Support for both callback and direct token values

The implementation is type-safe and handles edge cases appropriately.

packages/insight/src/client/client/index.ts (1)

1-23: LGTM! Well-organized client API consolidation.

The index file provides a clean, comprehensive public API surface by re-exporting:

  • Core authentication and serialization types
  • Body serializer functions for different content types
  • Main client creation function and related types
  • Configuration and utility functions

The modular structure and .js import extensions are appropriate for ESM compatibility.

packages/nebula/src/client/client/index.ts (1)

1-23: LGTM! Consistent client architecture across packages.

The index file mirrors the structure of the insight package, providing the same comprehensive API surface. This consistency across packages (engine, insight, nebula) enhances maintainability and provides a uniform developer experience.

packages/insight/src/client/client/client.ts (4)

72-75: LGTM! Correct fetch assignment pattern.

The comment and fetch assignment pattern correctly prevents the "Illegal invocation" TypeError that occurs when fetch is called without proper context binding.


53-56: LGTM! Proper Content-Type header management.

Removing the Content-Type header for empty bodies prevents invalid requests and follows HTTP best practices.


88-99: LGTM! Proper handling of no-content responses.

The logic correctly handles 204 No Content responses and zero-length content, returning empty objects based on the response style preference.


173-189: LGTM! Comprehensive HTTP client interface.

The client provides all standard HTTP methods with consistent options handling and exposes useful utilities like buildUrl, configuration management, and interceptors.

packages/engine/src/client/client/index.ts (1)

1-22: Well-structured API consolidation.

The index file properly consolidates the client package's public API with logical grouping of exports. The separation between types and functions is clear and the imports are well-organized.

packages/insight/src/client/core/bodySerializer.ts (3)

17-23: Good type handling for FormData serialization.

The implementation correctly handles different value types - strings and Blobs are appended directly while other values are JSON-stringified. This ensures proper FormData compatibility.


58-63: Excellent BigInt handling for JSON compatibility.

The JSON serializer properly converts BigInt values to strings using a replacer function, preventing JSON serialization errors.


43-52: Proper array serialization strategy.

The array handling correctly serializes each element separately, which is the expected behavior for form data and query parameters.

packages/engine/src/client/client/client.ts (1)

72-75: Good handling of fetch assignment.

The non-null assertion is safe here since opts.fetch is guaranteed to have a value from the fallback chain on line 38. The comment explaining the assignment pattern is helpful.

packages/insight/src/client/core/pathSerializer.ts (1)

1-179: Well-implemented OpenAPI parameter serialization.

The implementation correctly handles all OpenAPI serialization styles with proper encoding and error handling. The code is well-structured and type-safe.

packages/nebula/src/client/client/types.ts (1)

1-223: Well-structured type definitions for the Nebula client.

The type definitions are comprehensive and properly documented, providing good TypeScript support for the HTTP client functionality.

packages/engine/src/client/client/types.ts (5)

1-6: LGTM: Clean import structure

The import statements are well-organized and follow proper TypeScript conventions with type-only imports.


8-8: LGTM: Clear response style enumeration

The ResponseStyle union type clearly defines the two supported response formats.


10-59: Good interface design with clear documentation

The Config interface is well-structured with comprehensive JSDoc documentation. The intentional next?: never property effectively prevents misuse in Next.js applications.


165-167: Well-designed client interface extension

The Client type properly extends the CoreClient while adding the interceptors functionality. The middleware typing is appropriate for request/response processing.


177-179: Excellent configuration factory pattern

The CreateClientConfig type and its documentation clearly explain the intended usage pattern for client initialization, particularly for Next.js applications.

packages/insight/src/client/types.gen.ts (5)

1221-1222: Appropriate type changes for blockchain numeric values

The conversion of transaction value fields (value, gas_price, max_fee_per_gas, etc.) and signature components (r, s, v) from number to string is correct. These values can exceed JavaScript's safe integer range and should be handled as strings to prevent precision loss.

Also applies to: 1226-1227, 1229-1231, 1237-1237, 1239-1239, 1485-1486, 1490-1491, 1493-1495, 1501-1501, 1503-1503, 1739-1740, 1744-1745, 1747-1749, 1755-1755, 1757-1757


1233-1233: Support for EIP-7702 authorization lists

The addition of authorization_list_json alongside access_list_json appears to add support for EIP-7702 (Set EOA account code). This is a backward-compatible addition as the field is optional.

Also applies to: 1325-1325, 1497-1497, 1751-1751, 3325-3325, 5446-5446


1921-1950: Well-structured price data enhancements

The addition of price_data objects provides comprehensive token pricing information including USD price, volume, market cap, supply metrics, and price changes. The structure is consistent across all token-related endpoints and the fields are appropriately optional.

Also applies to: 2011-2040, 2142-2171, 2232-2261, 2394-2423, 2484-2513, 2702-2731, 3193-3222


2336-2359: Enhanced filtering capabilities with ENS support

The new query parameters add valuable filtering options:

  • Block timestamp filters for time-based queries
  • Transfer type filtering (mint/transfer/burn/sale)
  • Contract address array filtering
  • Sort order control

The JSDoc annotations indicating ENS support are helpful.

Verify that the backend properly handles ENS resolution for these address parameters:

Does the thirdweb Insight API support ENS (Ethereum Name Service) resolution for address parameters in API endpoints?

Also applies to: 4197-4227


541-541: Verify block_number and block_timestamp type changes

The block_number and block_timestamp fields have been changed from string to number. While these values typically fit within JavaScript's safe integer range, please confirm this change is intentional and won't cause issues with very large block numbers on some chains.

#!/bin/bash
# Check current usage of block_number and block_timestamp
rg -A 2 -B 2 "block_number|block_timestamp" --type ts --type tsx | grep -E "(parseInt|Number\(|\.toString\(\)|as string)" | head -20

# Look for any comparisons or operations that might be affected
ast-grep --pattern 'parseInt($_.block_number)'
ast-grep --pattern '$_.block_number.toString()'

Also applies to: 543-543, 755-755, 757-757, 966-966, 968-968, 1213-1213, 1215-1215

packages/insight/src/client/sdk.gen.ts (6)

3-7: LGTM: Import source migration to local module

The import change from @hey-api/client-fetch to the local ./client/index.js module is consistent with the broader refactoring effort to move client functionality from external dependencies to local implementations.


9-133: LGTM: Consistent type renaming from singular to plural forms

The systematic renaming of all response and error types from singular (e.g., GetV1WebhooksResponse) to plural forms (e.g., GetV1WebhooksResponses) is consistent throughout the import statements. This aligns with the new client structure and naming conventions.


156-173: LGTM: Function implementation correctly updated with new type parameters

The getV1Webhooks function properly uses the new pluralized types GetV1WebhooksResponses and GetV1WebhooksErrors in its generic type parameters, maintaining type safety while adapting to the new client structure.


251-251: LGTM: Header spreading cleanup

The removal of optional chaining (...options?.headers...options.headers) is appropriate since the options parameter is required in this context (options: Options<...>), making the optional chaining unnecessary.


534-534: LGTM: Appropriate deprecation annotations

The addition of @deprecated JSDoc comments for the ERC-20, ERC-721, and ERC-1155 balance endpoints aligns with the API comments indicating these endpoints are being deprecated in favor of newer alternatives (/tokens and /nfts/balance).

Also applies to: 583-583, 609-609


821-821: LGTM: Consistent header spreading cleanup

Similar to line 251, the removal of optional chaining in the headers spreading is appropriate since options is a required parameter in this function context.

Comment on lines +1 to +98
import type { Auth, AuthToken } from "./auth.js";
import type {
BodySerializer,
QuerySerializer,
QuerySerializerOptions,
} from "./bodySerializer.js";

export interface Client<
RequestFn = never,
Config = unknown,
MethodFn = never,
BuildUrlFn = never,
> {
/**
* Returns the final request URL.
*/
buildUrl: BuildUrlFn;
connect: MethodFn;
delete: MethodFn;
get: MethodFn;
getConfig: () => Config;
head: MethodFn;
options: MethodFn;
patch: MethodFn;
post: MethodFn;
put: MethodFn;
request: RequestFn;
setConfig: (config: Config) => Config;
trace: MethodFn;
}

export interface Config {
/**
* Auth token or a function returning auth token. The resolved value will be
* added to the request payload as defined by its `security` array.
*/
auth?: ((auth: Auth) => Promise<AuthToken> | AuthToken) | AuthToken;
/**
* A function for serializing request body parameter. By default,
* {@link JSON.stringify()} will be used.
*/
bodySerializer?: BodySerializer | null;
/**
* An object containing any HTTP headers that you want to pre-populate your
* `Headers` object with.
*
* {@link https://developer.mozilla.org/docs/Web/API/Headers/Headers#init See more}
*/
headers?:
| RequestInit["headers"]
| Record<
string,
| string
| number
| boolean
| (string | number | boolean)[]
| null
| undefined
| unknown
>;
/**
* The request method.
*
* {@link https://developer.mozilla.org/docs/Web/API/fetch#method See more}
*/
method?:
| "CONNECT"
| "DELETE"
| "GET"
| "HEAD"
| "OPTIONS"
| "PATCH"
| "POST"
| "PUT"
| "TRACE";
/**
* A function for serializing request query parameters. By default, arrays
* will be exploded in form style, objects will be exploded in deepObject
* style, and reserved characters are percent-encoded.
*
* This method will have no effect if the native `paramsSerializer()` Axios
* API function is used.
*
* {@link https://swagger.io/docs/specification/serialization/#query View examples}
*/
querySerializer?: QuerySerializer | QuerySerializerOptions;
/**
* A function transforming response data before it's returned. This is useful
* for post-processing data, e.g. converting ISO strings into Date objects.
*/
responseTransformer?: (data: unknown) => Promise<unknown>;
/**
* A function validating response data. This is useful if you want to ensure
* the response conforms to the desired shape, so it can be safely passed to
* the transformers and returned to the user.
*/
responseValidator?: (data: unknown) => Promise<unknown>;
}
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

Consider consolidating duplicate code across packages.

This file is identical to packages/insight/src/client/core/types.ts. Consider extracting common types to a shared module to reduce duplication and improve maintainability.

You could create a shared core types package or move common types to a shared location that both packages can import from.

🤖 Prompt for AI Agents
In packages/nebula/src/client/core/types.ts lines 1 to 98, the types defined
here are identical to those in packages/insight/src/client/core/types.ts,
causing code duplication. To fix this, extract the common types into a new
shared module or package that both nebula and insight can import from. Then,
update both packages to import these types from the shared location instead of
duplicating the code.

Comment on lines +74 to +141
export const buildClientParams = (
args: ReadonlyArray<unknown>,
fields: FieldsConfig,
) => {
const params: Params = {
body: {},
headers: {},
path: {},
query: {},
};

const map = buildKeyMap(fields);

let config: FieldsConfig[number] | undefined;

for (const [index, arg] of args.entries()) {
if (fields[index]) {
config = fields[index];
}

if (!config) {
continue;
}

if ("in" in config) {
if (config.key) {
const field = map.get(config.key)!;
const name = field.map || config.key;
(params[field.in] as Record<string, unknown>)[name] = arg;
} else {
params.body = arg;
}
} else {
for (const [key, value] of Object.entries(arg ?? {})) {
const field = map.get(key);

if (field) {
const name = field.map || key;
(params[field.in] as Record<string, unknown>)[name] = value;
} else {
const extra = extraPrefixes.find(([prefix]) =>
key.startsWith(prefix),
);

if (extra) {
const [prefix, slot] = extra;
(params[slot] as Record<string, unknown>)[
key.slice(prefix.length)
] = value;
} else {
for (const [slot, allowed] of Object.entries(
config.allowExtra ?? {},
)) {
if (allowed) {
(params[slot as Slot] as Record<string, unknown>)[key] = value;
break;
}
}
}
}
}
}
}

stripEmptySlots(params);

return params;
};
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

Consider consolidating duplicate parameter building logic.

This buildClientParams function appears to be duplicated across multiple packages (insight, engine, nebula). Consider extracting this shared logic to a common utility to reduce code duplication and improve maintainability.

Based on the relevant code snippets, the engine package contains nearly identical implementation. Consider creating a shared utility package or moving this logic to a common location.

🤖 Prompt for AI Agents
In packages/insight/src/client/core/params.ts around lines 74 to 141, the
buildClientParams function duplicates logic found in other packages like engine
and nebula. To fix this, extract the buildClientParams function into a shared
utility module accessible by all packages. Then, replace the duplicated
implementations in each package with imports from this common utility, ensuring
consistent behavior and easier maintenance.

Comment on lines +100 to +102
const field = map.get(config.key)!;
const name = field.map || config.key;
(params[field.in] as Record<string, unknown>)[name] = arg;
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

Remove unsafe non-null assertion operator.

The non-null assertion operator could cause runtime errors if the key doesn't exist in the map. Add proper error handling or validation.

-        const field = map.get(config.key)!;
-        const name = field.map || config.key;
-        (params[field.in] as Record<string, unknown>)[name] = arg;
+        const field = map.get(config.key);
+        if (!field) {
+          throw new Error(`Invalid field key: ${config.key}`);
+        }
+        const name = field.map || config.key;
+        (params[field.in] as Record<string, unknown>)[name] = arg;
📝 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 field = map.get(config.key)!;
const name = field.map || config.key;
(params[field.in] as Record<string, unknown>)[name] = arg;
const field = map.get(config.key);
if (!field) {
throw new Error(`Invalid field key: ${config.key}`);
}
const name = field.map || config.key;
(params[field.in] as Record<string, unknown>)[name] = arg;
🤖 Prompt for AI Agents
In packages/insight/src/client/core/params.ts around lines 100 to 102, the code
uses a non-null assertion operator on map.get(config.key), which can cause
runtime errors if the key is not found. Replace the non-null assertion with a
check to verify that the key exists in the map before accessing it. If the key
is missing, handle the error appropriately, such as throwing an error or
returning early, to ensure safe access and prevent runtime exceptions.

}
}

finalError = finalError || ({} as string);
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 type casting issue with error fallback.

The code casts an empty object as a string, which is incorrect and could lead to runtime type errors.

Apply this diff to fix the type casting:

-    finalError = finalError || ({} as string);
+    finalError = finalError || "";

Alternatively, if you need to preserve object errors:

-    finalError = finalError || ({} as string);
+    finalError = finalError || {};
📝 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
finalError = finalError || ({} as string);
finalError = finalError || "";
🤖 Prompt for AI Agents
In packages/engine/src/client/client/client.ts at line 158, the code incorrectly
casts an empty object as a string for the error fallback, which can cause
runtime type errors. Replace the fallback with an empty string literal or a
valid string value instead of casting an object to a string to ensure type
safety and prevent errors.

Comment on lines +175 to +187
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}

if (cleanContent.startsWith("text/")) {
return "text";
}

return;
};
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 missing return value at the end of getParseAs function.

The function returns undefined at line 186, but this doesn't match the declared return type.

Apply this diff to provide a default return value:

-  return;
+  return "stream";
📝 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
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}
if (cleanContent.startsWith("text/")) {
return "text";
}
return;
};
["application/", "audio/", "image/", "video/"].some((type) =>
cleanContent.startsWith(type),
)
) {
return "blob";
}
if (cleanContent.startsWith("text/")) {
return "text";
}
return "stream";
};
🤖 Prompt for AI Agents
In packages/engine/src/client/client/utils.ts around lines 175 to 187, the
function getParseAs ends with an implicit undefined return which does not match
its declared return type. Fix this by explicitly returning a default value
consistent with the return type at the end of the function instead of returning
undefined.

Comment on lines +148 to +162
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}

const cleanContent = contentType.split(";")[0]?.trim();

if (!cleanContent) {
return;
}

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 inconsistent return type in getParseAs function.

The function can return undefined at line 160, but the return type excludes it.

Apply this diff to fix the return type:

-): Exclude<Config["parseAs"], "auto"> => {
+): Exclude<Config["parseAs"], "auto"> | undefined => {
📝 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
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}
const cleanContent = contentType.split(";")[0]?.trim();
if (!cleanContent) {
return;
}
export const getParseAs = (
contentType: string | null,
): Exclude<Config["parseAs"], "auto"> | undefined => {
if (!contentType) {
// If no Content-Type header is provided, the best we can do is return the raw response body,
// which is effectively the same as the 'stream' option.
return "stream";
}
const cleanContent = contentType.split(";")[0]?.trim();
if (!cleanContent) {
return;
}
// …rest of function…
🤖 Prompt for AI Agents
In packages/engine/src/client/client/utils.ts around lines 148 to 162, the
getParseAs function currently returns undefined when cleanContent is falsy, but
the declared return type excludes undefined. To fix this, update the function to
always return a valid value matching the declared return type by replacing the
undefined return with a default valid return such as "stream" or another
appropriate value consistent with the return type.

Comment on lines +84 to +127
export type RequestResult<
TData = unknown,
TError = unknown,
ThrowOnError extends boolean = boolean,
TResponseStyle extends ResponseStyle = "fields",
> = ThrowOnError extends true
? Promise<
TResponseStyle extends "data"
? TData extends Record<string, unknown>
? TData[keyof TData]
: TData
: {
data: TData extends Record<string, unknown>
? TData[keyof TData]
: TData;
request: Request;
response: Response;
}
>
: Promise<
TResponseStyle extends "data"
?
| (TData extends Record<string, unknown>
? TData[keyof TData]
: TData)
| undefined
: (
| {
data: TData extends Record<string, unknown>
? TData[keyof TData]
: TData;
error: undefined;
}
| {
data: undefined;
error: TError extends Record<string, unknown>
? TError[keyof TError]
: TError;
}
) & {
request: Request;
response: Response;
}
>;
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

Complex conditional type may have unpredictable data extraction

The RequestResult type contains potentially problematic data extraction logic:

TData extends Record<string, unknown> ? TData[keyof TData] : TData

This pattern extracts a value using keyof TData, but if TData has multiple properties, the result is unpredictable since keyof TData returns a union of all keys.

Consider these alternatives:

  1. If you need the first property value, use a more explicit extraction method
  2. If you need all properties, return the entire object
  3. Add constraints to ensure TData has only one property
- TData extends Record<string, unknown>
-   ? TData[keyof TData]
-   : TData
+ TData extends Record<string, unknown>
+   ? TData extends Record<infer K, infer V>
+     ? K extends string
+       ? V
+       : TData
+     : TData
+   : TData
🤖 Prompt for AI Agents
In packages/engine/src/client/client/types.ts between lines 84 and 127, the
RequestResult type uses TData[keyof TData] to extract a value, which is
unpredictable if TData has multiple properties because keyof TData is a union of
keys. To fix this, clarify the intent by either restricting TData to a
single-property object, explicitly extracting the first property value using a
helper type or utility, or returning the entire TData object instead of a single
property value. Adjust the conditional type accordingly to ensure consistent and
predictable data extraction.

@@ -536,10 +537,10 @@ export type GetV1EventsResponses = {
*/
200: {
data?: Array<{
chain_id: number;
block_number: string;
chain_id: string;
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

❓ Verification inconclusive

Breaking change: chain_id type changed from number to string

The chain_id field has been changed from number to string across multiple response types. This is a breaking change that could impact existing consumers expecting numeric chain IDs.

Please verify if this type change is intentional and consistent with the backend API implementation:

Also applies to: 754-754, 965-965, 1212-1212, 1304-1304, 1336-1336, 1425-1425, 1476-1476, 1730-1730, 3304-3304, 3336-3336, 5425-5425


🏁 Script executed:

#!/bin/bash
# Check if there are any usages of chain_id that might be affected by this type change

# Search for chain_id usage in the codebase
rg -A 3 -B 3 "chain_id" --type ts --type tsx | grep -E "(chain_id.*:.*number|\.chain_id|chain_id\])" | head -20

# Check if there are any type assertions or comparisons that might break
ast-grep --pattern 'chain_id === $_' 
ast-grep --pattern 'chain_id == $_'
ast-grep --pattern '$_.chain_id as number'

Length of output: 261


Breaking change: chain_id type changed from number to string

The chain_id field has been changed from number to string across multiple response types. This is a breaking change that could impact existing consumers expecting numeric chain IDs.

Please verify if this type change is intentional and consistent with the backend API implementation:

#!/bin/bash
# Check if there are any usages of chain_id that might be affected by this type change

# Search for chain_id usage in the codebase
rg -A 3 -B 3 "chain_id" --type ts --type tsx | grep -E "(chain_id.*:.*number|\.chain_id|chain_id\])" | head -20

# Check if there are any type assertions or comparisons that might break
ast-grep --pattern 'chain_id === $_' 
ast-grep --pattern 'chain_id == $_'
ast-grep --pattern '$_.chain_id as number'

Also applies to: 754-754, 965-965, 1212-1212, 1304-1304, 1336-1336, 1425-1425, 1476-1476, 1730-1730, 3304-3304, 3336-3336, 5425-5425

🤖 Prompt for AI Agents
In packages/insight/src/client/types.gen.ts at line 540 and similarly at lines
754, 965, 1212, 1304, 1336, 1425, 1476, 1730, 3304, 3336, and 5425, the type of
the chain_id field has been changed from number to string. Verify this change is
intentional by confirming it matches the backend API specification. Then, update
all related code usages, type assertions, and comparisons involving chain_id to
handle it as a string instead of a number to prevent type errors and runtime
issues.

<!--

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

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

## Notes for the reviewer

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

## How to test

Unit tests, playground, etc.

-->
This PR updates the version of the `@hey-api/openapi-ts` package to `0.76.0` in the `@thirdweb-dev/engine`, `@thirdweb-dev/insight` and `@thirdweb-dev/nebula` packages. Also, it adds a check in the `chain_id` in the `thirdweb` package in case it gets returned as a string and not as a number.

<!-- start pr-codex -->

---

## PR-Codex overview
This PR focuses on updating various packages with minor version changes, enhancing type definitions, and improving request handling in the client libraries. It also includes adjustments to configuration files and serialization methods.

### Detailed summary
- Updated `limit` in `.size-limit.json` from `65 kB` to `68 kB`.
- Updated dependencies in `package.json` files for `@hey-api/openapi-ts` to `0.76.0`.
- Added type definitions for `Auth` and `Config` in client libraries.
- Enhanced request handling in `createClient` function.
- Improved serialization methods in `bodySerializer`.
- Updated response interfaces for various API methods to reflect new response types.

> The following files were skipped due to too many changes: `packages/engine/src/client/client/types.ts`, `packages/nebula/src/client/client/types.ts`, `packages/insight/src/client/client/types.ts`, `packages/nebula/src/client/client/utils.ts`, `packages/insight/src/client/client/utils.ts`, `packages/engine/src/client/client/utils.ts`, `packages/insight/src/client/sdk.gen.ts`, `pnpm-lock.yaml`, `packages/insight/src/client/types.gen.ts`

> ✨ 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 fully configurable HTTP client modules with request/response interceptors, authentication, serialization, and flexible response parsing across multiple packages.
  - Added centralized utility modules for body and query serialization, URL construction, and middleware/interceptor management.
  - Expanded comprehensive type definitions for client configuration, request options, response handling, and parameter mapping.

- **Enhancements**
  - Improved API type safety with extended filtering options, detailed address documentation, and enriched price data in responses.
  - Added support for new response styles and configurable error handling.
  - Updated default API endpoints and enhanced type documentation.

- **Bug Fixes**
  - Ensured consistent numeric types for fields like `chain_id`, `block_number`, and transaction values across APIs.
  - Fixed transaction history mapping to guarantee numeric `chainId`.

- **Chores**
  - Upgraded dependencies including "hey-api" and related packages; removed deprecated fields and cleaned type definitions.
  - Updated TypeScript configurations to include iterable DOM interfaces for better typings.

- **Style**
  - Standardized code formatting and indentation in configuration files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🔭 Outside diff range comments (1)
packages/nebula/src/client/client/types.ts (1)

1-223: Ensure consistent fixes across all packages.

The type definitions are nearly identical to the engine and insight packages. When fixing the RequestResult type issue, ensure the same fix is applied consistently across all three packages (engine, insight, nebula) to maintain uniformity.

♻️ Duplicate comments (5)
packages/insight/src/client/client/client.ts (1)

142-171: Error handling needs type improvements.

The error handling logic has the same type safety concerns identified in previous reviews: casting objects as strings and inconsistent error type handling.

packages/engine/src/client/client/client.ts (1)

158-158: Fix type casting issue with error fallback.

The same type casting issue exists here as flagged in previous reviews - casting empty object as string.

packages/engine/src/client/client/utils.ts (1)

148-187: Fix missing return type to include undefined.

The function can return undefined at lines 160 and 186, but the return type doesn't include undefined.

packages/insight/src/client/client/utils.ts (1)

148-187: Fix missing return type to include undefined.

The function can return undefined at lines 160 and 186, but the return type doesn't include undefined.

packages/engine/src/client/client/types.ts (1)

84-127: Complex conditional type may have unpredictable data extraction.

The TData[keyof TData] pattern used for data extraction can be unpredictable when TData has multiple properties, as previously identified.

🧹 Nitpick comments (3)
packages/engine/src/client/core/pathSerializer.ts (1)

120-124: Improve error message and type handling.

The error handling for nested objects could be more informative and the type checking more robust.

Consider this improvement:

  if (typeof value === "object") {
    throw new Error(
-      "Deeply-nested arrays/objects aren't supported. Provide your own `querySerializer()` to handle these.",
+      `Deeply-nested arrays/objects aren't supported for parameter "${name}". Provide your own querySerializer() to handle these.`,
    );
  }
packages/engine/src/client/client/utils.ts (1)

189-223: Clarify early return behavior in authentication loop.

The function returns early at line 221 after processing the first authentication token, which means subsequent security items in the array won't be processed. If this "first match wins" behavior is intentional, consider adding a comment to clarify this design decision.

  for (const auth of security) {
    const token = await getAuthToken(auth, options.auth);

    if (!token) {
      continue;
    }

    const name = auth.name ?? "Authorization";

    switch (auth.in) {
      case "query":
        if (!options.query) {
          options.query = {};
        }
        options.query[name] = token;
        break;
      case "cookie":
        options.headers.append("Cookie", `${name}=${token}`);
        break;
      case "header":
      default:
        options.headers.set(name, token);
        break;
    }

+   // Process only the first valid authentication token
    return;
  }
packages/insight/src/client/client/utils.ts (1)

189-222: Clarify early return behavior in authentication loop.

The function returns early at line 220 after processing the first authentication token, preventing subsequent security items from being processed. Consider documenting this "first match wins" behavior if intentional.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 047043d and 74e1f14.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (49)
  • .changeset/little-items-allow.md (1 hunks)
  • packages/engine/package.json (1 hunks)
  • packages/engine/src/client/client.gen.ts (1 hunks)
  • packages/engine/src/client/client/client.ts (1 hunks)
  • packages/engine/src/client/client/index.ts (1 hunks)
  • packages/engine/src/client/client/types.ts (1 hunks)
  • packages/engine/src/client/client/utils.ts (1 hunks)
  • packages/engine/src/client/core/auth.ts (1 hunks)
  • packages/engine/src/client/core/bodySerializer.ts (1 hunks)
  • packages/engine/src/client/core/params.ts (1 hunks)
  • packages/engine/src/client/core/pathSerializer.ts (1 hunks)
  • packages/engine/src/client/core/types.ts (1 hunks)
  • packages/engine/src/client/sdk.gen.ts (14 hunks)
  • packages/engine/src/client/types.gen.ts (5 hunks)
  • packages/engine/src/configure.ts (1 hunks)
  • packages/engine/tsconfig.base.json (1 hunks)
  • packages/insight/package.json (1 hunks)
  • packages/insight/src/client/client.gen.ts (1 hunks)
  • packages/insight/src/client/client/client.ts (1 hunks)
  • packages/insight/src/client/client/index.ts (1 hunks)
  • packages/insight/src/client/client/types.ts (1 hunks)
  • packages/insight/src/client/client/utils.ts (1 hunks)
  • packages/insight/src/client/core/auth.ts (1 hunks)
  • packages/insight/src/client/core/bodySerializer.ts (1 hunks)
  • packages/insight/src/client/core/params.ts (1 hunks)
  • packages/insight/src/client/core/pathSerializer.ts (1 hunks)
  • packages/insight/src/client/core/types.ts (1 hunks)
  • packages/insight/src/client/sdk.gen.ts (44 hunks)
  • packages/insight/src/client/types.gen.ts (70 hunks)
  • packages/insight/src/configure.ts (1 hunks)
  • packages/insight/tsconfig.base.json (1 hunks)
  • packages/nebula/openapi-ts.config.ts (1 hunks)
  • packages/nebula/package.json (1 hunks)
  • packages/nebula/src/client/client.gen.ts (2 hunks)
  • packages/nebula/src/client/client/client.ts (1 hunks)
  • packages/nebula/src/client/client/index.ts (1 hunks)
  • packages/nebula/src/client/client/types.ts (1 hunks)
  • packages/nebula/src/client/client/utils.ts (1 hunks)
  • packages/nebula/src/client/core/auth.ts (1 hunks)
  • packages/nebula/src/client/core/bodySerializer.ts (1 hunks)
  • packages/nebula/src/client/core/params.ts (1 hunks)
  • packages/nebula/src/client/core/pathSerializer.ts (1 hunks)
  • packages/nebula/src/client/core/types.ts (1 hunks)
  • packages/nebula/src/client/sdk.gen.ts (1 hunks)
  • packages/nebula/src/client/types.gen.ts (3 hunks)
  • packages/nebula/src/configure.ts (1 hunks)
  • packages/nebula/tsconfig.base.json (1 hunks)
  • packages/thirdweb/.size-limit.json (1 hunks)
  • packages/thirdweb/src/transaction/transaction-store.ts (1 hunks)
✅ Files skipped from review due to trivial changes (3)
  • packages/thirdweb/.size-limit.json
  • packages/engine/src/client/core/auth.ts
  • packages/nebula/src/client/core/auth.ts
🚧 Files skipped from review as they are similar to previous changes (36)
  • packages/engine/src/client/client.gen.ts
  • packages/engine/src/configure.ts
  • packages/nebula/src/configure.ts
  • packages/insight/src/configure.ts
  • packages/insight/src/client/client.gen.ts
  • packages/nebula/src/client/sdk.gen.ts
  • packages/engine/package.json
  • packages/nebula/package.json
  • packages/insight/package.json
  • packages/insight/tsconfig.base.json
  • packages/nebula/openapi-ts.config.ts
  • packages/nebula/src/client/client.gen.ts
  • packages/thirdweb/src/transaction/transaction-store.ts
  • .changeset/little-items-allow.md
  • packages/engine/tsconfig.base.json
  • packages/nebula/tsconfig.base.json
  • packages/insight/src/client/core/auth.ts
  • packages/nebula/src/client/client/index.ts
  • packages/insight/src/client/core/types.ts
  • packages/engine/src/client/types.gen.ts
  • packages/engine/src/client/sdk.gen.ts
  • packages/nebula/src/client/types.gen.ts
  • packages/nebula/src/client/core/types.ts
  • packages/insight/src/client/client/index.ts
  • packages/nebula/src/client/core/params.ts
  • packages/engine/src/client/client/index.ts
  • packages/engine/src/client/core/params.ts
  • packages/insight/src/client/core/params.ts
  • packages/nebula/src/client/core/bodySerializer.ts
  • packages/insight/src/client/core/bodySerializer.ts
  • packages/engine/src/client/core/bodySerializer.ts
  • packages/insight/src/client/core/pathSerializer.ts
  • packages/nebula/src/client/core/pathSerializer.ts
  • packages/nebula/src/client/client/utils.ts
  • packages/insight/src/client/types.gen.ts
  • packages/insight/src/client/sdk.gen.ts
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.@(ts|tsx)`: Accept a typed 'props' object and export a named function (e.g...

**/*.@(ts|tsx): Accept a typed 'props' object and export a named function (e.g., export function MyComponent()).
Combine class names via 'cn', expose 'className' prop if useful.
Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Local state or effects live inside; data fetching happens in hooks.
Merge class names with 'cn' from '@/lib/utils' to keep conditional logic readable.
Stick to design-tokens: background ('bg-card'), borders ('border-border'), muted text ('text-muted-foreground') etc.
Use the 'container' class with a 'max-w-7xl' cap for page width consistency.
Spacing utilities ('px-', 'py-', 'gap-*') are preferred over custom margins.
Responsive helpers follow mobile-first ('max-sm', 'md', 'lg', 'xl').
Never hard-code colors – always go through Tailwind variables.
Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Prefix files with 'import "server-only";' so they never end up in the client bundle (for server-only code).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/dashboard.mdc)

List of files the instruction was applied to:

  • packages/engine/src/client/core/types.ts
  • packages/insight/src/client/client/client.ts
  • packages/engine/src/client/client/client.ts
  • packages/nebula/src/client/client/client.ts
  • packages/engine/src/client/client/utils.ts
  • packages/engine/src/client/core/pathSerializer.ts
  • packages/insight/src/client/client/utils.ts
  • packages/insight/src/client/client/types.ts
  • packages/engine/src/client/client/types.ts
  • packages/nebula/src/client/client/types.ts
🧬 Code Graph Analysis (2)
packages/engine/src/client/core/types.ts (2)
packages/engine/src/client/core/auth.ts (2)
  • Auth (3-18)
  • AuthToken (1-1)
packages/engine/src/client/core/bodySerializer.ts (3)
  • BodySerializer (9-9)
  • QuerySerializer (7-7)
  • QuerySerializerOptions (11-15)
packages/engine/src/client/client/utils.ts (5)
packages/engine/src/client/core/pathSerializer.ts (5)
  • ArrayStyle (18-18)
  • ArraySeparatorStyle (19-19)
  • serializeArrayParam (67-109)
  • serializeObjectParam (129-179)
  • serializePrimitiveParam (111-127)
packages/engine/src/client/client/index.ts (9)
  • QuerySerializerOptions (2-2)
  • Config (13-13)
  • RequestOptions (17-17)
  • Client (11-11)
  • mergeHeaders (22-22)
  • Options (15-15)
  • createConfig (22-22)
  • ClientOptions (12-12)
  • jsonBodySerializer (5-5)
packages/engine/src/client/core/bodySerializer.ts (3)
  • QuerySerializerOptions (11-15)
  • QuerySerializer (7-7)
  • jsonBodySerializer (58-63)
packages/engine/src/client/client/types.ts (5)
  • Config (10-59)
  • RequestOptions (61-82)
  • Client (165-167)
  • Options (191-199)
  • ClientOptions (129-133)
packages/engine/src/client/core/auth.ts (1)
  • getAuthToken (20-40)
⏰ Context from checks skipped due to timeout of 90000ms (8)
  • GitHub Check: Lint Packages
  • GitHub Check: Size
  • GitHub Check: Unit Tests
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: Build Packages
  • GitHub Check: Analyze (javascript)
🔇 Additional comments (5)
packages/engine/src/client/core/types.ts (1)

1-98: Well-structured type definitions.

The interface design follows TypeScript best practices with appropriate use of generics, comprehensive configuration options, and clear documentation. The separation of concerns between Client and Config interfaces is excellent.

packages/engine/src/client/client/utils.ts (1)

1-418: Well-structured HTTP client utilities implementation.

The utility module provides comprehensive functionality for URL construction, serialization, authentication, and interceptor management. The implementation follows OpenAPI standards and handles edge cases appropriately.

packages/insight/src/client/client/utils.ts (1)

205-218: Good simplification of switch statement.

The switch statement correctly handles the default case for headers, which is cleaner than the engine version.

packages/insight/src/client/client/types.ts (1)

1-223: Comprehensive and well-structured type definitions.

The type system provides excellent flexibility for response styles, error handling, and request configuration. The conditional types appropriately handle different client behavior modes.

packages/engine/src/client/client/types.ts (1)

1-83: Well-designed client type definitions.

The configuration, request options, and utility types are comprehensive and well-documented, providing excellent type safety for the client implementation.

Also applies to: 128-223

}
}

finalError = finalError || ({} as string);
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

Same type casting issue as other client implementations.

This implementation has the identical type safety problem as the engine and insight clients - incorrectly casting an empty object as a string for error fallback.

Apply the same fix as suggested for the other client implementations:

-    finalError = finalError || ({} as string);
+    finalError = finalError || "";
📝 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
finalError = finalError || ({} as string);
- finalError = finalError || ({} as string);
+ finalError = finalError || "";
🤖 Prompt for AI Agents
In packages/nebula/src/client/client/client.ts at line 158, the code incorrectly
casts an empty object as a string for the error fallback, causing type safety
issues. Replace the cast with a proper fallback value of an empty string or a
string message instead of using an empty object cast to string. This aligns with
the fix applied in other client implementations to ensure type safety.

Comment on lines +146 to +152
Object.entries(value).forEach(([key, v]) => {
values = [
...values,
key,
allowReserved ? (v as string) : encodeURIComponent(v as 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

Add type safety for object value serialization.

The code uses type assertions without validation, which could cause runtime errors if object values aren't strings.

Consider adding type validation:

      values = [
        ...values,
        key,
-        allowReserved ? (v as string) : encodeURIComponent(v as string),
+        allowReserved ? String(v) : encodeURIComponent(String(v)),
      ];
📝 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
Object.entries(value).forEach(([key, v]) => {
values = [
...values,
key,
allowReserved ? (v as string) : encodeURIComponent(v as string),
];
});
Object.entries(value).forEach(([key, v]) => {
values = [
...values,
key,
allowReserved ? String(v) : encodeURIComponent(String(v)),
];
});
🤖 Prompt for AI Agents
In packages/engine/src/client/core/pathSerializer.ts around lines 146 to 152,
the code assumes object values are strings using type assertions without
validation, risking runtime errors. Add a type check to verify each value is a
string before processing; if not, handle the case appropriately (e.g., skip,
convert, or throw an error) to ensure type safety during serialization.

}) => {
if (!explode) {
const joinedValues = (
allowReserved ? value : value.map((v) => encodeURIComponent(v as 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

Add type validation for array serialization.

The code uses type assertion v as string without validating that the value is actually a string. This could cause runtime errors if the array contains non-string values.

Consider adding type validation:

-    ).join(separatorArrayNoExplode(style));
+    ).map(v => typeof v === 'string' ? v : String(v))
+    .join(separatorArrayNoExplode(style));

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

🤖 Prompt for AI Agents
In packages/engine/src/client/core/pathSerializer.ts at line 78, the code uses a
type assertion to treat each element as a string without validating the type,
which may cause runtime errors if non-string values are present. Modify the map
function to first check if each element is a string before encoding; if an
element is not a string, handle it appropriately, such as by converting it to a
string or skipping it, to ensure safe serialization.

Comment on lines +84 to +127
export type RequestResult<
TData = unknown,
TError = unknown,
ThrowOnError extends boolean = boolean,
TResponseStyle extends ResponseStyle = "fields",
> = ThrowOnError extends true
? Promise<
TResponseStyle extends "data"
? TData extends Record<string, unknown>
? TData[keyof TData]
: TData
: {
data: TData extends Record<string, unknown>
? TData[keyof TData]
: TData;
request: Request;
response: Response;
}
>
: Promise<
TResponseStyle extends "data"
?
| (TData extends Record<string, unknown>
? TData[keyof TData]
: TData)
| undefined
: (
| {
data: TData extends Record<string, unknown>
? TData[keyof TData]
: TData;
error: undefined;
}
| {
data: undefined;
error: TError extends Record<string, unknown>
? TError[keyof TError]
: TError;
}
) & {
request: Request;
response: Response;
}
>;
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

Identical data extraction issue as engine package.

The RequestResult type uses the same TData[keyof TData] pattern that can be unpredictable for multi-property objects, identical to the issue in the engine package.

Consider applying the same fix suggested for the engine package to ensure consistent behavior across packages.

🤖 Prompt for AI Agents
In packages/nebula/src/client/client/types.ts between lines 84 and 127, the
RequestResult type extracts data using TData[keyof TData], which can cause
unpredictable results for objects with multiple properties. To fix this, revise
the type to avoid indexing TData by keyof TData and instead return TData
directly or apply a safer extraction method consistent with the fix used in the
engine package, ensuring consistent and predictable data typing across packages.

@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 25, 2025 14:52 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui June 25, 2025 14:52 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 25, 2025 14:52 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb-www June 25, 2025 14:52 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula June 25, 2025 14:52 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb_playground June 25, 2025 14:55 Inactive
@vercel vercel bot temporarily deployed to Preview – docs-v2 June 25, 2025 14:55 Inactive
@vercel vercel bot temporarily deployed to Preview – thirdweb-www June 25, 2025 14:55 Inactive
@vercel vercel bot temporarily deployed to Preview – nebula June 25, 2025 14:55 Inactive
@vercel vercel bot temporarily deployed to Preview – wallet-ui June 25, 2025 14:55 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: 0

♻️ Duplicate comments (3)
packages/nebula/src/client/client/utils.ts (3)

86-88: Fix label style encoding to exclude the prefix from URL encoding.

The dot prefix for label style should not be URL-encoded.


148-187: Fix return type inconsistency in getParseAs function.

The function returns undefined on line 160 and 186, but the return type doesn't include it.


338-344: Fix potential bug with interceptor index 0.

The check this._fns[id] will fail when id is 0 and could return incorrect results.

🧹 Nitpick comments (10)
packages/nebula/src/client/client/utils.ts (10)

47-51: Add type safety for path parameter validation.

The function doesn't validate that the path parameter values are serializable types before processing them.

   const value = path[name];

   if (value === undefined || value === null) {
     continue;
   }
+
+  // Validate that the value is a serializable type
+  if (typeof value !== 'string' && typeof value !== 'number' && typeof value !== 'boolean' && !Array.isArray(value) && typeof value !== 'object') {
+    throw new Error(`Invalid path parameter type for "${name}": ${typeof value}`);
+  }

78-82: Add type validation for primitive parameter casting.

The code casts value to string without validation, which could lead to runtime errors.

   url = url.replace(
     match,
     `;${serializePrimitiveParam({
       name,
-      value: value as string,
+      value: String(value),
     })}`,
   );

86-89: Improve type safety for value casting.

The casting to string should be safer by using String() conversion.

   const replaceValue = encodeURIComponent(
-    style === "label" ? `.${value as string}` : (value as string),
+    String(value)
   );
-  url = url.replace(match, replaceValue);
+  url = url.replace(match, style === "label" ? `.${replaceValue}` : replaceValue);

131-137: Add type validation for primitive value casting.

Similar to other cases, the casting to string should be safer.

   const serializedPrimitive = serializePrimitiveParam({
     allowReserved,
     name,
-    value: value as string,
+    value: String(value),
   });

206-211: Validate query object mutation safety.

The function mutates the options.query object without ensuring it's safe to modify.

   case "query":
     if (!options.query) {
       options.query = {};
+    } else if (typeof options.query !== 'object') {
+      throw new Error('Query parameter must be an object');
     }
     options.query[name] = token;
     break;

292-295: Add type safety for array value iteration.

The casting of array values to string could be unsafe if the array contains non-string values.

   } else if (Array.isArray(value)) {
     for (const v of value) {
-      mergedHeaders.append(key, v as string);
+      mergedHeaders.append(key, String(v));
     }

298-301: Improve type safety for header value casting.

The casting to string should be safer and more explicit about object handling.

   mergedHeaders.set(
     key,
-    typeof value === "object" ? JSON.stringify(value) : (value as string),
+    typeof value === "object" ? JSON.stringify(value) : String(value),
   );

344-347: Simplify exists method logic.

The exists method can be simplified by using the result from getInterceptorIndex directly.

   exists(id: number | Interceptor) {
     const index = this.getInterceptorIndex(id);
-    return !!this._fns[index];
+    return index !== -1 && this._fns[index] !== null;
   }

349-354: Add bounds checking for array access.

The method should validate the index before accessing the array.

   eject(id: number | Interceptor) {
     const index = this.getInterceptorIndex(id);
-    if (this._fns[index]) {
+    if (index !== -1 && this._fns[index]) {
       this._fns[index] = null;
     }
   }

356-364: Add bounds checking for array access.

Similar to the eject method, this should validate the index.

   update(id: number | Interceptor, fn: Interceptor) {
     const index = this.getInterceptorIndex(id);
-    if (this._fns[index]) {
+    if (index !== -1 && this._fns[index]) {
       this._fns[index] = fn;
       return id;
     } else {
       return false;
     }
   }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 58be2d6 and a036969.

📒 Files selected for processing (4)
  • packages/nebula/src/client/client/client.ts (1 hunks)
  • packages/nebula/src/client/client/index.ts (1 hunks)
  • packages/nebula/src/client/client/types.ts (1 hunks)
  • packages/nebula/src/client/client/utils.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/nebula/src/client/client/index.ts
  • packages/nebula/src/client/client/client.ts
  • packages/nebula/src/client/client/types.ts
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.@(ts|tsx)`: Accept a typed 'props' object and export a named function (e.g...

**/*.@(ts|tsx): Accept a typed 'props' object and export a named function (e.g., export function MyComponent()).
Combine class names via 'cn', expose 'className' prop if useful.
Reuse core UI primitives; avoid re-implementing buttons, cards, modals.
Local state or effects live inside; data fetching happens in hooks.
Merge class names with 'cn' from '@/lib/utils' to keep conditional logic readable.
Stick to design-tokens: background ('bg-card'), borders ('border-border'), muted text ('text-muted-foreground') etc.
Use the 'container' class with a 'max-w-7xl' cap for page width consistency.
Spacing utilities ('px-', 'py-', 'gap-*') are preferred over custom margins.
Responsive helpers follow mobile-first ('max-sm', 'md', 'lg', 'xl').
Never hard-code colors – always go through Tailwind variables.
Tailwind CSS is the styling system – avoid inline styles or CSS modules.
Prefix files with 'import "server-only";' so they never end up in the client bundle (for server-only code).

📄 Source: CodeRabbit Inference Engine (.cursor/rules/dashboard.mdc)

List of files the instruction was applied to:

  • packages/nebula/src/client/client/utils.ts
⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: Analyze (javascript)
  • GitHub Check: E2E Tests (pnpm, esbuild)
  • GitHub Check: E2E Tests (pnpm, vite)
  • GitHub Check: E2E Tests (pnpm, webpack)
  • GitHub Check: Size
  • GitHub Check: Lint Packages

@joaquim-verges joaquim-verges merged commit 1387337 into main Jun 25, 2025
27 of 29 checks passed
@joaquim-verges joaquim-verges deleted the pr/update-nebula-package-responses branch June 25, 2025 19:30
@joaquim-verges joaquim-verges mentioned this pull request Jun 25, 2025
@coderabbitai coderabbitai bot mentioned this pull request Jun 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
packages SDK Involves changes to the thirdweb SDK
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants