Skip to content

Conversation

dstaley
Copy link
Member

@dstaley dstaley commented Sep 22, 2025

Description

This PR adds Web3 APIs to our experimental Signal implementation.

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • New Features

    • Experimental Web3 authentication for sign-in and sign-up (MetaMask, Coinbase Wallet, Base, OKX) including nonce handling, signature prompts, and a retry for Coinbase user-rejection.
    • Sign-up can optionally collect a Web3 wallet.
    • React state exposes web3 methods on sign-in/sign-up tickets.
  • Chores

    • Bumped minor versions of @clerk/clerk-js, @clerk/clerk-react, and @clerk/types.

Copy link

changeset-bot bot commented Sep 22, 2025

🦋 Changeset detected

Latest commit: 308b84a

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

This PR includes changesets to release 22 packages
Name Type
@clerk/clerk-js Minor
@clerk/clerk-react Minor
@clerk/types Minor
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch
@clerk/elements Patch
@clerk/nextjs Patch
@clerk/react-router Patch
@clerk/remix Patch
@clerk/tanstack-react-start Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nuxt Patch
@clerk/shared Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/vue 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 Sep 22, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
clerk-js-sandbox Ready Ready Preview Comment Sep 22, 2025 9:03pm

@dstaley dstaley marked this pull request as ready for review September 22, 2025 20:41
Copy link
Contributor

coderabbitai bot commented Sep 22, 2025

Walkthrough

Adds Web3 authentication flows to sign-in and sign-up, new public methods and types, React state proxies exposing web3 on ticket objects, an updated changeset, provider-specific identifier/signature handling, and a single-retry for Coinbase Wallet user-rejection (code 4001).

Changes

Cohort / File(s) Summary
Versioning & Changelog
\.changeset/quick-ghosts-fail.md
Bumps minor versions for @clerk/clerk-js, @clerk/clerk-react, @clerk/types; adds experimental entry: “[Experimental] Add Signal support for Web3 APIs”.
Clerk JS: Web3 Auth Flows
packages/clerk-js/src/core/resources/SignIn.ts, packages/clerk-js/src/core/resources/SignUp.ts
Adds web3(params) methods to SignInFuture and SignUpFuture. Implements provider-derived identifier lookup, nonce/message retrieval, signature generation, error handling, Coinbase Wallet retry on code 4001, and submission of verification attempts. SignUpFuture.create now optionally forwards web3Wallet.
React State Proxy Exposure
packages/react/src/stateProxy.ts
Exposes web3 on signIn.ticket and signUp.ticket via gateMethod, linking to underlying resource methods.
Types: Web3 Params & Methods
packages/types/src/signInFuture.ts, packages/types/src/signUpFuture.ts
Adds SignInFutureWeb3Params, SignUpFutureWeb3Params, and web3(...) to both resource interfaces; imports Web3Strategy. SignUpFutureCreateParams gains optional web3Wallet.
Bundle thresholds
packages/clerk-js/bundlewatch.config.json
Adjusts bundle size thresholds for clerk.browser.js and clerk.legacy.browser.js (increased limits).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant SI as SignInFuture
  participant P as Web3 Provider
  participant B as Clerk Backend

  C->>SI: web3({ strategy })
  SI->>SI: Resolve provider + identifier helper
  SI->>P: Request identifier (e.g., address)
  P-->>SI: identifier
  SI->>B: Create sign-in + prepare first factor
  B-->>SI: nonce/message + factor info
  SI->>P: Request signature over nonce/message
  alt Signature success
    P-->>SI: signature
  else Coinbase user rejection (code 4001) [retry once]
    SI->>P: Retry signature
    P-->>SI: signature or error
  end
  SI->>B: Attempt first-factor with signature
  B-->>SI: Result
  SI-->>C: { error } or success state
Loading
sequenceDiagram
  autonumber
  participant C as Client
  participant SU as SignUpFuture
  participant P as Web3 Provider
  participant B as Clerk Backend

  C->>SU: web3({ strategy, ... })
  SU->>SU: Resolve provider + identifier helper
  SU->>P: Request identifier (e.g., address)
  P-->>SU: identifier
  SU->>B: Create sign-up wallet (+optional web3Wallet)
  B-->>SU: Verification prepared (message/nonce)
  SU->>P: Request signature over message
  alt Signature success
    P-->>SU: signature
  else Coinbase user rejection (code 4001) [retry once]
    SU->>P: Retry signature
    P-->>SU: signature or error
  end
  SU->>B: attempt_verification(strategy, signature)
  B-->>SU: Result
  SU-->>C: { error } or success state
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

A nibble of nonce, a whisper to chain,
I twitch my ears at signatures plain.
Hop-hop through wallets, swift and sly,
Retry once more when pop-ups deny.
New burrows open where web3 lights lie. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat(clerk-js,clerk-react,types): Add Signal support for Web3 APIs" is concise, follows conventional commit formatting, and accurately summarizes the primary change (adding Signal support for Web3 across the named packages), so it clearly communicates the main intent to reviewers.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch ds.feat/signals-web3

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (9)
packages/types/src/signInFuture.ts (2)

118-121: Add JSDoc to the new public Web3 params interface.

Public APIs must ship with JSDoc. Please document the allowed strategies and usage.

Apply this diff:

-export interface SignInFutureWeb3Params {
-  strategy: Web3Strategy;
-}
+/**
+ * @experimental Web3-based sign-in parameters.
+ * @remarks Provide the wallet signature strategy to use.
+ * @example
+ * signIn.__internal_future.web3({ strategy: 'web3_metamask_signature' })
+ */
+export interface SignInFutureWeb3Params {
+  /** Wallet signature strategy, e.g. 'web3_metamask_signature'. */
+  strategy: Web3Strategy;
+}

282-286: Clarify method JSDoc (experimental + param semantics).

Expand the comment to meet the project’s public API doc standard.

-  /**
-   * Used to perform a Web3-based sign-in.
-   */
+  /**
+   * @experimental Perform a Web3-based sign-in using a wallet signature strategy.
+   * @param params.strategy Wallet signature strategy (e.g. 'web3_metamask_signature').
+   */
packages/clerk-js/src/core/resources/SignIn.ts (1)

873-942: Harden error paths and de-duplicate provider selection.

Use centralized error helpers for consistency, add a safe guard for err.code, and collapse the switch into a small provider map for maintainability.

   async web3(params: SignInFutureWeb3Params): Promise<{ error: unknown }> {
     const { strategy } = params;
     const provider = strategy.replace('web3_', '').replace('_signature', '') as Web3Provider;

     return runAsyncResourceTask(this.resource, async () => {
-      let identifier;
-      let generateSignature;
-      switch (provider) {
-        case 'metamask':
-          identifier = await getMetamaskIdentifier();
-          generateSignature = generateSignatureWithMetamask;
-          break;
-        case 'coinbase_wallet':
-          identifier = await getCoinbaseWalletIdentifier();
-          generateSignature = generateSignatureWithCoinbaseWallet;
-          break;
-        case 'base':
-          identifier = await getBaseIdentifier();
-          generateSignature = generateSignatureWithBase;
-          break;
-        case 'okx_wallet':
-          identifier = await getOKXWalletIdentifier();
-          generateSignature = generateSignatureWithOKXWallet;
-          break;
-        default:
-          throw new Error(`Unsupported Web3 provider: ${provider}`);
-      }
+      let identifier: string;
+      let generateSignature: (args: { identifier: string; nonce: string }) => Promise<string>;
+      const providerMap = {
+        metamask: [getMetamaskIdentifier, generateSignatureWithMetamask],
+        coinbase_wallet: [getCoinbaseWalletIdentifier, generateSignatureWithCoinbaseWallet],
+        base: [getBaseIdentifier, generateSignatureWithBase],
+        okx_wallet: [getOKXWalletIdentifier, generateSignatureWithOKXWallet],
+      } as const;
+      const entry = (providerMap as Record<string, readonly [() => Promise<string>, typeof generateSignatureWithMetamask]>)[provider];
+      if (!entry) {
+        throw new Error(`Unsupported Web3 provider: ${provider}`);
+      }
+      const [getIdentifier, signFn] = entry;
+      identifier = await getIdentifier();
+      generateSignature = signFn;

       await this.create({ identifier });

       const web3FirstFactor = this.resource.supportedFirstFactors?.find(
         f => f.strategy === strategy,
       ) as Web3SignatureFactor;
-      if (!web3FirstFactor) {
-        throw new Error('Web3 first factor not found');
-      }
+      if (!web3FirstFactor) {
+        clerkVerifyWeb3WalletCalledBeforeCreate('SignIn');
+      }

       await this.resource.__internal_basePost({
         body: { web3WalletId: web3FirstFactor.web3WalletId, strategy },
         action: 'prepare_first_factor',
       });

-      const { message } = this.firstFactorVerification;
-      if (!message) {
-        throw new Error('Web3 nonce not found');
-      }
+      const { message } = this.firstFactorVerification;
+      if (!message) {
+        clerkVerifyWeb3WalletCalledBeforeCreate('SignIn');
+      }

       let signature: string;
       try {
         signature = await generateSignature({ identifier, nonce: message });
       } catch (err) {
@@
-        if (provider === 'coinbase_wallet' && err.code === 4001) {
+        const code = (err as { code?: unknown })?.code;
+        if (provider === 'coinbase_wallet' && code === 4001) {
           signature = await generateSignature({ identifier, nonce: message });
         } else {
           throw err;
         }
       }

Please confirm the desired behavior for existing in-flight sign-ins: should web3() always create a new sign-in or only when this.resource.id is empty? If reuse is preferred, we can gate await this.create({ identifier }) accordingly.

packages/clerk-js/src/core/resources/SignUp.ts (3)

617-620: Forwarding web3Wallet from Future.create: consider light normalization.

Optional: normalize EVM addresses before sending (e.g., lowercase or checksum) to reduce duplicate identities caused by casing.


783-847: Mirror SignIn fixes: de-duplicate provider mapping and harden error guard.

Same small refactor as SignIn for maintainability and safer err.code access.

   async web3(params: SignUpFutureWeb3Params): Promise<{ error: unknown }> {
     const { strategy, unsafeMetadata, legalAccepted } = params;
     const provider = strategy.replace('web3_', '').replace('_signature', '') as Web3Provider;

     return runAsyncResourceTask(this.resource, async () => {
-      let identifier;
-      let generateSignature;
-      switch (provider) {
-        case 'metamask':
-          identifier = await getMetamaskIdentifier();
-          generateSignature = generateSignatureWithMetamask;
-          break;
-        case 'coinbase_wallet':
-          identifier = await getCoinbaseWalletIdentifier();
-          generateSignature = generateSignatureWithCoinbaseWallet;
-          break;
-        case 'base':
-          identifier = await getBaseIdentifier();
-          generateSignature = generateSignatureWithBase;
-          break;
-        case 'okx_wallet':
-          identifier = await getOKXWalletIdentifier();
-          generateSignature = generateSignatureWithOKXWallet;
-          break;
-        default:
-          throw new Error(`Unsupported Web3 provider: ${provider}`);
-      }
+      let identifier: string;
+      let generateSignature: (args: { identifier: string; nonce: string }) => Promise<string>;
+      const providerMap = {
+        metamask: [getMetamaskIdentifier, generateSignatureWithMetamask],
+        coinbase_wallet: [getCoinbaseWalletIdentifier, generateSignatureWithCoinbaseWallet],
+        base: [getBaseIdentifier, generateSignatureWithBase],
+        okx_wallet: [getOKXWalletIdentifier, generateSignatureWithOKXWallet],
+      } as const;
+      const entry = (providerMap as Record<string, readonly [() => Promise<string>, typeof generateSignatureWithMetamask]>)[provider];
+      if (!entry) {
+        throw new Error(`Unsupported Web3 provider: ${provider}`);
+      }
+      const [getIdentifier, signFn] = entry;
+      identifier = await getIdentifier();
+      generateSignature = signFn;

       // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
       const web3Wallet = identifier || this.resource.web3wallet!;
       await this.create({ web3Wallet, unsafeMetadata, legalAccepted });
@@
       let signature: string;
       try {
         signature = await generateSignature({ identifier, nonce: message });
       } catch (err) {
@@
-        if (provider === 'coinbase_wallet' && err.code === 4001) {
+        const code = (err as { code?: unknown })?.code;
+        if (provider === 'coinbase_wallet' && code === 4001) {
           signature = await generateSignature({ identifier, nonce: message });
         } else {
           throw err;
         }
       }

244-246: Optional: align default strategy with Future.web3 usage.

prepareWeb3WalletVerification defaults to metamask. If Future.web3 becomes the primary entry, consider removing the default here to avoid accidental strategy drift.

packages/types/src/signUpFuture.ts (3)

4-4: Use a type-only import for Web3Strategy.

This is a pure type; switch to import type to satisfy consistent-type-imports and avoid accidental value import.

-import { Web3Strategy } from './strategies';
+import type { Web3Strategy } from './strategies';

16-16: Document web3Wallet as an EVM address (0x...) and add a narrow type

Backend docs indicate web3Wallet is "0x" + 40 hex chars. Add JSDoc and, optionally, an EvmAddress alias and apply it where web3Wallet is typed.

Locations to update: packages/types/src/signUpFuture.ts (line 16), packages/types/src/web3Wallet.ts (web3Wallet field), packages/types/src/user.ts (CreateWeb3WalletParams). Authoritative doc: packages/backend/src/api/resources/Web3Wallet.ts.

Minimal doc-only change:

-  web3Wallet?: string;
+  /**
+   * Optional wallet identifier to prefill the Web3 flow (EVM address, e.g. "0x" followed by 40 hex characters).
+   */
+  web3Wallet?: string;

Optional type alias (add near top of types files and use across typings):

type EvmAddress = `0x${string}`;

Then:

-  web3Wallet?: string;
+  web3Wallet?: EvmAddress;

60-65: Derive SignUpFutureWeb3Params from SignUpFutureAdditionalParams (avoid duplication)

Reuse unsafeMetadata and legalAccepted from SignUpFutureAdditionalParams to prevent drift.

-export interface SignUpFutureWeb3Params {
-  strategy: Web3Strategy;
-  unsafeMetadata?: SignUpUnsafeMetadata;
-  legalAccepted?: boolean;
-}
+export interface SignUpFutureWeb3Params
+  extends Pick<SignUpFutureAdditionalParams, 'unsafeMetadata' | 'legalAccepted'> {
+  strategy: Web3Strategy;
+}

AbortSignal: repo search found only createAbortSignal in packages/clerk-js/src/utils/passkeys.ts and no occurrences of an AbortSignal-typed signal param in Web3-related params — add signal?: AbortSignal only if this PR’s “Signal support” explicitly means cancellation.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f5cd73a and a6aebae.

📒 Files selected for processing (6)
  • .changeset/quick-ghosts-fail.md (1 hunks)
  • packages/clerk-js/src/core/resources/SignIn.ts (2 hunks)
  • packages/clerk-js/src/core/resources/SignUp.ts (3 hunks)
  • packages/react/src/stateProxy.ts (2 hunks)
  • packages/types/src/signInFuture.ts (3 hunks)
  • packages/types/src/signUpFuture.ts (4 hunks)
🧰 Additional context used
📓 Path-based instructions (7)
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

**/*.{js,jsx,ts,tsx}: All code must pass ESLint checks with the project's configuration
Follow established naming conventions (PascalCase for components, camelCase for variables)
Maintain comprehensive JSDoc comments for public APIs
Use dynamic imports for optional features
All public APIs must be documented with JSDoc
Provide meaningful error messages to developers
Include error recovery suggestions where applicable
Log errors appropriately for debugging
Lazy load components and features when possible
Implement proper caching strategies
Use efficient data structures and algorithms
Profile and optimize critical paths
Validate all inputs and sanitize outputs
Implement proper logging with different levels

Files:

  • packages/react/src/stateProxy.ts
  • packages/types/src/signInFuture.ts
  • packages/clerk-js/src/core/resources/SignIn.ts
  • packages/types/src/signUpFuture.ts
  • packages/clerk-js/src/core/resources/SignUp.ts
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/react/src/stateProxy.ts
  • packages/types/src/signInFuture.ts
  • packages/clerk-js/src/core/resources/SignIn.ts
  • packages/types/src/signUpFuture.ts
  • packages/clerk-js/src/core/resources/SignUp.ts
packages/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

TypeScript is required for all packages

Files:

  • packages/react/src/stateProxy.ts
  • packages/types/src/signInFuture.ts
  • packages/clerk-js/src/core/resources/SignIn.ts
  • packages/types/src/signUpFuture.ts
  • packages/clerk-js/src/core/resources/SignUp.ts
packages/**/*.{ts,tsx,d.ts}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Packages should export TypeScript types alongside runtime code

Files:

  • packages/react/src/stateProxy.ts
  • packages/types/src/signInFuture.ts
  • packages/clerk-js/src/core/resources/SignIn.ts
  • packages/types/src/signUpFuture.ts
  • packages/clerk-js/src/core/resources/SignUp.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use proper TypeScript error types

**/*.{ts,tsx}: Always define explicit return types for functions, especially public APIs
Use proper type annotations for variables and parameters where inference isn't clear
Avoid any type - prefer unknown when type is uncertain, then narrow with type guards
Use interface for object shapes that might be extended
Use type for unions, primitives, and computed types
Prefer readonly properties for immutable data structures
Use private for internal implementation details
Use protected for inheritance hierarchies
Use public explicitly for clarity in public APIs
Prefer readonly for properties that shouldn't change after construction
Prefer composition and interfaces over deep inheritance chains
Use mixins for shared behavior across unrelated classes
Implement dependency injection for loose coupling
Let TypeScript infer when types are obvious
Use const assertions for literal types: as const
Use satisfies operator for type checking without widening
Use mapped types for transforming object types
Use conditional types for type-level logic
Leverage template literal types for string manipulation
Use ES6 imports/exports consistently
Use default exports sparingly, prefer named exports
Use type-only imports: import type { ... } from ...
No any types without justification
Proper error handling with typed errors
Consistent use of readonly for immutable data
Proper generic constraints
No unused type parameters
Proper use of utility types instead of manual type construction
Type-only imports where possible
Proper tree-shaking friendly exports
No circular dependencies
Efficient type computations (avoid deep recursion)

Files:

  • packages/react/src/stateProxy.ts
  • packages/types/src/signInFuture.ts
  • packages/clerk-js/src/core/resources/SignIn.ts
  • packages/types/src/signUpFuture.ts
  • packages/clerk-js/src/core/resources/SignUp.ts
**/*.{js,ts,tsx,jsx}

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Support multiple Clerk environment variables (CLERK_, NEXT_PUBLIC_CLERK_, etc.) for configuration.

Files:

  • packages/react/src/stateProxy.ts
  • packages/types/src/signInFuture.ts
  • packages/clerk-js/src/core/resources/SignIn.ts
  • packages/types/src/signUpFuture.ts
  • packages/clerk-js/src/core/resources/SignUp.ts
.changeset/**

📄 CodeRabbit inference engine (.cursor/rules/monorepo.mdc)

Automated releases must use Changesets.

Files:

  • .changeset/quick-ghosts-fail.md
🧬 Code graph analysis (3)
packages/types/src/signInFuture.ts (1)
packages/types/src/strategies.ts (1)
  • Web3Strategy (19-19)
packages/types/src/signUpFuture.ts (1)
packages/types/src/strategies.ts (1)
  • Web3Strategy (19-19)
packages/clerk-js/src/core/resources/SignUp.ts (5)
packages/types/src/signUpFuture.ts (1)
  • SignUpFutureWeb3Params (60-64)
packages/types/src/web3.ts (1)
  • Web3Provider (14-14)
packages/clerk-js/src/utils/runAsyncResourceTask.ts (1)
  • runAsyncResourceTask (8-30)
packages/clerk-js/src/utils/web3.ts (8)
  • getMetamaskIdentifier (49-51)
  • generateSignatureWithMetamask (70-72)
  • getCoinbaseWalletIdentifier (53-55)
  • generateSignatureWithCoinbaseWallet (74-76)
  • getBaseIdentifier (61-63)
  • generateSignatureWithBase (82-84)
  • getOKXWalletIdentifier (57-59)
  • generateSignatureWithOKXWallet (78-80)
packages/clerk-js/src/core/errors.ts (1)
  • clerkVerifyWeb3WalletCalledBeforeCreate (63-67)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: semgrep/ci
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (6)
.changeset/quick-ghosts-fail.md (1)

1-8: Changeset LGTM; confirm experimental gating and release notes alignment.

Minor versions for clerk-js/react/types are appropriate. Ensure docs and changelog clearly mark the feature as Experimental and that any feature flags/env toggles are reflected in product docs before merge.

Would you run a quick sanity check that the docs site has a matching “Experimental” notice for Web3 Signal APIs and that no stable guides reference them yet?

packages/types/src/signInFuture.ts (1)

4-4: Type import addition looks correct.

packages/clerk-js/src/core/resources/SignIn.ts (1)

49-49: Type import is fine.

packages/react/src/stateProxy.ts (2)

95-96: Expose web3 on SignIn signal: LGTM.

Server gating via gateMethod preserves SSR safety.


125-126: Expose web3 on SignUp signal — LGTM.
SignIn/SignUp future types expose web3 (packages/types/src/signUpFuture.ts, packages/types/src/signInFuture.ts).

packages/clerk-js/src/core/resources/SignUp.ts (1)

30-31: Type import addition is fine.

Comment on lines +136 to +140
/**
* Used to perform a Web3-based sign-up.
*/
web3: (params: SignUpFutureWeb3Params) => Promise<{ error: 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

🧩 Analysis chain

API surface LGTM; ensure it’s publicly exported and wired through.

Signature aligns with existing patterns. Verify it’s re-exported from the public types entry and consumed by clerk-js/react.


🏁 Script executed:

#!/bin/bash
set -euo pipefail
# 1) Ensure type is exported from the public entry
rg -nP 'export\s+\{[^}]*SignUpFutureWeb3Params|export\s+\*\s+from .+signUpFuture' packages/types

# 2) Confirm only type-only imports of Web3Strategy remain
rg -nP 'import\s+\{\s*Web3Strategy\s*\}\s+from\s+\'./strategies\'' packages/types/src | rg -nPv '^.*import type'

# 3) Find resource surfaces exposing `web3` for SignUp
rg -nP 'web3\s*:\s*\(params:\s*SignUpFutureWeb3Params' -C2

Length of output: 132


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== 1) repo-wide search for SignUpFutureWeb3Params ==="
rg -n --hidden --no-ignore-vcs "SignUpFutureWeb3Params" || true

echo
echo "=== 2) confirm types public entry exports signUpFuture ==="
rg -n --hidden --no-ignore-vcs "export .*signUpFuture" packages/types/src/index.ts || true
rg -n --hidden --no-ignore-vcs "export \* from './signUpFuture'" packages/types/src/index.ts || true

echo
echo "=== 3) show signUpFuture.ts around web3 and type defs (if file exists) ==="
if [ -f packages/types/src/signUpFuture.ts ]; then
  rg -n -C3 "SignUpFutureWeb3Params|web3\s*:\s*\(params:\s*SignUpFutureWeb3Params" packages/types/src/signUpFuture.ts || true
  echo "---- head of packages/types/src/signUpFuture.ts (first 240 lines) ----"
  sed -n '1,240p' packages/types/src/signUpFuture.ts || true
else
  echo "packages/types/src/signUpFuture.ts not found"
fi

echo
echo "=== 4) check imports of Web3Strategy in packages/types/src ==="
rg -n --hidden --no-ignore-vcs "import .*Web3Strategy" packages/types/src || true
rg -n --hidden --no-ignore-vcs "import type .*Web3Strategy" packages/types/src || true

echo
echo "=== 5) search for consumption across repo (clerk-js/react etc.) ==="
rg -n --hidden --no-ignore-vcs "SignUpFutureWeb3Params|SignUpFuture|signUpFuture" || true
rg -n --hidden --no-ignore-vcs "web3\s*:\s*\(params:\s*SignUpFutureWeb3Params" || true

Length of output: 12693


API surface LGTM — exported and wired; convert Web3Strategy import to type-only

packages/types/src/index.ts exports signUpFuture and packages/clerk-js/src/core/resources/SignUp.ts implements async web3(params: SignUpFutureWeb3Params). Change packages/types/src/signUpFuture.ts (line 4) from:
import { Web3Strategy } from './strategies'
to:
import type { Web3Strategy } from './strategies'
to avoid a runtime import in the types package.

🤖 Prompt for AI Agents
In packages/types/src/signUpFuture.ts (referencing the import at the top around
line 4 and the web3 export around lines 136–140), the file currently imports
Web3Strategy as a runtime dependency which causes an unnecessary runtime import
from the types package; change the import to a type-only import (use the
TypeScript "import type" form for Web3Strategy) so it is erased at runtime and
keep the exported web3 type signature unchanged.

@dstaley dstaley closed this Sep 22, 2025
@dstaley dstaley reopened this Sep 22, 2025
Copy link

pkg-pr-new bot commented Sep 22, 2025

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@6840

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@6840

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@6840

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@6840

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@6840

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@6840

@clerk/elements

npm i https://pkg.pr.new/@clerk/elements@6840

@clerk/clerk-expo

npm i https://pkg.pr.new/@clerk/clerk-expo@6840

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@6840

@clerk/express

npm i https://pkg.pr.new/@clerk/express@6840

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@6840

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@6840

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@6840

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@6840

@clerk/clerk-react

npm i https://pkg.pr.new/@clerk/clerk-react@6840

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@6840

@clerk/remix

npm i https://pkg.pr.new/@clerk/remix@6840

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@6840

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@6840

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@6840

@clerk/themes

npm i https://pkg.pr.new/@clerk/themes@6840

@clerk/types

npm i https://pkg.pr.new/@clerk/types@6840

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@6840

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@6840

commit: 308b84a

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

🧹 Nitpick comments (1)
packages/clerk-js/bundlewatch.config.json (1)

1-35: Consider alerting if multiple related bundles grow together.

Given Web3 Signal additions, verify that other UI bundles (signin*, signup*, vendors*, coinbase*) didn’t grow beyond current caps. If they did, adjust surgically with measured values and include rationale.

If helpful, I can script a size report from a local build and propose precise maxSize values.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a6aebae and 308b84a.

📒 Files selected for processing (1)
  • packages/clerk-js/bundlewatch.config.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,jsx,ts,tsx,json,css,scss,md,yaml,yml}

📄 CodeRabbit inference engine (.cursor/rules/development.mdc)

Use Prettier for consistent code formatting

Files:

  • packages/clerk-js/bundlewatch.config.json
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (28)
  • GitHub Check: Integration Tests (react-router, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 15)
  • GitHub Check: Integration Tests (nuxt, chrome)
  • GitHub Check: Integration Tests (custom, chrome)
  • GitHub Check: Integration Tests (vue, chrome)
  • GitHub Check: Integration Tests (nextjs, chrome, 14)
  • GitHub Check: Integration Tests (quickstart, chrome)
  • GitHub Check: Integration Tests (billing, chrome)
  • GitHub Check: Integration Tests (machine, chrome)
  • GitHub Check: Integration Tests (tanstack-react-start, chrome)
  • GitHub Check: Integration Tests (tanstack-react-router, chrome)
  • GitHub Check: Integration Tests (sessions, chrome)
  • GitHub Check: Integration Tests (astro, chrome)
  • GitHub Check: Integration Tests (expo-web, chrome)
  • GitHub Check: Integration Tests (generic, chrome)
  • GitHub Check: Integration Tests (ap-flows, chrome)
  • GitHub Check: Integration Tests (localhost, chrome)
  • GitHub Check: Integration Tests (express, chrome)
  • GitHub Check: Integration Tests (elements, chrome)
  • GitHub Check: Static analysis
  • GitHub Check: Publish with pkg-pr-new
  • GitHub Check: Unit Tests (22, **)
  • GitHub Check: Unit Tests (18, --filter=@clerk/astro --filter=@clerk/backend --filter=@clerk/express --filter=@c...
  • GitHub Check: Formatting | Dedupe | Changeset
  • GitHub Check: semgrep/ci
  • GitHub Check: Analyze (javascript-typescript)
  • GitHub Check: semgrep-cloud-platform/scan
  • GitHub Check: semgrep-cloud-platform/scan
🔇 Additional comments (1)
packages/clerk-js/bundlewatch.config.json (1)

4-5: Verify and justify bundlewatch budget increases (+2KB) for clerk.browser.js and clerk.legacy.browser.js

  • Observed changes in packages/clerk-js/bundlewatch.config.json:
    • ./dist/clerk.browser.js | 79KB -> 81KB | artifact missing at packages/clerk-js/dist/clerk.browser.js
    • ./dist/clerk.legacy.browser.js | 121KB -> 123KB | artifact missing at packages/clerk-js/dist/clerk.legacy.browser.js
  • Built artifacts are not present in the repo, so post-change sizes could not be measured. Add measured sizes (bytes/KB) and a short rationale in the PR description (e.g., Web3 Signal or other dependency overhead). Prefer setting maxSize = measured + 1KB rather than a flat +2KB.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants