Skip to content

Conversation

@kduprey
Copy link
Contributor

@kduprey kduprey commented Dec 13, 2025

Description

This PR ports over the new Sign in with Solana feature changes currently in Core 2 over to Core 3, allowing for continued support of the new feature.

USER-4212

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

    • Sign in / Sign up with Solana wallets — dedicated wallet chooser, Solana-specific authentication flows, and wallet-name support.
    • New Solana wallet buttons and responsive wallet-selection screens for quick connect/continue.
    • Profile UI updated to add, select and manage Solana wallets.
  • Documentation

    • Added Solana/Web3 UI copy and new Web3 error messages across 40+ locales.

✏️ Tip: You can customize this high-level summary in your review settings.

@kduprey kduprey requested a review from dstaley December 13, 2025 00:58
@kduprey kduprey self-assigned this Dec 13, 2025
@changeset-bot
Copy link

changeset-bot bot commented Dec 13, 2025

🦋 Changeset detected

Latest commit: bca9f40

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

This PR includes changesets to release 19 packages
Name Type
@clerk/localizations Minor
@clerk/clerk-js Minor
@clerk/shared Minor
@clerk/react Minor
@clerk/ui Minor
@clerk/chrome-extension Patch
@clerk/expo Patch
@clerk/agent-toolkit Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/nextjs Patch
@clerk/nuxt Patch
@clerk/react-router Patch
@clerk/tanstack-react-start Patch
@clerk/testing 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

@vercel
Copy link

vercel bot commented Dec 13, 2025

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

Project Deployment Review Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Dec 15, 2025 5:10pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

Walkthrough

Adds Solana Web3 wallet support across SDKs and UI: new authenticateWithSolana flows, Solana provider discovery and signMessage signing, wallet-selection UI and routes, type and localization additions, dependency updates, and bundling/config adjustments.

Changes

Cohort / File(s) Summary
Changesets
\.changeset/afraid-apes-cough.md`, `.changeset/legal-jokes-beg.md``
Adds changeset files documenting Solana feature and package version bumps.
Core SDK: Clerk JS
\packages/clerk-js/src/core/clerk.ts`, `packages/clerk-js/src/core/resources/SignIn.ts`, `packages/clerk-js/src/core/resources/SignUp.ts``
Adds authenticateWithSolana methods; threads walletName through web3 auth/sign-in/up flows; Solana-specific signature generation and error handling.
Web3 infra (shared)
\packages/shared/src/internal/.../web3.ts`, `packages/shared/src/internal/.../injectedWeb3SolanaProviders.ts`, `packages/shared/src/internal/.../injectedWeb3EthProviders.ts``
Implements Solana provider discovery singleton, Solana identifier retrieval, unified signature generation (Solana + Ethereum), and renames Eth provider module/types.
Types
\packages/shared/src/types/*``
Adds Solana types (AuthenticateWithSolanaParams, SignIn/SignUp Solana params), extends Web3Provider union, adds walletName fields and localization typings.
UI components & elements
\packages/ui/src/elements/Web3SolanaWalletButtons.tsx`, `packages/ui/src/components//SignInFactorOneSolanaWalletsCard.tsx`, `packages/ui/src/components//SignUpStartSolanaWalletsCard.tsx`, `packages/ui/src/components/UserProfile/Web3SelectSolanaWalletScreen.tsx`, `packages/ui/src/components/UserProfile/Web3Form.tsx`, `packages/ui/src/common/WalletInitialIcon.tsx``
Adds Solana wallet buttons, wallet-selection screens/cards, wallet initial icon; refactors Web3Form to handle walletName and two-panel flow.
UI integration & routing
\packages/ui/src/components/SignIn/index.tsx`, `packages/ui/src/components/SignUp/index.tsx`, `packages/ui/src/components/SignIn/SignInSocialButtons.tsx`, `packages/ui/src/components/SignUp/SignUpSocialButtons.tsx``
Adds 'choose-wallet' routes and routes web3_solana_signature strategy to the wallet-selection UI.
Appearance & contexts
\packages/ui/src/customizables/elementDescriptors.ts`, `packages/ui/src/internal/appearance.ts`, `packages/ui/src/elements/contexts/index.tsx``
Adds appearance keys and ElementsConfig for Solana wallet UI; adds 'chooseWallet' to FlowMetadata.part.
React wrapper
\packages/react/src/isomorphicClerk.ts``
Adds authenticateWithSolana premount/replay wiring to isomorphic clerk wrapper.
Build & deps / bundling
\packages/clerk-js/package.json`, `packages/ui/package.json`, `packages/shared/package.json`, `pnpm-workspace.yaml`, `packages/clerk-js/rspack.config.js`, `packages/clerk-js/bundle-check.mjs``
Adds Solana wallet adapter dependencies, updates workspace, excludes Solana packages from vendor chunk test, and updates Playwright JSDoc reference.
Localizations
\packages/localizations/src/*` (40+ files)`
Adds Solana web3 sign-in/sign-up strings, wallet selection screen texts, web3SolanaWalletButtons, and Web3-related error messages across locales.
Utilities & fixes
\packages/ui/src/utils/web3CallbackErrorHandler.ts`, `packages/ui/bundlewatch.config.json``
Hardens error access with optional chaining; increases vendor bundlewatch maxSize.
Naming / refactor
\packages/shared/src/internal/clerk-js/injectedWeb3EthProviders.ts`, `packages/shared/src/internal/clerk-js/injectedWeb3Providers.ts``
Renames injected web3 provider types/module to Eth-focused names and adjusts exports accordingly.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as Client UI
    participant ClerkJS as Clerk JS
    participant WalletUI as Wallet Selection UI
    participant Wallet as Solana Wallet
    participant Backend as Clerk Backend

    User->>UI: Click "Sign in with Solana"
    UI->>ClerkJS: web3Callback(strategy: web3_solana_signature)
    ClerkJS->>UI: navigate('choose-wallet')
    UI->>WalletUI: render wallet options
    WalletUI->>Wallet: query installed wallets
    Wallet-->>WalletUI: return wallets
    WalletUI-->>User: show wallet buttons
    User->>WalletUI: select wallet (walletName)
    WalletUI->>ClerkJS: authenticateWithSolana({ walletName, redirect... })
    ClerkJS->>Wallet: connect / request public key
    Wallet-->>ClerkJS: public key (identifier)
    ClerkJS->>Wallet: signMessage(nonce)
    Wallet->>User: prompt to approve signature
    User->>Wallet: approve
    Wallet-->>ClerkJS: signature (base64)
    ClerkJS->>Backend: authenticateWithWeb3({ identifier, signature, strategy })
    Backend-->>ClerkJS: auth token / session
    ClerkJS-->>UI: complete sign-in (redirect)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Areas to focus review on:

  • packages/clerk-js/src/core/clerk.ts — new public API authenticateWithSolana and walletName propagation.
  • packages/shared/src/internal/clerk-js/injectedWeb3SolanaProviders.ts — dynamic imports, event subscriptions, singleton lifecycle, fallback behavior.
  • packages/shared/src/internal/clerk-js/web3.ts — Solana signMessage flow, encoding, error mapping and exposed methods.
  • packages/ui/src/elements/Web3SolanaWalletButtons.tsx — wallet discovery/rendering, layout and retry logic.
  • packages/ui/src/components/UserProfile/Web3Form.tsx — refactor to two-panel flow and walletName handling.
  • Types across packages/shared/src/types/** — ensure consistency of walletName threading and new Web3Provider composition.
  • packages/clerk-js/rspack.config.js — custom vendor test logic excluding Solana packages.

Poem

"I'm a rabbit with a tiny key,
hopping through chains of Solana tree,
wallets gleam and buttons glow,
signatures signed — hop, off we go!
Here’s to wallets, swift and spry 🥕"

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(clerk-js,react,localizations,shared,ui): Add Solana feature support to core 3' clearly summarizes the main change: adding Solana support across multiple core packages for the core 3 release.
Linked Issues check ✅ Passed The PR successfully implements the objective from USER-4212 to port Solana feature support from Core 2 to Core 3, with comprehensive changes across clerk-js, shared, react, ui, and localizations packages.
Out of Scope Changes check ✅ Passed All code changes are directly related to implementing Solana Web3 authentication support across the specified packages, including dependencies, type definitions, localization, and UI components. No unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch kenton/user-4212-add-solana-support-to-core-3

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Dec 13, 2025

Open in StackBlitz

@clerk/agent-toolkit

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

@clerk/astro

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

@clerk/backend

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

@clerk/chrome-extension

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

@clerk/clerk-js

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

@clerk/dev-cli

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

@clerk/expo

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

@clerk/expo-passkeys

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

@clerk/express

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

@clerk/fastify

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

@clerk/localizations

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

@clerk/nextjs

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

@clerk/nuxt

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

@clerk/react

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

@clerk/react-router

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

@clerk/shared

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

@clerk/tanstack-react-start

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

@clerk/testing

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

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@7450

@clerk/upgrade

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

@clerk/vue

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

commit: bca9f40

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

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (13)
packages/shared/src/internal/clerk-js/injectedWeb3SolanaProviders.ts-54-60 (1)

54-60: Unsafe type cast for fallback provider.

The fallback window.solana is cast to SolanaWalletAdapterWallet after only checking for connect and signMessage methods. The SolanaWalletAdapterWallet interface likely requires additional properties (like accounts, chains, features) that the legacy window.solana provider may not have, potentially causing runtime errors in generateWeb3Signature when accessing wallet.accounts or wallet.features.

Consider either:

  1. Adding more comprehensive validation before casting
  2. Returning a different type for the fallback case
  3. Adding a comment documenting the expected behavior with legacy providers
packages/clerk-js/package.json-65-67 (1)

65-67: Remove @solana/wallet-adapter-react dependency.

@solana/wallet-adapter-react is included in dependencies but has no imports or usage anywhere in the codebase. Remove it to reduce bundle size.

packages/localizations/src/ro-RO.ts-1344-1347 (1)

1344-1347: Wallet selection screen strings: consider informal voice to match the rest of the locale.

packages/localizations/src/ro-RO.ts-763-766 (1)

763-766: Keep tone consistent: consider switching “Selectați” → “Selectează”.
This file generally speaks informally, so the new Solana copy reads inconsistent.

packages/localizations/src/ro-RO.ts-860-863 (1)

860-863: Keep tone consistent: consider switching “Selectați” → “Selectează”.

packages/localizations/src/ro-RO.ts-973-975 (1)

973-975: New Web3 error strings: OK, but keep tone consistent (“Ați/Încercați” vs informal).

packages/localizations/src/de-DE.ts-1402-1407 (1)

1402-1407: Same tone issue here (“Bitte installiere …”): align with formal “Sie”.

-      'Keine Solana-Web3-Wallets erkannt. Bitte installiere eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
+      'Keine Solana-Web3-Wallets erkannt. Bitte installieren Sie eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
packages/localizations/src/de-DE.ts-983-986 (1)

983-986: Fix pronoun/tone consistency (Sie vs du) in new de-DE error strings. The surrounding German copy is predominantly formal (“Sie”), but these lines switch to informal (“Du …”).

-    web3_signature_request_rejected:
-      'Du hast die Signaturanfrage abgelehnt. Bitte versuche es erneut, um fortzufahren.',
-    web3_solana_signature_generation_failed:
-      'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuche es erneut, um fortzufahren.',
+    web3_signature_request_rejected:
+      'Sie haben die Signaturanfrage abgelehnt. Bitte versuchen Sie es erneut, um fortzufahren.',
+    web3_solana_signature_generation_failed:
+      'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut, um fortzufahren.',
packages/localizations/src/es-UY.ts-1380-1385 (1)

1380-1385: Localize the user-visible link label ("wallet extension") in noneAvailable.

  web3SolanaWalletButtons: {
    connect: 'Conectar con {{walletName}}',
    continue: 'Continuar con {{walletName}}',
    noneAvailable:
-      'No se detectaron billeteras Web3 de Solana. Instala una {{ solanaWalletsLink || link("wallet extension") }} compatible con Web3.',
+      'No se detectaron billeteras Web3 de Solana. Instalá una {{ solanaWalletsLink || link("extensión de billetera") }} compatible con Web3.',
  },
packages/localizations/src/es-UY.ts-968-970 (1)

968-970: Keep voseo consistent in the new error messages (“Intentá”, not “Inténtalo”).
Current strings switch to “tú” imperative, while the rest of es-UY uses voseo.

-    web3_signature_request_rejected: 'Has rechazado la solicitud de firma. Inténtalo de nuevo para continuar.',
+    web3_signature_request_rejected: 'Has rechazado la solicitud de firma. Intentá de nuevo para continuar.',
     web3_solana_signature_generation_failed:
-      'Se produjo un error al generar la firma. Inténtalo de nuevo para continuar.',
+      'Se produjo un error al generar la firma. Intentá de nuevo para continuar.',
packages/localizations/src/be-BY.ts-1376-1381 (1)

1376-1381: Localize the user-visible link label ("wallet extension") in noneAvailable.
link("wallet extension") will render English text in a be-BY UI.

  web3SolanaWalletButtons: {
    connect: 'Падключыцца з {{walletName}}',
    continue: 'Працягнуць з {{walletName}}',
    noneAvailable:
-      'Кашалькі Solana Web3 не выяўлены. Калі ласка, усталюйце {{ solanaWalletsLink || link("wallet extension") }} з падтрымкай Web3.',
+      'Кашалькі Solana Web3 не выяўлены. Калі ласка, усталюйце {{ solanaWalletsLink || link("пашырэнне кашалька") }} з падтрымкай Web3.',
  },
packages/localizations/src/bn-IN.ts-1378-1383 (1)

1378-1383: Localize the user-visible link label ("wallet extension") in noneAvailable.

  web3SolanaWalletButtons: {
    connect: '{{walletName}} দিয়ে সংযুক্ত করুন',
    continue: '{{walletName}} দিয়ে চালিয়ে যান',
    noneAvailable:
-      'কোনো Solana Web3 ওয়ালেট শনাক্ত হয়নি। অনুগ্রহ করে Web3 সমর্থিত {{ solanaWalletsLink || link("wallet extension") }} ইনস্টল করুন।',
+      'কোনো Solana Web3 ওয়ালেট শনাক্ত হয়নি। অনুগ্রহ করে Web3 সমর্থিত {{ solanaWalletsLink || link("ওয়ালেট এক্সটেনশন") }} ইনস্টল করুন।',
  },
packages/localizations/src/ko-KR.ts-1350-1355 (1)

1350-1355: Localize the user-visible link label ("wallet extension") in noneAvailable.

  web3SolanaWalletButtons: {
    connect: '{{walletName}}(으)로 연결',
    continue: '{{walletName}}(으)로 계속',
    noneAvailable:
-      'Solana Web3 지갑을 찾을 수 없습니다. Web3를 지원하는 {{ solanaWalletsLink || link("wallet extension") }}을(를) 설치해 주세요.',
+      'Solana Web3 지갑을 찾을 수 없습니다. Web3를 지원하는 {{ solanaWalletsLink || link("지갑 확장 프로그램") }}을(를) 설치해 주세요.',
  },
🧹 Nitpick comments (40)
packages/localizations/src/te-IN.ts (1)

1379-1384: Localize the link label inside link("wallet extension") for te-IN

Right now the surrounding sentence is Telugu, but the link label defaults to English (“wallet extension”), which will likely surface as English UI in this locale. Suggest translating just the link label while keeping the token structure identical.

 web3SolanaWalletButtons: {
   connect: '{{walletName}} తో కనెక్ట్ అవ్వండి',
   continue: '{{walletName}} తో కొనసాగించండి',
   noneAvailable:
-    'Solana Web3 వాలెట్లు ఏవీ గుర్తించబడలేదు. Web3 కి మద్దతు ఉన్న {{ solanaWalletsLink || link("wallet extension") }} ను ఇన్‌స్టాల్ చేయండి.',
+    'Solana Web3 వాలెట్లు ఏవీ గుర్తించబడలేదు. Web3 కి మద్దతు ఉన్న {{ solanaWalletsLink || link("వాలెట్ ఎక్స్‌టెన్షన్") }} ను ఇన్‌స్టాల్ చేయండి.',
 },
packages/ui/src/utils/web3CallbackErrorHandler.ts (1)

6-8: Prefer unknown over any for the error parameter.

The err parameter is typed as any, which violates the coding guidelines. Since the type is uncertain and you're already using isClerkAPIResponseError as a type guard, consider refactoring to use unknown for better type safety.

As per coding guidelines, prefer unknown over any for type safety.

Apply this diff:

 type Web3CallbackErrorHandler = {
-  (err: any, setError?: (err: ClerkRuntimeErrorType | ClerkAPIError | string | undefined) => void): void;
+  (err: unknown, setError?: (err: ClerkRuntimeErrorType | ClerkAPIError | string | undefined) => void): void;
 };
packages/ui/src/common/WalletInitialIcon.tsx (1)

5-11: Consider documenting the expected value format.

The value prop represents the wallet name/label but lacks documentation about format requirements. Consider adding a JSDoc comment explaining what value represents and any format expectations.

Apply this diff to improve documentation:

 type WalletInitialIconProps = PropsOfComponent<typeof Box> & {
+  /**
+   * The wallet name or label to display the initial of
+   */
   value: string;
   /**
    * The wallet provider name
    */
   id: string;
 };
packages/shared/src/internal/clerk-js/web3.ts (3)

80-81: Potential issue with large signature byte arrays.

Using String.fromCharCode(...signedMessages[0].signature) with the spread operator may fail for large Uint8Array values due to stack size limitations. While Solana signatures are typically 64 bytes (well within limits), consider using a more robust approach:

- return signedMessages?.[0]?.signature ? btoa(String.fromCharCode(...signedMessages[0].signature)) : '';
+ if (!signedMessages?.[0]?.signature) {
+   return '';
+ }
+ // Convert Uint8Array to base64 without spread operator stack limitations
+ const bytes = signedMessages[0].signature;
+ let binary = '';
+ for (let i = 0; i < bytes.length; i++) {
+   binary += String.fromCharCode(bytes[i]);
+ }
+ return btoa(binary);

Alternatively, if the environment supports it, use Buffer.from(bytes).toString('base64').


82-87: Brittle error detection based on message string.

Checking err.message.includes('User rejected the request.') is fragile as the exact message may vary across wallet implementations or change in future versions.

Consider checking for common error codes or error types if available:

- if (err instanceof Error && err.message.includes('User rejected the request.')) {
+ // Check for user rejection - wallets may use different error patterns
+ const isUserRejection = err instanceof Error && (
+   err.message.includes('User rejected') ||
+   err.message.includes('user rejected') ||
+   (err as any).code === 4001 // Standard rejection code
+ );
+ if (isUserRejection) {

46-49: Consider adding a feature existence check before accessing StandardConnect.

The code assumes wallet.features[StandardConnect] exists. If a wallet doesn't support this feature, connect() will fail with an unclear error.

  if (provider === 'solana') {
+   if (!walletProvider.features?.[StandardConnect]) {
+     console.warn('Solana wallet does not support StandardConnect feature');
+     return '';
+   }
    const identifiers = await walletProvider.features[StandardConnect].connect();
    return (identifiers && identifiers.accounts[0].address) || '';
  }
packages/shared/src/types/web3Wallet.ts (1)

30-35: Add JSDoc for the new walletName property.

As per coding guidelines, public API properties should be documented with JSDoc comments. Consider adding documentation for walletName to clarify its purpose and when it's required (e.g., for Solana sign-ins).

 export interface AuthenticateWithWeb3Params {
   identifier: string;
   generateSignature: GenerateSignature;
   strategy?: Web3Strategy;
+  /**
+   * The name of the wallet to use for Solana sign-ins.
+   * Required when using Solana-based Web3 authentication.
+   */
   walletName?: string;
 }
packages/shared/src/types/signInFuture.ts (1)

243-256: Consider using a discriminated union for compile-time safety.

The JSDoc correctly states that walletName is "Required when provider is set to 'solana'", but this constraint isn't enforced at the type level. Using a discriminated union would catch missing walletName at compile time for Solana flows.

Example approach:

export type SignInFutureWeb3Params =
  | {
      strategy: Web3Strategy;
      provider: Exclude<Web3Provider, 'solana'>;
      walletName?: string;
    }
  | {
      strategy: Web3Strategy;
      provider: 'solana';
      walletName: string;
    };

That said, the current implementation with runtime validation is acceptable for this feature port.

packages/shared/src/types/signUp.ts (1)

111-111: Add JSDoc for the new authenticateWithSolana method.

The new method follows the established pattern for Web3 wallet authentication. Note that unlike other Web3 methods (lines 107-110) which have optional params, this correctly requires params since walletName is mandatory for Solana flows.

Consider adding JSDoc documentation to maintain consistency with other public API methods.

+  /**
+   * Authenticates the user with a Solana wallet.
+   * @param params - The authentication parameters including the required wallet name.
+   * @returns A promise that resolves to the updated SignUpResource.
+   */
   authenticateWithSolana: (params: SignUpAuthenticateWithSolanaParams) => Promise<SignUpResource>;
packages/localizations/src/vi-VN.ts (1)

1374-1379: Localize the link label inside link("wallet extension").
Right now the CTA label is English; consider Vietnamese (e.g., link("tiện ích mở rộng ví")) to keep the whole sentence localized.

packages/localizations/src/ro-RO.ts (1)

1383-1388: Localize link("wallet extension") and align formality (“Instalați” vs informal).
E.g., consider link("extensie de portofel") (and corresponding verb form).

packages/localizations/src/es-MX.ts (1)

1381-1386: Localize the link label inside link("wallet extension").
For es-MX, consider something like link("extensión de billetera") so the CTA isn’t English.

packages/ui/src/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx (1)

12-16: Lazy-load setup looks fine; consider adding an error boundary for render-time failures.
Suspense won’t catch exceptions thrown by wallet/provider initialization; an error boundary would prevent a hard crash and can surface card.setError.

packages/ui/src/components/SignUp/SignUpStartSolanaWalletsCard.tsx (1)

21-89: Consider ctx.afterSignUpUrl ?? '/' instead of || to avoid treating '' as missing (if empty-string is meaningful).

-                      redirectUrl: ctx.afterSignUpUrl || '/',
+                      redirectUrl: ctx.afterSignUpUrl ?? '/',
packages/ui/src/elements/Web3SolanaWalletButtons.tsx (2)

57-66: Don’t silently swallow unexpected auth callback failures.
If web3AuthCallback throws (e.g., a future refactor removes the .catch in callers), consider surfacing something via card.setError(...) (and/or rethrow) rather than sleeping and returning.

   const startWeb3AuthFlow = (walletName: string) => async () => {
     card.setLoading(walletName);
     try {
       await web3AuthCallback({ walletName });
-    } catch {
-      await sleep(1000);
+    } catch (err) {
+      card.setError(err instanceof Error ? err.message : 'Web3 authentication failed');
+      await sleep(1000);
     } finally {
       card.setIdle();
     }
   };

195-263: WalletButtonBlock icon handling has a dead branch / mismatched types.
WalletButtonProps.icon is a ReactElement, so isValidElement(icon) is almost always true and the !isIconElement && icon branch is effectively unreachable. Either:

  • simplify by removing that branch, or
  • widen icon’s type to ReactNode | React.ComponentType and handle both intentionally.

(Keeping this tight also avoids the as unknown as React.ComponentType cast.)

packages/localizations/src/nl-NL.ts (1)

1365-1370: Consider localizing the link label (“wallet extension”) for nl-NL.
Everything else (placeholder + link() fallback) looks correct. Based on learnings, undefined keys elsewhere are expected.

packages/shared/src/types/clerk.ts (1)

2250-2259: walletName?: string on ClerkAuthenticateWithWeb3Params is a bit under-typed—consider making it strategy-discriminated.
If strategy: 'web3_solana' | ... (or equivalent) exists, prefer a union where walletName is required only for the Solana variant to prevent runtime “missing walletName” failures.

packages/localizations/src/ja-JP.ts (1)

1378-1383: Optional: localize the link label (“wallet extension”) for ja-JP.
The solanaWalletsLink || link(...) fallback usage looks correct. Based on learnings, undefined keys elsewhere are expected.

packages/localizations/src/pt-PT.ts (1)

1365-1370: Optional: localize the link label (“wallet extension”) for pt-PT.
Fallback linking pattern looks correct. Based on learnings, undefined keys elsewhere are expected.

packages/localizations/src/fi-FI.ts (1)

1368-1373: Consider localizing the link label inside link("wallet extension").
Right now the clickable label is English inside an otherwise Finnish sentence.

   web3SolanaWalletButtons: {
     connect: 'Yhdistä {{walletName}}',
     continue: 'Jatka {{walletName}}',
     noneAvailable:
-      'Solana Web3 -lompakoita ei havaittu. Asenna Web3-yhteensopiva {{ solanaWalletsLink || link("wallet extension") }}.',
+      'Solana Web3 -lompakoita ei havaittu. Asenna Web3-yhteensopiva {{ solanaWalletsLink || link("lompakkolaajennus") }}.',
   },
packages/localizations/src/el-GR.ts (1)

1376-1381: Consider localizing the link label inside link("wallet extension").
The rest of the sentence is Greek; the linked label is English.

   web3SolanaWalletButtons: {
     connect: 'Σύνδεση με {{walletName}}',
     continue: 'Συνέχεια με {{walletName}}',
     noneAvailable:
-      'Δεν εντοπίστηκαν πορτοφόλια Solana Web3. Εγκαταστήστε ένα {{ solanaWalletsLink || link("wallet extension") }} με υποστήριξη Web3.',
+      'Δεν εντοπίστηκαν πορτοφόλια Solana Web3. Εγκαταστήστε ένα {{ solanaWalletsLink || link("επέκταση πορτοφολιού") }} με υποστήριξη Web3.',
   },
packages/localizations/src/fr-FR.ts (1)

1391-1396: Consider localizing the link label inside link("wallet extension").
The linked label is English in an otherwise French sentence.

   web3SolanaWalletButtons: {
     connect: 'Se connecter avec {{walletName}}',
     continue: 'Continuer avec {{walletName}}',
     noneAvailable:
-      'Aucun portefeuille Solana Web3 détecté. Veuillez installer une {{ solanaWalletsLink || link("wallet extension") }} compatible Web3.',
+      'Aucun portefeuille Solana Web3 détecté. Veuillez installer une {{ solanaWalletsLink || link("extension de portefeuille") }} compatible Web3.',
   },
packages/localizations/src/uk-UA.ts (1)

1364-1369: Consider localizing the link label inside link("wallet extension").
The linked label is English in an otherwise Ukrainian sentence.

   web3SolanaWalletButtons: {
     connect: 'Підключитися через {{walletName}}',
     continue: 'Продовжити через {{walletName}}',
     noneAvailable:
-      'Гаманці Solana Web3 не виявлено. Установіть {{ solanaWalletsLink || link("wallet extension") }} з підтримкою Web3.',
+      'Гаманці Solana Web3 не виявлено. Установіть {{ solanaWalletsLink || link("розширення гаманця") }} з підтримкою Web3.',
   },
packages/localizations/src/pt-BR.ts (1)

1385-1390: Consider localizing the fallback link label (“wallet extension”) for pt-BR. It’s user-facing if solanaWalletsLink isn’t provided.

-      'Nenhuma carteira Solana Web3 foi detectada. Instale uma {{ solanaWalletsLink || link("wallet extension") }} compatível com Web3.',
+      'Nenhuma carteira Solana Web3 foi detectada. Instale uma {{ solanaWalletsLink || link("extensão de carteira") }} compatível com Web3.',
packages/localizations/src/ca-ES.ts (1)

1373-1378: Consider localizing the fallback link label (“wallet extension”) for ca-ES.

-      'No s\'han detectat carteres Web3 de Solana. Instal·la una {{ solanaWalletsLink || link("wallet extension") }} compatible amb Web3.',
+      'No s\'han detectat carteres Web3 de Solana. Instal·la una {{ solanaWalletsLink || link("extensió de cartera") }} compatible amb Web3.',
packages/localizations/src/zh-CN.ts (1)

1332-1337: Optional: localize the fallback link label (“wallet extension”) for zh-CN.

-      '未检测到 Solana Web3 钱包。请安装支持 Web3 的 {{ solanaWalletsLink || link("wallet extension") }}。',
+      '未检测到 Solana Web3 钱包。请安装支持 Web3 的 {{ solanaWalletsLink || link("钱包扩展") }}。',
packages/localizations/src/cs-CZ.ts (1)

1380-1385: Optional: localize fallback link label (“wallet extension”) for cs-CZ.

-      'Nebyla zjištěna žádná Solana Web3 peněženka. Nainstalujte si prosím {{ solanaWalletsLink || link("wallet extension") }} s podporou Web3.',
+      'Nebyla zjištěna žádná Solana Web3 peněženka. Nainstalujte si prosím {{ solanaWalletsLink || link("rozšíření peněženky") }} s podporou Web3.',
packages/clerk-js/src/core/resources/SignIn.ts (3)

368-416: Consider narrowing err before reading err.code (TS safety), but overall Solana walletName propagation looks solid.

  • Requiring walletName when provider === 'solana' is a good guardrail.
  • Passing { walletName, provider } into generateSignature and preserving Coinbase retry is consistent.

Suggested small hardening (keeps behavior identical):

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

454-462: Add JSDoc for new public API authenticateWithSolana (public surface).
This is a new exported capability and should be documented alongside the other auth helpers.


975-1063: SignInFuture.web3 Solana branch looks correct; drop the unnecessary as string cast.
Since you already throw when !params.walletName, you can avoid the assertion:

         case 'solana':
           if (!params.walletName) {
             throw new ClerkRuntimeError('Wallet name is required for Solana authentication.', {
               code: 'web3_solana_wallet_name_required',
             });
           }
           identifier = await web3().getSolanaIdentifier(params.walletName);
           generateSignature = p =>
-            web3().generateSignatureWithSolana({ ...p, walletName: params.walletName as string });
+            web3().generateSignatureWithSolana({ ...p, walletName: params.walletName });
           break;
packages/localizations/src/en-US.ts (1)

1367-1372: web3SolanaWalletButtons.noneAvailable placeholder/link pattern is correct; consider a small grammar tweak.
“a Web3 supported …” reads a bit off; “a Web3-supported …” would scan better.

packages/ui/src/components/UserProfile/Web3Form.tsx (1)

65-73: Avoid catch (err: any); use unknown and narrow.
This keeps the error-handling path type-safe and matches TS guidelines.

-    } catch (err: any) {
+    } catch (err: unknown) {
       card.setIdle();
       const fieldError = getFieldError(err);
       if (fieldError) {
         card.setError(fieldError.longMessage);
       } else {
         handleError(err, [], card.setError);
       }
     }
packages/clerk-js/src/core/clerk.ts (1)

2342-2348: Add JSDoc for the new public API authenticateWithSolana.
This is a new externally-facing method; please document params (esp. walletName) + redirects. As per coding guidelines.

packages/localizations/src/ru-RU.ts (1)

1389-1394: Localize the link label in noneAvailable (currently English: “wallet extension”).
This will show up in Russian UI.

   web3SolanaWalletButtons: {
     connect: 'Подключиться через {{walletName}}',
     continue: 'Продолжить через {{walletName}}',
     noneAvailable:
-      'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("wallet extension") }} с поддержкой Web3.',
+      'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("расширение кошелька") }} с поддержкой Web3.',
   },

Based on learnings, undefined localization values are expected fallbacks and should remain as-is.

packages/localizations/src/he-IL.ts (1)

1343-1348: Consider localizing the link label in noneAvailable (“wallet extension”).

   web3SolanaWalletButtons: {
     connect: 'התחבר/י עם {{walletName}}',
     continue: 'המשך/י עם {{walletName}}',
     noneAvailable:
-      'לא זוהו ארנקי Solana Web3. נא להתקין {{ solanaWalletsLink || link("wallet extension") }} התומך ב‑Web3.',
+      'לא זוהו ארנקי Solana Web3. נא להתקין {{ solanaWalletsLink || link("תוסף ארנק") }} התומך ב‑Web3.',
   },

Based on learnings, undefined localization values are expected fallbacks and should remain as-is.

packages/localizations/src/bg-BG.ts (1)

1367-1372: Localize the link label in noneAvailable (currently English: “wallet extension”).

   web3SolanaWalletButtons: {
     connect: 'Свързване с {{walletName}}',
     continue: 'Продължаване с {{walletName}}',
     noneAvailable:
-      'Не са открити Solana Web3 портфейли. Моля, инсталирайте {{ solanaWalletsLink || link("wallet extension") }} с поддръжка на Web3.',
+      'Не са открити Solana Web3 портфейли. Моля, инсталирайте {{ solanaWalletsLink || link("разширение за портфейл") }} с поддръжка на Web3.',
   },

Based on learnings, undefined localization values are expected fallbacks and should remain as-is.

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

260-309: Harden Web3 signature flow: narrow err and keep retry args consistent

  • If useUnknownInCatchVariables is enabled, err.code (Line 301) will be unsafe without narrowing.
  • Coinbase retry (Line 302) currently drops walletName; harmless today, but better to keep call shapes consistent.
@@
-    } catch (err) {
+    } catch (err) {
@@
-      if (provider === 'coinbase_wallet' && err.code === 4001) {
-        signature = await generateSignature({ identifier, nonce: message, provider });
+      const code = typeof err === 'object' && err !== null && 'code' in err ? (err as any).code : undefined;
+      if (provider === 'coinbase_wallet' && code === 4001) {
+        signature = await generateSignature({ identifier, nonce: message, provider, walletName });
       } else {
         throw err;
       }
     }

361-371: Validate walletName early to avoid opaque Solana failures
authenticateWithSolana assumes params.walletName is valid (Line 362). Consider failing fast with a clear error (and keep params access non-optional since it’s required).

@@
   public authenticateWithSolana = async (params: SignUpAuthenticateWithSolanaParams): Promise<SignUpResource> => {
+    if (!params.walletName?.trim()) {
+      clerkMissingOptionError('walletName');
+    }
     const identifier = await web3().getSolanaIdentifier(params.walletName);
     return this.authenticateWithWeb3({
@@
-      unsafeMetadata: params?.unsafeMetadata,
+      unsafeMetadata: params.unsafeMetadata,
       strategy: 'web3_solana_signature',
-      legalAccepted: params?.legalAccepted,
+      legalAccepted: params.legalAccepted,
       walletName: params.walletName,
     });
   };
packages/localizations/src/th-TH.ts (1)

753-757: LGTM: placeholders align with the new Solana localization params
{{walletName}} and {{ solanaWalletsLink || link("wallet extension") }} match the expected param names, and the new keys are correctly placed under signIn, signUp, unstable__errors, web3WalletsSection, and web3SolanaWalletButtons. (Also noting: existing undefined keys in this repo’s localization files are intentional fallbacks, so no concerns there.) Based on learnings, undefined values are expected.
Optional: consider localizing the "wallet extension" fallback label inside the link(...) call for a fully Thai experience.

Also applies to: 848-852, 954-956, 1315-1323, 1358-1364

Comment on lines +39 to +43
get = async (walletName: string): Promise<SolanaWalletAdapterWallet | undefined> => {
await this.#initialize();
const wallet = (this.#wallets || []).find(
w => w.name === walletName && this.#isSolanaWallet(w) && this.#hasSignMessage(w),
);
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 | 🟠 Major

Repeated initialization causes event listener memory leak.

#initialize() is called on every get() invocation, which re-registers event listeners without cleanup. This will accumulate listeners over time and cause a memory leak.

Consider adding an initialization guard:

+ #initialized = false;
+
  async #initialize() {
+   if (this.#initialized) {
+     return;
+   }
+   this.#initialized = true;
    const wallets = await import('@wallet-standard/core').then(mod => mod.getWallets());
    this.#wallets = wallets.get();

    wallets.on('register', () => {
      this.#wallets = wallets.get();
    });
    wallets.on('unregister', () => {
      this.#wallets = wallets.get();
    });
  }

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

🤖 Prompt for AI Agents
In packages/shared/src/internal/clerk-js/injectedWeb3SolanaProviders.ts around
lines 39 to 43, calling this.#initialize() on every get() re-registers event
listeners and leaks memory; change initialization to run only once by adding an
initialized guard (e.g., a private boolean like #initialized) and have
#initialize() set that flag after registering listeners, then early-return if
already initialized; ensure any listener registration remains inside
#initialize() and do not call it from get() more than when the guard is false.

width: '100%',
}}
>
{value[0].toUpperCase()}
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 | 🔴 Critical

Add safety check for empty value.

Line 39 accesses value[0] without checking if the string is non-empty. If an empty string is passed, this will result in undefined.toUpperCase(), causing a runtime error.

Apply this diff to add a safety check:

-        {value[0].toUpperCase()}
+        {value[0]?.toUpperCase() ?? ''}

Or add a runtime check at the component level:

 export const WalletInitialIcon = (props: WalletInitialIconProps) => {
   const { value, id, ...rest } = props;
+
+  if (!value) {
+    return null;
+  }

   return (
📝 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
{value[0].toUpperCase()}
{value[0]?.toUpperCase() ?? ''}
🤖 Prompt for AI Agents
In packages/ui/src/common/WalletInitialIcon.tsx around line 39, the component
directly calls value[0].toUpperCase() which will throw if value is an empty
string or undefined; add a runtime guard to ensure value is a non-empty string
before accessing index 0 (e.g., compute an initial like const initial = value &&
value.length ? value[0].toUpperCase() : fallback and render that), or
validate/normalize the prop earlier so the rendered expression never calls
toUpperCase on undefined/empty.

Comment on lines +31 to +90
return (
<Flow.Part part='chooseWallet'>
<Card.Root>
<Card.Content>
<Header.Root showLogo>
<Header.Title localizationKey={localizationKeys('signIn.web3Solana.title')} />
<Header.Subtitle localizationKey={localizationKeys('signIn.web3Solana.subtitle')} />
</Header.Root>
<Card.Alert>{card.error}</Card.Alert>
<Flex
direction='col'
gap={4}
>
<Suspense
fallback={
<Flex
direction={'row'}
align={'center'}
justify={'center'}
sx={t => ({
height: '100%',
minHeight: t.sizes.$32,
})}
>
<Spinner
size={'lg'}
colorScheme={'primary'}
elementDescriptor={descriptors.spinner}
/>
</Flex>
}
>
<Web3SolanaWalletButtons
web3AuthCallback={({ walletName }) => {
return clerk
.authenticateWithWeb3({
customNavigate: router.navigate,
redirectUrl: ctx.afterSignInUrl || '/',
secondFactorUrl: 'factor-two',
signUpContinueUrl: ctx.isCombinedFlow ? '../create/continue' : ctx.signUpContinueUrl,
strategy: 'web3_solana_signature',
walletName,
})
.catch(err => web3CallbackErrorHandler(err, card.setError));
}}
/>
</Suspense>

<BackLink
boxElementDescriptor={descriptors.backRow}
linkElementDescriptor={descriptors.backLink}
onClick={onBackLinkClick}
/>
</Flex>
</Card.Content>
<Card.Footer />
</Card.Root>
</Flow.Part>
);
};
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n --type=ts --type=tsx "authenticateWithWeb3\(" -C4 packages/ui/src

Repository: clerk/javascript

Length of output: 87


🏁 Script executed:

rg -n --type=ts --type=tsx "secondFactorUrl\s*:" -C3 packages/ui/src

Repository: clerk/javascript

Length of output: 87


🏁 Script executed:

rg -n --type=ts --type=tsx "signUpContinueUrl\s*:" -C3 packages/ui/src

Repository: clerk/javascript

Length of output: 87


🏁 Script executed:

rg -n "authenticateWithWeb3\(" -g "*.ts" -g "*.tsx" -C4 packages/ui/src | head -300

Repository: clerk/javascript

Length of output: 3976


🏁 Script executed:

rg -n "secondFactorUrl\s*:" -g "*.ts" -g "*.tsx" -C3 packages/ui/src

Repository: clerk/javascript

Length of output: 2254


🏁 Script executed:

rg -n "signUpContinueUrl\s*:" -g "*.ts" -g "*.tsx" -C3 packages/ui/src

Repository: clerk/javascript

Length of output: 3795


🏁 Script executed:

fd -t f "SignInSocialButtons.tsx|SignInFactorOneSolanaWalletsCard.tsx" packages/ui/src

Repository: clerk/javascript

Length of output: 188


🏁 Script executed:

rg -n "router.navigate|navigate\(" -g "*.tsx" packages/ui/src/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx -C2

Repository: clerk/javascript

Length of output: 411


🏁 Script executed:

rg -n "create/continue|../create/continue" -g "*.ts" -g "*.tsx" packages/ui/src

Repository: clerk/javascript

Length of output: 397


🏁 Script executed:

rg -n "signUpContinueUrl\s*:" -g "*.tsx" packages/ui/src/components/SignIn -B2 -A2

Repository: clerk/javascript

Length of output: 1295


🏁 Script executed:

rg -n "Flow.Part.*SignIn\|Flow.Part.*chooseWallet" -g "*.tsx" packages/ui/src/components/SignIn

Repository: clerk/javascript

Length of output: 42


Fix inconsistent signUpContinueUrl path in combined-flow condition: use 'create/continue' to match SignInSocialButtons.tsx.
SignInSocialButtons.tsx (same directory) uses 'create/continue' while this component uses '../create/continue' for the combined-flow override. Both components are siblings in the same routing context, so the relative path syntax should match. The extra ../ prefix will navigate to an incorrect step.
secondFactorUrl: 'factor-two' is consistent across both SignIn components and correct.

🤖 Prompt for AI Agents
In packages/ui/src/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx around
lines 31 to 90, the combined-flow override uses a relative path
'../create/continue' which is inconsistent with SignInSocialButtons.tsx and
causes navigation to the wrong step; change the signUpContinueUrl value from
'../create/continue' to 'create/continue' so it matches the sibling component
and stays within the same routing context.

Comment on lines +22 to +37
export const Web3SelectSolanaWalletScreen = ({ onConnect }: Web3SelectWalletProps) => {
const card = useCardState();
const { close } = useActionContext();

const onClick = async ({ walletName }: { walletName: string }) => {
card.setLoading(walletName);
try {
await onConnect({ strategy: 'web3_solana_signature', walletName });
card.setIdle();
} catch (err) {
card.setIdle();
console.error(err);
} finally {
close();
}
};
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 | 🟠 Major

Don’t silently close the screen on connect errors; surface a user-visible error (and consider staying open).
Right now failures only console.error(err) and then close() in finally, which can look like a no-op to the user and prevents retry. Prefer card.setError(...) (and only close on success).

   const onClick = async ({ walletName }: { walletName: string }) => {
     card.setLoading(walletName);
     try {
       await onConnect({ strategy: 'web3_solana_signature', walletName });
-      card.setIdle();
+      card.setIdle();
+      close();
     } catch (err) {
       card.setIdle();
-      console.error(err);
-    } finally {
-      close();
+      card.setError(err as unknown);
     }
   };
🤖 Prompt for AI Agents
In packages/ui/src/components/UserProfile/Web3SelectSolanaWalletScreen.tsx
around lines 22 to 37, the onClick handler currently logs errors and always
calls close() in finally which hides failures from the user and prevents retry;
change the flow so that on success you call close(), and on error you set a
visible error on the card (e.g., card.setError(message)) and return the screen
open for retry. Concretely: remove close() from the finally block, move close()
to the successful path after card.setIdle(), on catch call card.setIdle() then
card.setError(...) with a user-friendly message (and optionally log the raw
error to console for debugging), and do not close the modal on error so users
can retry.

Comment on lines +66 to +75
<FormButtonContainer>
<Button
variant='ghost'
onClick={() => {
close();
}}
localizationKey={localizationKeys('userProfile.formButtonReset')}
elementDescriptor={descriptors.formButtonReset}
/>
</FormButtonContainer>
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 | 🟠 Major

Set reset button type="button" to avoid accidental form submit.
If Button renders a native <button> without an explicit type, HTML defaults to submit, which can trigger unintended submit behavior inside Form.Root.

           <Button
             variant='ghost'
+            type="button"
             onClick={() => {
               close();
             }}
             localizationKey={localizationKeys('userProfile.formButtonReset')}
             elementDescriptor={descriptors.formButtonReset}
           />
📝 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
<FormButtonContainer>
<Button
variant='ghost'
onClick={() => {
close();
}}
localizationKey={localizationKeys('userProfile.formButtonReset')}
elementDescriptor={descriptors.formButtonReset}
/>
</FormButtonContainer>
<FormButtonContainer>
<Button
variant='ghost'
type="button"
onClick={() => {
close();
}}
localizationKey={localizationKeys('userProfile.formButtonReset')}
elementDescriptor={descriptors.formButtonReset}
/>
</FormButtonContainer>
🤖 Prompt for AI Agents
In packages/ui/src/components/UserProfile/Web3SelectSolanaWalletScreen.tsx
around lines 66 to 75, the reset Button currently may render a native <button>
without an explicit type so it defaults to submit inside Form.Root; update the
Button invocation to include type="button" (pass the prop through the Button
component) so clicking it does not trigger form submission; ensure the Button
component accepts and forwards the type prop to the underlying element.

Comment on lines +174 to +193
const WalletButtonIcon = forwardRef((props: WalletButtonProps, ref: Ref<HTMLButtonElement> | null): JSX.Element => {
const { icon, label, id, ...rest } = props;

return (
<Button
ref={ref}
textVariant='buttonLarge'
variant='outline'
colorScheme='neutral'
hoverAsFocus
sx={t => ({
minHeight: t.sizes.$8,
width: '100%',
})}
{...rest}
>
{icon}
</Button>
);
});
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 | 🟠 Major

Add an explicit accessible name for icon-only wallet buttons.
Relying on child image alt / initials is brittle; set aria-label on the button so SR users consistently get “Connect with X”.

 const WalletButtonIcon = forwardRef((props: WalletButtonProps, ref: Ref<HTMLButtonElement> | null): JSX.Element => {
   const { icon, label, id, ...rest } = props;

   return (
     <Button
       ref={ref}
+      aria-label={label}
       textVariant='buttonLarge'
       variant='outline'
       colorScheme='neutral'
       hoverAsFocus
       sx={t => ({
         minHeight: t.sizes.$8,
         width: '100%',
       })}
       {...rest}
     >
       {icon}
     </Button>
   );
 });

Also applies to: 127-160

🤖 Prompt for AI Agents
In packages/ui/src/elements/Web3SolanaWalletButtons.tsx around lines 174 to 193
(and also apply same change to lines 127-160), the WalletButtonIcon component
renders an icon-only button without an explicit accessible name; add an
aria-label to the Button using the provided label (or fallback to id) so screen
readers get a consistent phrase like "Connect with X" — e.g. set
aria-label={`Connect with ${label ?? id}`} on the Button and pass no other
changes.

Comment on lines +265 to +279
export const Web3SolanaWalletButtons = (props: Web3WalletButtonsProps) => {
const network = MAINNET_ENDPOINT;
const wallets = useMemo(() => [], [network]);
return (
<ConnectionProvider endpoint={network}>
<WalletProvider
wallets={wallets}
onError={err => {
console.error(err);
}}
>
<Web3SolanaWalletButtonsInner web3AuthCallback={props.web3AuthCallback} />
</WalletProvider>
</ConnectionProvider>
);
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

find . -type f -name "package.json" | grep -E "packages/ui|package\.json$" | head -20

Repository: clerk/javascript

Length of output: 176


🏁 Script executed:

cat packages/ui/package.json | grep -A 5 -B 5 "wallet-adapter"

Repository: clerk/javascript

Length of output: 524


🏁 Script executed:

rg "WalletProvider|useMemo.*\[\].*network" packages/ui/src --type tsx -B 3 -A 3

Repository: clerk/javascript

Length of output: 87


🏁 Script executed:

rg "@solana/wallet-adapter" packages/ui/src --type tsx

Repository: clerk/javascript

Length of output: 87


🏁 Script executed:

rg "WalletProvider|useMemo.*\[\]" packages/ui/src -B 3 -A 3

Repository: clerk/javascript

Length of output: 4915


🏁 Script executed:

cat packages/ui/src/elements/Web3SolanaWalletButtons.tsx

Repository: clerk/javascript

Length of output: 8457


🏁 Script executed:

find . -name "pnpm-lock.yaml" -o -name "yarn.lock" -o -name "package-lock.json" | head -1

Repository: clerk/javascript

Length of output: 136


🏁 Script executed:

rg "wallet-adapter-react" . --type json | head -20

Repository: clerk/javascript

Length of output: 336


🏁 Script executed:

head -100 pnpm-lock.yaml | grep -A 10 "wallet-adapter-react"

Repository: clerk/javascript

Length of output: 337


🏁 Script executed:

rg "wallet-adapter|Wallet.*Adapter" packages/ui/src --no-heading | grep -i import | head -20

Repository: clerk/javascript

Length of output: 323


🏁 Script executed:

rg "Web3SolanaWalletButtons" . --no-heading | grep -v "node_modules" | head -20

Repository: clerk/javascript

Length of output: 2055


🏁 Script executed:

rg "WalletProvider" . --no-heading -B 5 -A 5 | grep -v "node_modules" | head -40

Repository: clerk/javascript

Length of output: 2194


WalletProvider receives an empty wallets array, causing the component to always display the "none available" message.

The useWallet() hook in Web3SolanaWalletButtonsInner relies on wallets passed to WalletProvider. With wallets={useMemo(() => [], [network])}, the hook will always return an empty list, triggering the fallback UI regardless of which wallets are installed on the user's system. No wallet adapter instances are provided or imported anywhere in the file.

To fix: instantiate and pass wallet adapters (e.g., PhantomWalletAdapter) to the wallets prop, or provide a wallet-standard adapter that discovers installed wallets. Ensure adapters are tree-shaking friendly by importing them from a central module.

🤖 Prompt for AI Agents
In packages/ui/src/elements/Web3SolanaWalletButtons.tsx around lines 265 to 279,
the WalletProvider is given an empty wallets array so useWallet() in the inner
component always finds no adapters; replace the useMemo(() => [], [network])
with a useMemo that instantiates and returns the appropriate wallet adapter
instances (e.g., PhantomWalletAdapter and any others you support) configured for
the network, and import those adapter constructors from the central adapters
module so they are tree-shakable; pass that memoized array to WalletProvider and
keep onError as-is.

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

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (5)
packages/shared/src/types/signInFuture.ts (1)

243-256: All 16 .web3() call sites in tests are missing the required provider parameter and will fail TypeScript compilation.

The SignInFutureWeb3Params interface requires provider: Web3Provider as a mandatory field, but the implementation derives the provider from the strategy parameter and never uses the passed-in provider. All test call sites only pass strategy (e.g., .web3({ strategy: 'web3_metamask_signature' })), which violates the type signature. With strict: true enabled in tsconfig, these tests will fail to compile.

Either provider should be removed from the required parameters and derived entirely from strategy, or marked as optional with a default value. The current type definition does not match the implementation's contract.

packages/shared/src/types/clerk.ts (1)

2251-2259: Add JSDoc to clarify that walletName is required for Solana, or use a discriminated union to enforce at the type level.

Currently, ClerkAuthenticateWithWeb3Params allows callers to pass strategy: 'web3_solana_signature' without providing walletName, yet the runtime code throws an error in this case. Either document this constraint clearly in JSDoc, or better yet, use a discriminated union keyed by strategy to enforce walletName as required when strategy is Solana (matching the pattern used in SignUpAuthenticateWithSolanaParams and SignInAuthenticateWithSolanaParams, where walletName is already required).

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

260-309: Add walletName validation for Solana strategy.

The authenticateWithWeb3 method is missing validation to ensure walletName is provided when the strategy is 'web3_solana_signature'. This validation exists in SignIn.ts (lines 376-378) but is absent here, creating inconsistency and allowing late-stage failures.

Add the validation after Line 278:

   if (!(typeof generateSignature === 'function')) {
     clerkMissingOptionError('generateSignature');
   }
+
+  if (provider === 'solana' && !walletName) {
+    clerkMissingOptionError('walletName');
+  }

   // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
   const web3Wallet = identifier || this.web3wallet!;

311-359: Address signature inconsistency across wallet authentication methods.

Lines 327, 339, and 350 update authenticateWithCoinbaseWallet, authenticateWithBase, and authenticateWithOKXWallet to accept SignUpAuthenticateWithWeb3Params, but authenticateWithMetamask (lines 311-324) retains an inline type with explicit legalAccepted field. This creates an inconsistency in the public API.

Normalize authenticateWithMetamask to match the other methods:

- public authenticateWithMetamask = async (
-   params?: SignUpAuthenticateWithWeb3Params & {
-     legalAccepted?: boolean;
-   },
- ): Promise<SignUpResource> => {
+ public authenticateWithMetamask = async (params?: SignUpAuthenticateWithWeb3Params): Promise<SignUpResource> => {

874-938: Critical: Missing Solana case in SignUpFuture.web3.

The SignUpFuture.web3 method lacks a 'solana' case in the provider switch statement (lines 881-900), causing any Solana authentication attempt via the Future API to throw "Unsupported Web3 provider: solana". This is inconsistent with SignInFuture.web3 in SignIn.ts (lines 999-1008), which correctly implements Solana support.

Add the Solana case after the okx_wallet case:

       case 'okx_wallet':
         identifier = await web3().getOKXWalletIdentifier();
         generateSignature = web3().generateSignatureWithOKXWallet;
         break;
+      case 'solana':
+        if (!params.walletName) {
+          throw new ClerkRuntimeError('Wallet name is required for Solana authentication.', {
+            code: 'web3_solana_wallet_name_required',
+          });
+        }
+        identifier = await web3().getSolanaIdentifier(params.walletName);
+        generateSignature = p =>
+          web3().generateSignatureWithSolana({ ...p, walletName: params.walletName as string });
+        break;
       default:
         throw new Error(`Unsupported Web3 provider: ${provider}`);

Additionally, update the retry logic to preserve walletName if present:

       } catch (err) {
         // ... comment ...
         if (provider === 'coinbase_wallet' && err.code === 4001) {
-          signature = await generateSignature({ identifier, nonce: message });
+          signature = await generateSignature({ identifier, nonce: message, walletName: params?.walletName });
         } else {
           throw err;
         }
♻️ Duplicate comments (6)
.changeset/legal-jokes-beg.md (1)

1-9: Past review comment still applies.

The incorrect package names (@clerk/clerk-react and @clerk/elements) have already been flagged in a previous review. Please update to @clerk/react and @clerk/ui respectively.

packages/ui/src/components/UserProfile/Web3SelectSolanaWalletScreen.tsx (2)

26-37: Past review comment still applies: Error handling needs improvement.

The close() call in the finally block (line 35) means the screen closes on both success and error, hiding failures from the user and preventing retry. This issue was already flagged in a previous review.


66-75: Past review comment still applies: Button needs explicit type.

The reset Button should include type="button" to prevent accidental form submission when inside Form.Root. This issue was already flagged in a previous review.

packages/ui/src/elements/Web3SolanaWalletButtons.tsx (2)

174-193: Icon-only wallet buttons need an explicit accessible name (aria-label).


265-279: WalletProvider with wallets=[] makes “no wallets available” the only possible outcome.

You’ll need to pass actual adapter instances (or a wallet-standard discovery adapter) instead of an empty array, and confirm the correct adapter packages/versions for this repo.

packages/shared/src/internal/clerk-js/injectedWeb3SolanaProviders.ts (1)

39-43: Memory leak from repeated initialization.

The #initialize() method is called on every get() invocation, which re-registers event listeners without cleanup. This will accumulate listeners over time.

Add an initialization guard:

+ #initialized = false;
+
  async #initialize() {
+   if (this.#initialized) {
+     return;
+   }
+   this.#initialized = true;
    const wallets = await import('@wallet-standard/core').then(mod => mod.getWallets());
    // ...
  }
🟡 Minor comments (20)
packages/localizations/src/id-ID.ts-1365-1370 (1)

1365-1370: Localize the link label text (“wallet extension”) to Indonesian. The surrounding sentence is Indonesian but the link label is English.

 web3SolanaWalletButtons: {
   connect: 'Hubungkan dengan {{walletName}}',
   continue: 'Lanjutkan dengan {{walletName}}',
   noneAvailable:
-    'Tidak ada dompet Solana Web3 yang terdeteksi. Silakan instal {{ solanaWalletsLink || link("wallet extension") }} yang mendukung Web3.',
+    'Tidak ada dompet Solana Web3 yang terdeteksi. Silakan instal {{ solanaWalletsLink || link("ekstensi dompet") }} yang mendukung Web3.',
 },
packages/localizations/src/hr-HR.ts-1372-1377 (1)

1372-1377: Fix Croatian grammar + consider translating the link label in noneAvailable.
Current: “Nisu otkrivene Solana Web3 novčanike …” mixes gender/case. Suggested: “Nisu otkriveni Solana Web3 novčanici …”. Also consider translating link("wallet extension") (e.g., “proširenje novčanika”) if other locales localize that label.

   web3SolanaWalletButtons: {
     connect: 'Poveži se s {{walletName}}',
     continue: 'Nastavi s {{walletName}}',
     noneAvailable:
-      'Nisu otkrivene Solana Web3 novčanike. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
+      'Nisu otkriveni Solana Web3 novčanici. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
   },
packages/localizations/src/ms-MY.ts-757-760 (1)

757-760: Prefer consistent “daftar masuk” phrasing (vs “log masuk”) in Solana sign-in copy.
Elsewhere in this file you consistently use “Daftar masuk”, so “log masuk” may read inconsistent in the same flow.

   web3Solana: {
-    subtitle: 'Pilih dompet di bawah untuk log masuk',
-    title: 'Log masuk dengan Solana',
+    subtitle: 'Pilih dompet di bawah untuk daftar masuk',
+    title: 'Daftar masuk dengan Solana',
   },
packages/localizations/src/ms-MY.ts-1385-1390 (1)

1385-1390: Localize the default link label (“wallet extension”) in the “noneAvailable” message.
If solanaWalletsLink isn’t provided, users will see the English fallback text.

   noneAvailable:
-    'Tiada dompet Solana Web3 dikesan. Sila pasang {{ solanaWalletsLink || link("wallet extension") }} yang menyokong Web3.',
+    'Tiada dompet Solana Web3 dikesan. Sila pasang {{ solanaWalletsLink || link("sambungan dompet") }} yang menyokong Web3.',
packages/localizations/src/nl-NL.ts-1365-1370 (1)

1365-1370: Translate fallback link text to Dutch for consistency.

The noneAvailable message on line 1369 contains English text "wallet extension" within the link fallback. For consistency with the Dutch locale and the pattern used elsewhere in this file (e.g., line 808), this should be translated to Dutch.

Apply this diff to translate the fallback text:

     noneAvailable:
-      'Geen Solana Web3-wallets gedetecteerd. Installeer een Web3-ondersteunde {{ solanaWalletsLink || link("wallet extension") }}.',
+      'Geen Solana Web3-wallets gedetecteerd. Installeer een Web3-ondersteunde {{ solanaWalletsLink || link("wallet-extensie") }}.',
packages/localizations/src/es-UY.ts-1341-1344 (1)

1341-1344: Use vos conjugation and consistent wallet terminology.

This is directly inconsistent with line 1359 in the same web3WalletsSection, which correctly uses "Seleccioná una cartera Web3".

Apply this diff:

         web3SelectSolanaWalletScreen: {
-          subtitle: 'Selecciona una billetera de Solana para conectarla a tu cuenta.',
-          title: 'Agregar una billetera de Solana',
+          subtitle: 'Seleccioná una cartera de Solana para conectarla a tu cuenta.',
+          title: 'Agregar una cartera de Solana',
         },
packages/localizations/src/es-UY.ts-854-857 (1)

854-857: Use vos conjugation and consistent wallet terminology.

Same inconsistency as the sign-in flow: should use vos form "Seleccioná" and "cartera" to match the established locale conventions.

Apply this diff:

     web3Solana: {
-      subtitle: 'Selecciona una billetera abajo para registrarte',
+      subtitle: 'Seleccioná una cartera abajo para registrarte',
       title: 'Registrarse con Solana',
     },
packages/localizations/src/es-UY.ts-1380-1385 (1)

1380-1385: Use consistent wallet terminology.

The noneAvailable message uses "billeteras" but should use "carteras" to match the existing Web3 wallet terminology in this locale.

Apply this diff:

   web3SolanaWalletButtons: {
     connect: 'Conectar con {{walletName}}',
     continue: 'Continuar con {{walletName}}',
     noneAvailable:
-      'No se detectaron billeteras Web3 de Solana. Instala una {{ solanaWalletsLink || link("wallet extension") }} compatible con Web3.',
+      'No se detectaron carteras Web3 de Solana. Instala una {{ solanaWalletsLink || link("wallet extension") }} compatible con Web3.',
   },
packages/localizations/src/es-UY.ts-968-970 (1)

968-970: Use vos conjugation for imperative forms.

The imperative "Inténtalo" is tú form. In Uruguayan Spanish (vos), it should be "Intentalo" without the accent.

Apply this diff:

-    web3_signature_request_rejected: 'Has rechazado la solicitud de firma. Inténtalo de nuevo para continuar.',
+    web3_signature_request_rejected: 'Has rechazado la solicitud de firma. Intentalo de nuevo para continuar.',
     web3_solana_signature_generation_failed:
-      'Se produjo un error al generar la firma. Inténtalo de nuevo para continuar.',
+      'Se produjo un error al generar la firma. Intentalo de nuevo para continuar.',
packages/localizations/src/es-UY.ts-756-759 (1)

756-759: Use vos conjugation and consistent wallet terminology.

The es-UY locale uses vos conjugation throughout (e.g., "Seleccioná" on line 1167), but these new additions use tú form. Additionally, existing Web3 wallet translations use "cartera" (lines 1337-1340), not "billetera".

Apply this diff for consistency:

     web3Solana: {
-      subtitle: 'Selecciona una billetera abajo para iniciar sesión',
+      subtitle: 'Seleccioná una cartera abajo para iniciar sesión',
       title: 'Iniciar sesión con Solana',
     },
packages/localizations/src/hi-IN.ts-1378-1383 (1)

1378-1383: Localize the remaining English fragment (“wallet extension”) for hi-IN.

Suggested tweak:

   noneAvailable:
-      'कोई Solana Web3 वॉलेट नहीं मिला। कृपया Web3 समर्थित {{ solanaWalletsLink || link("wallet extension") }} इंस्टॉल करें।',
+      'कोई Solana Web3 वॉलेट नहीं मिला। कृपया Web3 समर्थित {{ solanaWalletsLink || link("वॉलेट एक्सटेंशन") }} इंस्टॉल करें।',
packages/shared/src/types/clerk.ts-916-920 (1)

916-920: Add full JSDoc for this new public API (param details + expected walletName).
Current comment doesn’t document required inputs / behavior.

   /**
    * Authenticates user using their Solana supported Web3 wallet browser extension
+   *
+   * @param params - Configuration options for the Solana authentication flow.
+   * @returns A promise that resolves when the authentication flow completes.
    */
   authenticateWithSolana: (params: AuthenticateWithSolanaParams) => Promise<unknown>;
packages/ui/src/elements/Web3SolanaWalletButtons.tsx-28-30 (1)

28-30: Public export needs JSDoc + explicit return type (and keep the prop type stable). This is a new exported UI API in packages/**/src/**/*.tsx.

 type Web3WalletButtonsProps = {
   web3AuthCallback: ({ walletName }: { walletName: string }) => Promise<unknown>;
 };

+/**
+ * Renders installed Solana wallets and invokes `web3AuthCallback` with the selected wallet name.
+ */
-export const Web3SolanaWalletButtons = (props: Web3WalletButtonsProps) => {
+export const Web3SolanaWalletButtons = (props: Web3WalletButtonsProps): JSX.Element => {
   const network = MAINNET_ENDPOINT;
   const wallets = useMemo(() => [], [network]);
   return (
     <ConnectionProvider endpoint={network}>
       <WalletProvider
         wallets={wallets}
         onError={err => {
           console.error(err);
         }}
       >
         <Web3SolanaWalletButtonsInner web3AuthCallback={props.web3AuthCallback} />
       </WalletProvider>
     </ConnectionProvider>
   );
 };

Also applies to: 265-280

packages/localizations/src/fr-FR.ts-1391-1396 (1)

1391-1396: Localize the fallback link label (“wallet extension”). The surrounding sentence is French; the link text should be too.

   web3SolanaWalletButtons: {
     connect: 'Se connecter avec {{walletName}}',
     continue: 'Continuer avec {{walletName}}',
     noneAvailable:
-      'Aucun portefeuille Solana Web3 détecté. Veuillez installer une {{ solanaWalletsLink || link("wallet extension") }} compatible Web3.',
+      'Aucun portefeuille Solana Web3 détecté. Veuillez installer une {{ solanaWalletsLink || link("extension de portefeuille") }} compatible Web3.',
   },
packages/ui/src/elements/Web3SolanaWalletButtons.tsx-195-263 (1)

195-263: id is dropped in both button variants; forward it (or remove it). Currently id is destructured and never applied, so passing id={w.name} has no effect.

 const WalletButtonIcon = forwardRef((props: WalletButtonProps, ref: Ref<HTMLButtonElement> | null): JSX.Element => {
   const { icon, label, id, ...rest } = props;

   return (
     <Button
       ref={ref}
+      id={id}
       textVariant='buttonLarge'
       variant='outline'
       colorScheme='neutral'
       hoverAsFocus
       sx={t => ({
         minHeight: t.sizes.$8,
         width: '100%',
       })}
       {...rest}
     >
       {icon}
     </Button>
   );
 });

 const WalletButtonBlock = forwardRef((props: WalletButtonProps, ref: Ref<HTMLButtonElement> | null): JSX.Element => {
   const { id, icon, isLoading, label, ...rest } = props;
   const isIconElement = isValidElement(icon);

   return (
     <SimpleButton
+      id={id}
       variant='outline'
       block
       isLoading={isLoading}
       hoverAsFocus
       ref={ref}
       {...rest}
       sx={theme => [
         {
           gap: theme.space.$4,
           position: 'relative',
           justifyContent: 'flex-start',
         },
         props.sx,
       ]}
     >
packages/localizations/src/sr-RS.ts-1364-1369 (1)

1364-1369: Localize the fallback link label ("wallet extension") to Serbian.

The string passed to link() is currently English but should be translated to Serbian to match the surrounding text. The suggested translation is appropriate.

   web3SolanaWalletButtons: {
     connect: 'Poveži se sa {{walletName}}',
     continue: 'Nastavi sa {{walletName}}',
     noneAvailable:
-      'Nisu detektovani Solana Web3 novčanici. Instaliraj {{ solanaWalletsLink || link("wallet extension") }} koji podržava Web3.',
+      'Nisu detektovani Solana Web3 novčanici. Instaliraj {{ solanaWalletsLink || link("ekstenziju novčanika") }} koji podržava Web3.',
   },
packages/localizations/src/vi-VN.ts-1374-1379 (1)

1374-1379: Localize the fallback link label in the Solana wallet buttons message. The fallback text "wallet extension" should be translated to Vietnamese to match the localization pattern used elsewhere in the file (e.g., "Chính sách bảo mật", "Điều khoản dịch vụ").

Suggested fix:

   web3SolanaWalletButtons: {
     connect: 'Kết nối với {{walletName}}',
     continue: 'Tiếp tục với {{walletName}}',
     noneAvailable:
-      'Không phát hiện ví Solana Web3 nào. Vui lòng cài đặt {{ solanaWalletsLink || link("wallet extension") }} hỗ trợ Web3.',
+      'Không phát hiện ví Solana Web3 nào. Vui lòng cài đặt {{ solanaWalletsLink || link("phần mở rộng ví") }} hỗ trợ Web3.',
   },
packages/localizations/src/mn-MN.ts-1368-1373 (1)

1368-1373: All localization files have an English fallback in the Solana Web3 wallet message. The pattern {{ solanaWalletsLink || link("wallet extension") }} appears identically in all 40+ language files. While solanaWalletsLink is always provided in the actual implementation (Web3SolanaWalletButtons.tsx passes 'https://solana.com/solana-wallets'), the fallback text "wallet extension" would render literally if the parameter were ever missing, creating an English UI text in non-English locales. This should be addressed systematically across all language files, not just mn-MN—for instance, a Mongolian translation like "түрийвчийн өргөтгөл" or "таалай өргөтгөл" would be more appropriate.

packages/shared/src/internal/clerk-js/injectedWeb3SolanaProviders.ts-54-60 (1)

54-60: Fallback provider type assertion may not match SolanaWalletAdapterWallet interface.

The window.solana fallback is cast to SolanaWalletAdapterWallet, but the global window.solana provider (e.g., Phantom's legacy API) may not conform to the Wallet Standard interface. This could cause runtime errors when accessing features[StandardConnect] or features[SolanaSignMessage] in the calling code.

Consider returning a more specific type or documenting that the fallback provider may have a different API:

- if (
-   fallbackProvider &&
-   typeof fallbackProvider.connect === 'function' &&
-   typeof fallbackProvider.signMessage === 'function'
- ) {
-   return fallbackProvider as SolanaWalletAdapterWallet;
- }
+ // Note: Legacy providers may not fully implement SolanaWalletAdapterWallet
+ // The caller should handle potential API differences
+ if (
+   fallbackProvider &&
+   typeof fallbackProvider.connect === 'function' &&
+   typeof fallbackProvider.signMessage === 'function'
+ ) {
+   return fallbackProvider as SolanaWalletAdapterWallet;
+ }
packages/shared/src/internal/clerk-js/web3.ts-184-190 (1)

184-190: Potential control flow issue after errorThrower.throw().

The errorThrower.throw() call on line 186 is followed by return; on line 187, but errorThrower.throw() should already throw an exception. If errorThrower.throw() doesn't actually throw (e.g., in certain build configurations), the function would return undefined which could cause issues downstream.

Consider restructuring to ensure the throw is explicit:

  if (provider === 'solana') {
    if (!walletName || walletName.length === 0) {
-     errorThrower.throw('Wallet name must be provided to get Solana wallet provider');
-     return;
+     throw errorThrower.throw('Wallet name must be provided to get Solana wallet provider');
    }
    return await getInjectedWeb3SolanaProviders().get(walletName);
  }

Or verify that errorThrower.throw() always throws and remove the unreachable return;.

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

🧹 Nitpick comments (20)
packages/localizations/src/zh-TW.ts (2)

937-938: New web3 error strings are clear; consider slightly more user-actionable wording.
Current messages are fine; optional tweak would be adding a hint like “確認錢包已解鎖/已連線” for the signature-generation failure if that matches product tone.


1330-1335: Localize the fallback link label (“wallet extension”) to avoid mixed-language UI.
link("wallet extension") will likely render English in a zh-TW sentence; suggest a zh-TW label (e.g., link("錢包擴充功能") or link("錢包擴充套件")) unless there’s a product requirement to keep this specific label in English.

packages/ui/src/utils/web3CallbackErrorHandler.ts (1)

6-8: Good hardening with optional chaining; consider removing any to preserve type-safety

The optional chaining on err.errors?.[0] (Line 13-14) is a solid robustness improvement (avoids crashes on missing/empty errors). Since this is a public exported utility, I’d also tighten err: any to err: unknown so isClerkAPIResponseError(err) actually provides meaningful narrowing.

 type Web3CallbackErrorHandler = {
-  (err: any, setError?: (err: ClerkRuntimeErrorType | ClerkAPIError | string | undefined) => void): void;
+  (err: unknown, setError?: (err: ClerkRuntimeErrorType | ClerkAPIError | string | undefined) => void): void;
 };

Also applies to: 10-22

packages/localizations/src/fa-IR.ts (3)

761-764: Consider localizing “Solana” consistently with Persian copy (or confirm brand-style choice).
Strings are clear, but mixing Persian with Latin “Solana” can be stylistically inconsistent across fa-IR; consider “سولانا” if that’s the convention elsewhere.


858-861: Keep sign-up wording aligned with sign-in wording (terminology + punctuation).
Same comment as sign-in: if you decide on “Solana” vs “سولانا”, apply consistently across both flows.


1375-1380: Potential template-token + localization issue in noneAvailable (whitespace + English fallback label).

  • You use {{ solanaWalletsLink || link("wallet extension") }} (extra spaces inside {{ ... }}) whereas other strings use {{privacyPolicyLink || link("...")}}; if the templating engine is strict, keep formatting consistent.
  • The fallback label "wallet extension" is English in an fa-IR string; consider a Persian label if that’s expected for this locale.

Proposed tweak:

-      'هیچ کیف پول Solana Web3 شناسایی نشد. لطفاً یک {{ solanaWalletsLink || link("wallet extension") }} پشتیبانی‌شده از Web3 نصب کنید.',
+      'هیچ کیف پول Solana Web3 شناسایی نشد. لطفاً یک {{solanaWalletsLink || link("افزونهٔ کیف پول")}} پشتیبانی‌شده از Web3 نصب کنید.',
packages/localizations/src/ru-RU.ts (1)

1350-1353: Minor terminology inconsistency.

The subtitle uses "аккаунту" while the rest of the file predominantly uses "учетная запись" for "account" (e.g., lines 585, 1017, 1119). Consider aligning for consistency:

 web3SelectSolanaWalletScreen: {
-  subtitle: 'Выберите кошелёк Solana для подключения к вашему аккаунту.',
+  subtitle: 'Выберите кошелёк Solana для подключения к вашей учетной записи.',
   title: 'Добавить кошелёк Solana',
 },
packages/clerk-js/rspack.config.js (1)

126-139: Consider maintenance burden of hardcoded Solana dependency list.

The explicit exclusion list for Solana packages and their transitive dependencies (bn.js, borsh, buffer, superstruct, bs58, jayson, rpc-websockets, qrcode) may become stale if Solana wallet adapter dependencies change. Consider:

  1. Adding a comment explaining why these specific packages are excluded
  2. Documenting the source of this dependency list (e.g., "transitive deps of @solana/wallet-adapter-* as of v1.x")

This will help future maintainers understand when/if the list needs updating.

packages/shared/src/types/signInCommon.ts (1)

195-198: Add JSDoc + clarify walletName expectations for this new public type.
Since this is a new exported/public surface, please document what walletName should match (e.g., display name vs adapter name) and any validation expectations.

packages/shared/src/types/factors.ts (1)

41-46: Document/guard walletName usage (likely Solana-only).
Consider adding a short comment/JSDoc on Line 45 that walletName is used for Solana flows (and ignored otherwise), and ensure downstream code doesn’t treat it as trusted input without validation.

packages/shared/src/types/web3Wallet.ts (1)

30-42: Consider a discriminated union to enforce “walletName required for Solana”.
Right now walletName is optional even when provider is 'solana', which pushes errors to runtime.

-export interface GenerateSignatureParams {
-  identifier: string;
-  nonce: string;
-  provider: Web3Provider;
-  walletName?: string;
-}
+export type GenerateSignatureParams =
+  | {
+      identifier: string;
+      nonce: string;
+      provider: 'solana';
+      walletName: string;
+    }
+  | {
+      identifier: string;
+      nonce: string;
+      provider: Exclude<Web3Provider, 'solana'>;
+      walletName?: never;
+    };
packages/shared/src/types/signInFuture.ts (1)

7-8: Good doc, but consider encoding “Solana requires walletName” in the type.
The comment on Lines 253-255 is helpful; a discriminated union would prevent invalid calls at compile-time.

Also applies to: 243-256

packages/localizations/src/ja-JP.ts (1)

1378-1383: Consider localizing the link("wallet extension") label to avoid mixed-language UI.
Right now the clickable label will render as “wallet extension” in Japanese.

   noneAvailable:
-      'Solana Web3 ウォレットが検出されませんでした。Web3 に対応した {{ solanaWalletsLink || link("wallet extension") }} をインストールしてください。',
+      'Solana Web3 ウォレットが検出されませんでした。Web3 に対応した {{ solanaWalletsLink || link("ウォレット拡張機能") }} をインストールしてください。',
packages/shared/src/types/clerk.ts (1)

2302-2309: AuthenticateWithSolanaParams looks good; consider documenting what walletName should match (UI label vs provider id).
This helps prevent callers passing display names that don’t map to injected providers.

packages/localizations/src/pl-PL.ts (3)

754-757: Polish grammar: consider “przez Solanę” (accusative) instead of “przez Solana”.

   web3Solana: {
     subtitle: 'Wybierz poniżej portfel, aby się zalogować',
-    title: 'Zaloguj się przez Solana',
+    title: 'Zaloguj się przez Solanę',
   },

852-855: Polish grammar: consider “przez Solanę” (accusative) instead of “przez Solana”.

   web3Solana: {
     subtitle: 'Wybierz poniżej portfel, aby się zarejestrować',
-    title: 'Zarejestruj się przez Solana',
+    title: 'Zarejestruj się przez Solanę',
   },

1376-1381: Consider translating the link("wallet extension") label to Polish to avoid mixed-language UI.

   noneAvailable:
-      'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("wallet extension") }} obsługujący Web3.',
+      'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("rozszerzenie portfela") }} obsługujące Web3.',
packages/localizations/src/en-US.ts (1)

1367-1372: Minor copy nit: consider “Web3-supported” for readability.

   noneAvailable:
-      'No Solana Web3 wallets detected. Please install a Web3 supported {{ solanaWalletsLink || link("wallet extension") }}.',
+      'No Solana Web3 wallets detected. Please install a Web3-supported {{ solanaWalletsLink || link("wallet extension") }}.',
packages/clerk-js/src/core/resources/SignIn.ts (1)

26-26: Consider using type-only imports for better tree-shaking.

The imported GenerateSignature and SignInAuthenticateWithSolanaParams are types and should use the import type syntax.

As per coding guidelines, use type-only imports for better tree-shaking.

Apply this diff:

   EmailLinkFactor,
   EnterpriseSSOConfig,
-  GenerateSignature,
+  type GenerateSignature,
   PassKeyConfig,
   ResetPasswordParams,
   ResetPasswordPhoneCodeFactorConfig,
-  SignInAuthenticateWithSolanaParams,
+  type SignInAuthenticateWithSolanaParams,
   SignInCreateParams,

Also applies to: 36-36

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

19-19: Consider using type-only import for better tree-shaking.

The imported SignUpAuthenticateWithSolanaParams is a type and should use the import type syntax.

As per coding guidelines, use type-only imports for better tree-shaking.

Apply this diff:

   PreparePhoneNumberVerificationParams,
   PrepareVerificationParams,
   PrepareWeb3WalletVerificationParams,
-  SignUpAuthenticateWithSolanaParams,
+  type SignUpAuthenticateWithSolanaParams,
   SignUpAuthenticateWithWeb3Params,

Comment on lines +454 to +462
public authenticateWithSolana = async (params: SignInAuthenticateWithSolanaParams): Promise<SignInResource> => {
const identifier = await web3().getSolanaIdentifier(params.walletName);
return this.authenticateWithWeb3({
identifier,
generateSignature: p => web3().generateSignatureWithSolana({ ...p, walletName: params.walletName }),
strategy: 'web3_solana_signature',
walletName: params.walletName,
});
};
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 | 🟠 Major

Add JSDoc documentation for the new public API.

The new authenticateWithSolana method is a public API and should include JSDoc comments explaining parameters, return value, and usage.

As per coding guidelines, all public APIs must be documented with JSDoc.

Add documentation like this:

+  /**
+   * Authenticates a user using a Solana Web3 wallet.
+   *
+   * @param params - Configuration for Solana authentication
+   * @param params.walletName - The name of the Solana wallet to use for authentication
+   * @returns A promise that resolves to the updated SignIn resource
+   * @throws {ClerkRuntimeError} If walletName is not provided or wallet connection fails
+   *
+   * @example
+   * ```typescript
+   * await signIn.authenticateWithSolana({ walletName: 'phantom' });
+   * ```
+   */
   public authenticateWithSolana = async (params: SignInAuthenticateWithSolanaParams): Promise<SignInResource> => {
🤖 Prompt for AI Agents
In packages/clerk-js/src/core/resources/SignIn.ts around lines 454 to 462, the
new public method authenticateWithSolana lacks JSDoc; add a JSDoc block
immediately above the method that documents the params
(SignInAuthenticateWithSolanaParams and walletName), the Promise<SignInResource>
return value, a short description of what the method does (authenticates using a
Solana wallet), and a usage example (e.g. await signIn.authenticateWithSolana({
walletName: 'phantom' })); keep tags @param and @returns and format the example
inside a code fence as in project guidelines.

Comment on lines +361 to +371
public authenticateWithSolana = async (params: SignUpAuthenticateWithSolanaParams): Promise<SignUpResource> => {
const identifier = await web3().getSolanaIdentifier(params.walletName);
return this.authenticateWithWeb3({
identifier,
generateSignature: p => web3().generateSignatureWithSolana({ ...p, walletName: params.walletName }),
unsafeMetadata: params?.unsafeMetadata,
strategy: 'web3_solana_signature',
legalAccepted: params?.legalAccepted,
walletName: params.walletName,
});
};
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 | 🟠 Major

Add JSDoc documentation for the new public API.

The new authenticateWithSolana method is a public API and should include JSDoc comments explaining parameters, return value, and usage.

As per coding guidelines, all public APIs must be documented with JSDoc.

Add documentation like this:

+  /**
+   * Authenticates a user using a Solana Web3 wallet during sign-up.
+   *
+   * @param params - Configuration for Solana authentication
+   * @param params.walletName - The name of the Solana wallet to use (e.g., 'phantom', 'solflare')
+   * @param params.unsafeMetadata - Optional unsafe metadata to attach to the user
+   * @param params.legalAccepted - Optional flag indicating legal terms acceptance
+   * @returns A promise that resolves to the updated SignUp resource
+   * @throws {ClerkRuntimeError} If wallet connection fails
+   *
+   * @example
+   * ```typescript
+   * await signUp.authenticateWithSolana({ 
+   *   walletName: 'phantom',
+   *   legalAccepted: true 
+   * });
+   * ```
+   */
   public authenticateWithSolana = async (params: SignUpAuthenticateWithSolanaParams): Promise<SignUpResource> => {
🤖 Prompt for AI Agents
In packages/clerk-js/src/core/resources/SignUp.ts around lines 361 to 371, the
new public method authenticateWithSolana is missing JSDoc; add a JSDoc block
immediately above the method that describes the method purpose, lists @param
entries for the SignUpAuthenticateWithSolanaParams fields (at least walletName,
legalAccepted, unsafeMetadata), specifies the @returns Promise<SignUpResource>,
and includes a short usage example showing await signUp.authenticateWithSolana({
walletName: 'phantom', legalAccepted: true });; ensure the JSDoc is properly
closed and formatted to satisfy the project's documentation standards.

Comment on lines +767 to +770
web3Solana: {
subtitle: 'Wähle unten eine Wallet aus, um dich anzumelden',
title: 'Mit Solana anmelden',
},
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 | 🟠 Major

Maintain consistent formal German ("Sie" form) throughout the localization file.

The new web3Solana strings use informal German ("du" form), while the entire file consistently uses formal German ("Sie" form). This creates an inconsistent user experience.

Apply this diff to use formal German:

     web3Solana: {
-      subtitle: 'Wähle unten eine Wallet aus, um dich anzumelden',
+      subtitle: 'Wählen Sie unten eine Wallet aus, um sich anzumelden',
       title: 'Mit Solana anmelden',
     },
📝 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
web3Solana: {
subtitle: 'Wähle unten eine Wallet aus, um dich anzumelden',
title: 'Mit Solana anmelden',
},
web3Solana: {
subtitle: 'Wählen Sie unten eine Wallet aus, um sich anzumelden',
title: 'Mit Solana anmelden',
},
🤖 Prompt for AI Agents
In packages/localizations/src/de-DE.ts around lines 767 to 770, the new
web3Solana strings use informal "du" wording while the file uses formal "Sie";
update the subtitle and title to formal German (use "Sie" and appropriate formal
phrasing), e.g. change "Wähle unten eine Wallet aus, um dich anzumelden" to a
formal variant and "Mit Solana anmelden" to a formal title, ensuring
capitalization and punctuation match existing entries and maintain the same key
names and surrounding structure.

Comment on lines +862 to +865
web3Solana: {
subtitle: 'Wähle unten eine Wallet aus, um dich zu registrieren',
title: 'Mit Solana registrieren',
},
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 | 🟠 Major

Maintain consistent formal German ("Sie" form).

The web3Solana strings use informal German, creating inconsistency with the rest of the file.

Apply this diff:

     web3Solana: {
-      subtitle: 'Wähle unten eine Wallet aus, um dich zu registrieren',
+      subtitle: 'Wählen Sie unten eine Wallet aus, um sich zu registrieren',
       title: 'Mit Solana registrieren',
     },
🤖 Prompt for AI Agents
In packages/localizations/src/de-DE.ts around lines 862 to 865, the web3Solana
strings use informal German ("dich" and "Wähle ... aus") which is inconsistent
with the rest of the file that uses the formal "Sie" form; update the subtitle
and title to use formal phrasing (e.g., change "Wähle unten eine Wallet aus, um
dich zu registrieren" to "Wählen Sie unten eine Wallet aus, um sich zu
registrieren" and ensure the title remains formal like "Mit Solana registrieren"
or adjust to "Mit Solana registrieren" if no change needed) so all user-facing
text consistently uses the formal "Sie" form.

Comment on lines +983 to +986
web3_signature_request_rejected:
'Du hast die Signaturanfrage abgelehnt. Bitte versuche es erneut, um fortzufahren.',
web3_solana_signature_generation_failed:
'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuche es erneut, um fortzufahren.',
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 | 🟠 Major

Maintain consistent formal German ("Sie" form) in error messages.

The new Solana error messages use informal German, inconsistent with other error messages in the file.

Apply this diff:

     web3_signature_request_rejected:
-      'Du hast die Signaturanfrage abgelehnt. Bitte versuche es erneut, um fortzufahren.',
+      'Sie haben die Signaturanfrage abgelehnt. Bitte versuchen Sie es erneut, um fortzufahren.',
     web3_solana_signature_generation_failed:
-      'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuche es erneut, um fortzufahren.',
+      'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut, um fortzufahren.',
📝 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
web3_signature_request_rejected:
'Du hast die Signaturanfrage abgelehnt. Bitte versuche es erneut, um fortzufahren.',
web3_solana_signature_generation_failed:
'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuche es erneut, um fortzufahren.',
web3_signature_request_rejected:
'Sie haben die Signaturanfrage abgelehnt. Bitte versuchen Sie es erneut, um fortzufahren.',
web3_solana_signature_generation_failed:
'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut, um fortzufahren.',
🤖 Prompt for AI Agents
In packages/localizations/src/de-DE.ts around lines 983 to 986, the two new
Solana error messages use informal "Du" and "versuche"; update them to formal
German to match the rest of the file by replacing the strings so the first
message uses "Sie haben ..." and the second message uses "Bitte versuchen Sie
..." (i.e., change "Du hast die Signaturanfrage abgelehnt. Bitte versuche es
erneut, um fortzufahren." to the formal equivalent and change "Bitte versuche es
erneut, um fortzufahren." in the second message to "Bitte versuchen Sie es
erneut, um fortzufahren.").

Comment on lines +1362 to +1365
web3SelectSolanaWalletScreen: {
subtitle: 'Wähle eine Solana-Wallet aus, um sie mit deinem Konto zu verbinden.',
title: 'Solana-Wallet hinzufügen',
},
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 | 🟠 Major

Maintain consistent formal German ("Sie" form) in wallet selection screen.

The web3SelectSolanaWalletScreen strings use informal German, inconsistent with the surrounding web3WalletsSection.

Apply this diff:

         web3SelectSolanaWalletScreen: {
-          subtitle: 'Wähle eine Solana-Wallet aus, um sie mit deinem Konto zu verbinden.',
+          subtitle: 'Wählen Sie eine Solana-Wallet aus, um sie mit Ihrem Konto zu verbinden.',
           title: 'Solana-Wallet hinzufügen',
         },
📝 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
web3SelectSolanaWalletScreen: {
subtitle: 'Wähle eine Solana-Wallet aus, um sie mit deinem Konto zu verbinden.',
title: 'Solana-Wallet hinzufügen',
},
web3SelectSolanaWalletScreen: {
subtitle: 'Wählen Sie eine Solana-Wallet aus, um sie mit Ihrem Konto zu verbinden.',
title: 'Solana-Wallet hinzufügen',
},
🤖 Prompt for AI Agents
In packages/localizations/src/de-DE.ts around lines 1362 to 1365, the
web3SelectSolanaWalletScreen strings use informal German; change the subtitle to
the formal "Sie" form. Replace "Wähle eine Solana-Wallet aus, um sie mit deinem
Konto zu verbinden." with "Wählen Sie eine Solana-Wallet aus, um sie mit Ihrem
Konto zu verbinden." and keep the title as-is to match surrounding
web3WalletsSection formal tone.

Comment on lines +1402 to +1407
web3SolanaWalletButtons: {
connect: 'Mit {{walletName}} verbinden',
continue: 'Weiter mit {{walletName}}',
noneAvailable:
'Keine Solana-Web3-Wallets erkannt. Bitte installiere eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
},
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 | 🟠 Major

Maintain consistent formal German ("Sie" form) in wallet button messages.

The noneAvailable string uses informal German, inconsistent with the rest of the file.

Apply this diff:

   web3SolanaWalletButtons: {
     connect: 'Mit {{walletName}} verbinden',
     continue: 'Weiter mit {{walletName}}',
     noneAvailable:
-      'Keine Solana-Web3-Wallets erkannt. Bitte installiere eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
+      'Keine Solana-Web3-Wallets erkannt. Bitte installieren Sie eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
   },
📝 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
web3SolanaWalletButtons: {
connect: 'Mit {{walletName}} verbinden',
continue: 'Weiter mit {{walletName}}',
noneAvailable:
'Keine Solana-Web3-Wallets erkannt. Bitte installiere eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
},
web3SolanaWalletButtons: {
connect: 'Mit {{walletName}} verbinden',
continue: 'Weiter mit {{walletName}}',
noneAvailable:
'Keine Solana-Web3-Wallets erkannt. Bitte installieren Sie eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
},
🤖 Prompt for AI Agents
In packages/localizations/src/de-DE.ts around lines 1402 to 1407, the
noneAvailable message uses informal German ("installiere") which is inconsistent
with the rest of the file; update the string to formal German by rephrasing to
something like "Es wurden keine Solana-Web3-Wallets erkannt. Bitte installieren
Sie eine Web3-unterstützte {{ solanaWalletsLink || link(\"wallet extension\")
}}." so that it uses "Sie" and matches the tone of the other messages.

Comment on lines +1389 to +1394
web3SolanaWalletButtons: {
connect: 'Подключиться через {{walletName}}',
continue: 'Продолжить через {{walletName}}',
noneAvailable:
'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("wallet extension") }} с поддержкой Web3.',
},
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 | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, let's check the structure of the localization file
fd 'ru-RU.ts' packages/localizations/src/

Repository: clerk/javascript

Length of output: 95


🏁 Script executed:

# Look for similar patterns with link() function in other localization files
rg 'link\(' packages/localizations/src/ -A 2 -B 2 | head -50

Repository: clerk/javascript

Length of output: 3731


🏁 Script executed:

# Check if there are other instances of fallback patterns in the Russian localization
rg '\|\|' packages/localizations/src/ru-RU.ts

Repository: clerk/javascript

Length of output: 555


🏁 Script executed:

# Search for the localization system implementation to understand how template expressions are processed
fd -e ts -e js packages/ -type f | xargs rg 'link\(' | grep -E '(function|const.*link|export)' | head -20

Repository: clerk/javascript

Length of output: 230


🏁 Script executed:

# Look for any documentation or comments about the link() function
rg -B 5 -A 5 'link\(' packages/localizations/src/ | grep -E '(//|/\*|\*)' | head -20

Repository: clerk/javascript

Length of output: 42


🏁 Script executed:

# Check the English localization file for comparison
cat packages/localizations/src/en-US.ts | grep -A 5 "web3SolanaWalletButtons"

Repository: clerk/javascript

Length of output: 329


🏁 Script executed:

# Look for the en-US pattern to understand the original
rg 'wallet extension' packages/localizations/src/

Repository: clerk/javascript

Length of output: 8187


🏁 Script executed:

# Check if "wallet extension" appears elsewhere in code (not in localizations)
rg 'wallet extension' packages/ --type-list | grep -v localizations | head -20

Repository: clerk/javascript

Length of output: 449


🏁 Script executed:

# Verify this is indeed a systemic issue - check how many files have this pattern
rg 'link\("wallet extension"\)' packages/localizations/src/ | wc -l

Repository: clerk/javascript

Length of output: 62


🏁 Script executed:

# Check the total number of localization files to confirm coverage
ls -1 packages/localizations/src/*.ts | grep -v index | wc -l

Repository: clerk/javascript

Length of output: 62


Untranslated fallback text in template expression affects all language files.

The noneAvailable message in web3SolanaWalletButtons contains English fallback text "wallet extension" across ALL 49 localization files. This creates a systemic issue where English text displays when solanaWalletsLink is not provided, regardless of the user's language setting.

While other link() fallbacks in ru-RU.ts ARE properly translated (e.g., "Политика конфиденциальности", "Условия обслуживания"), the wallet extension fallback remains untranslated everywhere. This should be translated consistently across all language files:

- 'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("wallet extension") }} с поддержкой Web3.',
+ 'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("расширение кошелька") }} с поддержкой Web3.',
📝 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
web3SolanaWalletButtons: {
connect: 'Подключиться через {{walletName}}',
continue: 'Продолжить через {{walletName}}',
noneAvailable:
'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("wallet extension") }} с поддержкой Web3.',
},
web3SolanaWalletButtons: {
connect: 'Подключиться через {{walletName}}',
continue: 'Продолжить через {{walletName}}',
noneAvailable:
'Кошельки Solana Web3 не обнаружены. Установите {{ solanaWalletsLink || link("расширение кошелька") }} с поддержкой Web3.',
},
🤖 Prompt for AI Agents
In packages/localizations/src/ru-RU.ts around lines 1389–1394 the template
fallback text link("wallet extension") is left in English; replace that fallback
with the proper Russian translation (e.g., link("расширение кошелька")) while
preserving the template interpolation, spacing and existing keys, and then apply
the same replacement consistently across all other localization files so no
language falls back to the English phrase.

Comment on lines +36 to +66
const Web3SolanaWalletButtonsInner = ({ web3AuthCallback }: Web3WalletButtonsProps) => {
const card = useCardState();
const { wallets } = useWallet();
const { t } = useLocalizations();

// Filter to only show installed wallets
const installedWallets = React.useMemo(
() =>
wallets
.filter(w => {
return w.readyState === WalletReadyState.Installed;
})
.map(wallet => {
return {
name: wallet.adapter.name,
icon: wallet.adapter.icon,
};
}),
[wallets],
);

const startWeb3AuthFlow = (walletName: string) => async () => {
card.setLoading(walletName);
try {
await web3AuthCallback({ walletName });
} catch {
await sleep(1000);
} finally {
card.setIdle();
}
};
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 | 🟠 Major

Don’t swallow auth errors; surface them via card.setError (and avoid arbitrary sleep). Right now failures silently “wait 1s” and reset to idle, which is hard to debug and UX-hostile.

-  const startWeb3AuthFlow = (walletName: string) => async () => {
+  const startWeb3AuthFlow = (walletName: string) => async () => {
     card.setLoading(walletName);
     try {
       await web3AuthCallback({ walletName });
-    } catch {
-      await sleep(1000);
+    } catch (err: unknown) {
+      card.setError(err instanceof Error ? err.message : 'Web3 authentication failed');
     } finally {
       card.setIdle();
     }
   };
📝 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 Web3SolanaWalletButtonsInner = ({ web3AuthCallback }: Web3WalletButtonsProps) => {
const card = useCardState();
const { wallets } = useWallet();
const { t } = useLocalizations();
// Filter to only show installed wallets
const installedWallets = React.useMemo(
() =>
wallets
.filter(w => {
return w.readyState === WalletReadyState.Installed;
})
.map(wallet => {
return {
name: wallet.adapter.name,
icon: wallet.adapter.icon,
};
}),
[wallets],
);
const startWeb3AuthFlow = (walletName: string) => async () => {
card.setLoading(walletName);
try {
await web3AuthCallback({ walletName });
} catch {
await sleep(1000);
} finally {
card.setIdle();
}
};
const Web3SolanaWalletButtonsInner = ({ web3AuthCallback }: Web3WalletButtonsProps) => {
const card = useCardState();
const { wallets } = useWallet();
const { t } = useLocalizations();
// Filter to only show installed wallets
const installedWallets = React.useMemo(
() =>
wallets
.filter(w => {
return w.readyState === WalletReadyState.Installed;
})
.map(wallet => {
return {
name: wallet.adapter.name,
icon: wallet.adapter.icon,
};
}),
[wallets],
);
const startWeb3AuthFlow = (walletName: string) => async () => {
card.setLoading(walletName);
try {
await web3AuthCallback({ walletName });
} catch (err: unknown) {
card.setError(err instanceof Error ? err.message : 'Web3 authentication failed');
} finally {
card.setIdle();
}
};
🤖 Prompt for AI Agents
In packages/ui/src/elements/Web3SolanaWalletButtons.tsx around lines 36 to 66,
the startWeb3AuthFlow catch block swallows errors and uses an arbitrary sleep
then resets the card to idle; change it to capture the caught error, call
card.setError with a meaningful message or the error object (e.g.,
card.setError(error.message || error)), remove the sleep call, and only call
card.setIdle on success (move setIdle into the try after await web3AuthCallback)
so errors remain visible; ensure the catch does not rethrow unless caller
expects it and preserve any cleanup needed.

@kduprey kduprey force-pushed the kenton/user-4212-add-solana-support-to-core-3 branch from 647c5d6 to 571a845 Compare December 15, 2025 16:40
@kduprey kduprey changed the title feat(clerk-js,localizations,shared,ui): Add Solana feature support to core 3 feat(clerk-js,clerk-react,localizations,shared,ui): Add Solana feature support to core 3 Dec 15, 2025
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: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/clerk-js/package.json (1)

61-80: Remove unused Solana dependencies or implement their integration.

The four new Solana dependencies (@solana/wallet-adapter-base, @solana/wallet-adapter-react, @solana/wallet-standard, @wallet-standard/core) are added to package.json but are not imported or used anywhere in the clerk-js source code. Additionally:

  • No TypeScript exports field is configured in package.json to expose types alongside runtime code
  • @clerk/shared already contains Web3 type definitions (web3.ts, web3Wallet.ts); clarify whether these dependencies should be added there instead or if clerk-js actually needs them

Either implement the dependencies with corresponding source code changes or remove them from this PR.

packages/localizations/src/pl-PL.ts (1)

809-811: Stray quote in label__onlyTermsOfService string

There’s an extra " at the end of this string:

label__onlyTermsOfService: 'Akceptuję {{ termsOfServiceLink || link("Warunki świadczenia usługi") }}"',

This will render an unwanted quote character in the UI and is inconsistent with the neighboring strings. Suggest:

-        label__onlyTermsOfService: 'Akceptuję {{ termsOfServiceLink || link("Warunki świadczenia usługi") }}"',
+        label__onlyTermsOfService: 'Akceptuję {{ termsOfServiceLink || link("Warunki świadczenia usługi") }}',
♻️ Duplicate comments (11)
packages/localizations/src/de-DE.ts (1)

767-770: Align new Solana strings with formal German (“Sie”) used elsewhere

The newly added Solana strings mix informal “du/dich/installiere” with a file that otherwise consistently speaks in the formal “Sie” tone. This is the same concern raised in earlier review comments and is still present.

Suggested diff to standardize to formal German while keeping keys and structure unchanged:

@@
   signIn: {
@@
-    web3Solana: {
-      subtitle: 'Wähle unten eine Wallet aus, um dich anzumelden',
-      title: 'Mit Solana anmelden',
-    },
+    web3Solana: {
+      subtitle: 'Wählen Sie unten eine Wallet aus, um sich anzumelden',
+      title: 'Mit Solana anmelden',
+    },
@@
   signUp: {
@@
-    web3Solana: {
-      subtitle: 'Wähle unten eine Wallet aus, um dich zu registrieren',
-      title: 'Mit Solana registrieren',
-    },
+    web3Solana: {
+      subtitle: 'Wählen Sie unten eine Wallet aus, um sich zu registrieren',
+      title: 'Mit Solana registrieren',
+    },
@@
   unstable__errors: {
@@
-    web3_signature_request_rejected:
-      'Du hast die Signaturanfrage abgelehnt. Bitte versuche es erneut, um fortzufahren.',
-    web3_solana_signature_generation_failed:
-      'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuche es erneut, um fortzufahren.',
+    web3_signature_request_rejected:
+      'Sie haben die Signaturanfrage abgelehnt. Bitte versuchen Sie es erneut, um fortzufahren.',
+    web3_solana_signature_generation_failed:
+      'Beim Erstellen der Signatur ist ein Fehler aufgetreten. Bitte versuchen Sie es erneut, um fortzufahren.',
@@
       web3WalletsSection: {
@@
-        web3SelectSolanaWalletScreen: {
-          subtitle: 'Wähle eine Solana-Wallet aus, um sie mit deinem Konto zu verbinden.',
-          title: 'Solana-Wallet hinzufügen',
-        },
+        web3SelectSolanaWalletScreen: {
+          subtitle: 'Wählen Sie eine Solana-Wallet aus, um sie mit Ihrem Konto zu verbinden.',
+          title: 'Solana-Wallet hinzufügen',
+        },
@@
-  web3SolanaWalletButtons: {
-    connect: 'Mit {{walletName}} verbinden',
-    continue: 'Weiter mit {{walletName}}',
-    noneAvailable:
-      'Keine Solana-Web3-Wallets erkannt. Bitte installiere eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
-  },
+  web3SolanaWalletButtons: {
+    connect: 'Mit {{walletName}} verbinden',
+    continue: 'Weiter mit {{walletName}}',
+    noneAvailable:
+      'Keine Solana-Web3-Wallets erkannt. Bitte installieren Sie eine Web3-unterstützte {{ solanaWalletsLink || link("wallet extension") }}.',
+  },

This keeps the existing meaning while matching the formal tone used across the rest of the locale.

Also applies to: 862-865, 983-986, 1362-1365, 1402-1407

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

454-462: Add JSDoc for authenticateWithSolana public API.

This is a new public method on SignIn and should be documented like the other authentication helpers.

+  /**
+   * Authenticates a user using a Solana Web3 wallet.
+   *
+   * @param params - Configuration for Solana authentication.
+   * @param params.walletName - The name of the Solana wallet to use (for example, 'phantom').
+   * @returns A promise that resolves to the updated {@link SignInResource}.
+   * @throws {ClerkRuntimeError} If the Solana wallet cannot be found or the signature flow fails.
+   *
+   * @example
+   * ```ts
+   * await signIn.authenticateWithSolana({ walletName: 'phantom' });
+   * ```
+   */
   public authenticateWithSolana = async (params: SignInAuthenticateWithSolanaParams): Promise<SignInResource> => {

As per coding guidelines, all public APIs should have JSDoc with params, return type, throws, and an example.

packages/shared/src/internal/clerk-js/injectedWeb3SolanaProviders.ts (1)

6-23: Guard #initialize to prevent repeated listener registration and redundant imports.

get() invokes #initialize() on every call, which re-imports @wallet-standard/core and re-attaches the register/unregister listeners each time. Over time this will accumulate listeners and do unnecessary work.

Consider guarding initialization and sharing a single in‑flight promise:

 class InjectedWeb3SolanaProviders {
   #wallets: readonly Wallet[] | undefined = undefined;
   static #instance: InjectedWeb3SolanaProviders | null = null;
+  #initialized = false;
+  #initializing: Promise<void> | null = null;

   private constructor() {}

   async #initialize() {
-    const wallets = await import('@wallet-standard/core').then(mod => mod.getWallets());
-    this.#wallets = wallets.get();
-
-    wallets.on('register', () => {
-      this.#wallets = wallets.get();
-    });
-    wallets.on('unregister', () => {
-      this.#wallets = wallets.get();
-    });
+    if (this.#initialized) {
+      return;
+    }
+    if (this.#initializing) {
+      await this.#initializing;
+      return;
+    }
+
+    this.#initializing = (async () => {
+      const wallets = await import('@wallet-standard/core').then(mod => mod.getWallets());
+      this.#wallets = wallets.get();
+
+      wallets.on('register', () => {
+        this.#wallets = wallets.get();
+      });
+      wallets.on('unregister', () => {
+        this.#wallets = wallets.get();
+      });
+
+      this.#initialized = true;
+      this.#initializing = null;
+    })();
+
+    await this.#initializing;
   }

This keeps listener registration strictly once while still updating #wallets on changes.

Also applies to: 39-63

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

361-371: Add JSDoc for authenticateWithSolana sign-up API.

authenticateWithSolana is a new public entry point on SignUp and should be documented similarly to the other Web3 helpers, including walletName, legalAccepted, and unsafeMetadata.

+  /**
+   * Authenticates a user during sign-up using a Solana Web3 wallet.
+   *
+   * @param params - Configuration for Solana Web3 sign-up.
+   * @param params.walletName - The Solana wallet to use (for example, 'phantom' or 'solflare').
+   * @param params.unsafeMetadata - Optional unsafe metadata to attach to the new user.
+   * @param params.legalAccepted - Optional flag indicating the user has accepted legal terms.
+   * @returns A promise that resolves to the updated {@link SignUpResource}.
+   * @throws {ClerkRuntimeError} If wallet connection or signature generation fails.
+   *
+   * @example
+   * ```ts
+   * await signUp.authenticateWithSolana({
+   *   walletName: 'phantom',
+   *   legalAccepted: true,
+   * });
+   * ```
+   */
   public authenticateWithSolana = async (params: SignUpAuthenticateWithSolanaParams): Promise<SignUpResource> => {

As per coding guidelines, all public APIs should carry JSDoc with parameters, return type, throws, and a usage example.

packages/ui/src/elements/Web3SolanaWalletButtons.tsx (3)

57-66: Surface web3 auth errors instead of sleeping and swallowing them.

startWeb3AuthFlow hides failures and just sleeps 1s before idling, which is opaque for users and hard to debug. Use card.setError and remove the artificial delay so callers see a meaningful error.

-  const startWeb3AuthFlow = (walletName: string) => async () => {
-    card.setLoading(walletName);
-    try {
-      await web3AuthCallback({ walletName });
-    } catch {
-      await sleep(1000);
-    } finally {
-      card.setIdle();
-    }
-  };
+  const startWeb3AuthFlow = (walletName: string) => async () => {
+    card.setLoading(walletName);
+    try {
+      await web3AuthCallback({ walletName });
+    } catch (err: unknown) {
+      card.setError(err instanceof Error ? err : 'Web3 authentication failed');
+    } finally {
+      card.setIdle();
+    }
+  };

Then drop the now-unused sleep import at Line 26.


174-193: Add an explicit accessible name for the icon‑only WalletButtonIcon.

WalletButtonIcon renders only icon as its child, so the underlying <Button> has no explicit name; relying on inner image/initials is brittle for screen readers. Use the label prop as aria-label so SR users consistently hear which wallet they’re activating.

 const WalletButtonIcon = forwardRef((props: WalletButtonProps, ref: Ref<HTMLButtonElement> | null): JSX.Element => {
   const { icon, label, id, ...rest } = props;

   return (
     <Button
       ref={ref}
+      aria-label={label}
       textVariant='buttonLarge'
       variant='outline'
       colorScheme='neutral'
       hoverAsFocus
       sx={t => ({
         minHeight: t.sizes.$8,
         width: '100%',
       })}
       {...rest}
     >
       {icon}
     </Button>
   );
 });

265-279: WalletProvider receives an empty wallets array, so no Solana wallets will ever appear.

wallets = useMemo(() => [], [network]) means useWallet() in Web3SolanaWalletButtonsInner always sees an empty list, so installedWallets is always [] and the component will permanently render the “noneAvailable” alert, regardless of what users have installed.

You need to instantiate and pass actual Solana wallet adapters (or a wallet-standard discovery adapter) here—ideally reusing the same adapter factory you use elsewhere / in the Core 2 implementation.

For example (pseudocode; wire up to your real adapter factory):

 export const Web3SolanaWalletButtons = (props: Web3WalletButtonsProps) => {
   const network = MAINNET_ENDPOINT;
-  const wallets = useMemo(() => [], [network]);
+  const wallets = useMemo(
+    () => {
+      // TODO: replace with your real adapter factory, e.g. from a shared Solana adapters module.
+      // return createSolanaWalletAdapters({ endpoint: network });
+      return [];
+    },
+    [network],
+  );

…and then ensure createSolanaWalletAdapters (or equivalent) returns the supported Adapter[] for WalletProvider.

#!/bin/bash
# Compare Core 2 vs Core 3 wiring for Solana wallet adapters to make sure this matches.
rg -n "WalletProvider" packages/ui/src --type tsx -C3 | sed -n '1,120p'
packages/ui/src/common/WalletInitialIcon.tsx (1)

39-40: Guard against empty or undefined value when computing the initial.

value[0].toUpperCase() will throw if value is an empty string or undefined. Use optional chaining/fallback so the component can safely render with an empty initial.

-        {value[0].toUpperCase()}
+        {value[0]?.toUpperCase() ?? ''}

Or derive an initial variable with the same logic and render that.

packages/ui/src/components/UserProfile/Web3SelectSolanaWalletScreen.tsx (2)

26-37: Don’t close the screen on connect errors; surface a visible error instead.

Right now errors are just logged and the screen always closes in finally, which looks like a no-op to the user and blocks retry. Prefer closing only on success and using card.setError on failure.

   const onClick = async ({ walletName }: { walletName: string }) => {
     card.setLoading(walletName);
     try {
       await onConnect({ strategy: 'web3_solana_signature', walletName });
-      card.setIdle();
+      card.setIdle();
+      close();
     } catch (err) {
       card.setIdle();
-      console.error(err);
-    } finally {
-      close();
+      console.error(err);
+      card.setError(err as unknown);
     }
   };

This keeps the screen open on failure and lets the existing card error plumbing show a message.


66-75: Set reset Button to type="button" to avoid accidental submit.

Inside Form.Root, a Button without an explicit type can default to submit if it renders a native <button>, unintentionally submitting the form.

         <FormButtonContainer>
           <Button
             variant='ghost'
+            type='button'
             onClick={() => {
               close();
             }}
             localizationKey={localizationKeys('userProfile.formButtonReset')}
             elementDescriptor={descriptors.formButtonReset}
           />
         </FormButtonContainer>
packages/ui/src/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx (1)

63-75: Align signUpContinueUrl path with other SignIn combined-flow components.

In the combined-flow case you currently use '../create/continue', but sibling components (e.g., SignInSocialButtons.tsx) use 'create/continue' for the same override. The extra ../ will change the routing context and likely send users to the wrong step.

-                      signUpContinueUrl: ctx.isCombinedFlow ? '../create/continue' : ctx.signUpContinueUrl,
+                      signUpContinueUrl: ctx.isCombinedFlow ? 'create/continue' : ctx.signUpContinueUrl,

This keeps the navigation consistent across SignIn Solana and social flows.

🧹 Nitpick comments (23)
packages/localizations/src/tr-TR.ts (1)

1370-1375: Optional: localize the “wallet extension” fallback label

Current noneAvailable mixes Turkish with the English "wallet extension" label inside link(...), which is slightly jarring but functional. You could localize the fallback link text to keep the sentence fully Turkish:

-    noneAvailable:
-      'Solana Web3 cüzdanı tespit edilmedi. Lütfen Web3 destekli {{ solanaWalletsLink || link("wallet extension") }} kurun.',
+    noneAvailable:
+      'Solana Web3 cüzdanı tespit edilmedi. Lütfen Web3 destekli {{ solanaWalletsLink || link("cüzdan uzantısını") }} kurun.',

This keeps the grammar natural while preserving the link helper pattern.

packages/localizations/src/id-ID.ts (1)

1365-1370: Consider localizing “wallet extension” link label

The button texts look good, and placeholders are correct. You might optionally localize the inner "wallet extension" label to Indonesian for consistency with the rest of the file.

-      'Tidak ada dompet Solana Web3 yang terdeteksi. Silakan instal {{ solanaWalletsLink || link("wallet extension") }} yang mendukung Web3.',
+      'Tidak ada dompet Solana Web3 yang terdeteksi. Silakan instal {{ solanaWalletsLink || link("ekstensi dompet") }} yang mendukung Web3.',
packages/localizations/src/ja-JP.ts (1)

1378-1383: Wallet button labels look good; consider localizing link text

The connect/continue strings with {{walletName}} are correct and consistent.
Minor nit: you might want to localize the inline link label "wallet extension" to Japanese, e.g. link("ウォレット拡張機能"), to match how other links in this file localize their visible text.

packages/localizations/src/da-DK.ts (1)

1325-1328: Consider terminology consistency for "wallet" vs "tegnebog".

The new Solana-related sections use "wallet" as a loanword (lines 752, 846, 1327, 1368), while existing Web3 wallet sections in this file consistently use the Danish word "tegnebog/tegnebøger" (lines 1321, 1323, 1324, 1339, 1343, 1346).

While "wallet" is commonly understood in crypto contexts, consider using consistent terminology throughout the file for better maintainability.

For example, you could change "Solana-wallet" to "Solana-tegnebog" throughout:

  • Line 752: "Vælg en tegnebog nedenfor for at logge ind"
  • Line 846: "Vælg en tegnebog nedenfor for at tilmelde dig"
  • Line 1327: "Tilføj en Solana-tegnebog"
  • Lines 1365-1368: Use "tegnebog" instead of "wallet" (note: {{walletName}} interpolation should remain as-is)
packages/localizations/src/nb-NO.ts (1)

1366-1371: Wallet button labels good; consider localizing inner “wallet extension” text

The web3SolanaWalletButtons strings and placeholders ({{walletName}}, {{ solanaWalletsLink || link("wallet extension") }}) look structurally correct. Minor nit: the anchor text "wallet extension" inside the last string is still English; consider translating it (e.g., a Norwegian equivalent for “wallet extension”) if consistency with the rest of this locale is desired.

packages/localizations/src/pl-PL.ts (3)

754-757: Solana sign-in copy is fine; optional word-order tweak

The text is clear, but Wybierz poniżej portfel, aby się zalogować is slightly unusual word order in Polish. If you want a more natural phrasing, consider Wybierz portfel poniżej, aby się zalogować. Not required if you’re aligning with other locales.


852-855: Sign-up Solana copy matches sign-in; same optional phrasing tweak

Copy is consistent with the sign-in variant. As above, you might prefer Wybierz portfel poniżej, aby się zarejestrować for a slightly more natural word order, but the current text is understandable.


1376-1381: Consider localizing the “wallet extension” link text

The sentence is Polish but the fallback link label is English:

'... Zainstaluj {{ solanaWalletsLink || link("wallet extension") }} obsługujący Web3.'

For consistency with other entries that localize the text inside link(...), you might prefer something like:

-      'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("wallet extension") }} obsługujący Web3.',
+      'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("rozszerzenie portfela") }} obsługujące Web3.',

Adjust wording as you see fit, but keeping the link label Polish will make the UI feel more consistent.

packages/clerk-js/rspack.config.js (2)

126-139: Consider following the existing pattern of dedicated cache groups.

The file already defines dedicated cache groups for stripeVendor, coinbaseWalletSDKVendor, and baseAccountSDKVendor (lines 112-117, 107-111, 102-106). For consistency and maintainability, Solana packages and their dependencies could follow the same pattern rather than being excluded from defaultVendors.

This approach would:

  • Align with the existing architecture
  • Make the bundling strategy more explicit
  • Simplify future updates to the Solana dependency list
  • Provide better control over chunk naming and priority

Example refactor:

+          solanaVendor: {
+            test: /[\\/]node_modules[\\/](@solana|@solana-mobile|@wallet-standard|bn\.js|borsh|buffer|superstruct|bs58|jayson|rpc-websockets|qrcode)[\\/]/,
+            name: 'solana-vendors',
+            chunks: 'all',
+            enforce: true,
+          },
           defaultVendors: {
             minChunks: 1,
-            test: module => {
-              if (!(module instanceof rspack.NormalModule) || !module.resource) {
-                return false;
-              }
-              // Exclude Solana packages and their known transitive dependencies
-              if (
-                /[\\/]node_modules[\\/](@solana|@solana-mobile|@wallet-standard|bn\.js|borsh|buffer|superstruct|bs58|jayson|rpc-websockets|qrcode)[\\/]/.test(
-                  module.resource,
-                )
-              ) {
-                return false;
-              }
-              return /[\\/]node_modules[\\/]/.test(module.resource);
-            },
+            test: /[\\/]node_modules[\\/]/,
             name: 'vendors',
             priority: -10,
           },

130-137: Add documentation explaining the rationale for Solana exclusion.

The comment states what is being excluded but not why these packages require special treatment. Adding context would help future maintainers understand the bundling strategy.

Consider expanding the comment:

-              // Exclude Solana packages and their known transitive dependencies
+              // Exclude Solana packages and their known transitive dependencies from the default vendor chunk
+              // to enable separate chunking or lazy loading due to [size/compatibility/loading strategy reason]
packages/localizations/src/he-IL.ts (1)

1343-1348: Root Solana wallet button texts and templating look good

The web3SolanaWalletButtons group cleanly exposes connect, continue, and noneAvailable strings, using interpolation ({{walletName}}, {{ solanaWalletsLink || link("wallet extension") }}) in a way that matches the project’s templating style. Also, many other keys in this file remain undefined, which is correct given the fallback behavior in Clerk localizations. Based on learnings, this is the expected pattern.

packages/localizations/src/es-UY.ts (5)

756-759: Align Solana sign-in strings with es‑UY voseo and existing “cartera” term

The structure and keys look correct, but for es-UY this block currently mixes tú-style (“Selecciona”) and the new “billetera” term, while the rest of the file uses voseo (“Seleccioná”) and “cartera Web3”.

Consider updating for consistency:

   totpMfa: {
     formTitle: 'Código de verificación',
     subtitle: 'Para continuar, ingresá el código generado por tu aplicación autenticadora',
     title: 'Verificación en dos pasos',
   },
-  web3Solana: {
-    subtitle: 'Selecciona una billetera abajo para iniciar sesión',
-    title: 'Iniciar sesión con Solana',
-  },
+  web3Solana: {
+    subtitle: 'Seleccioná una cartera abajo para iniciar sesión',
+    title: 'Iniciar sesión con Solana',
+  },

854-857: Unify Solana sign-up wording with es‑UY style

Same pattern here: tú-style “Selecciona” + “billetera” vs voseo and “cartera” elsewhere in es-UY.

You could align it like this:

   start: {
     actionLink: 'Iniciar sesión',
@@
     },
-    web3Solana: {
-      subtitle: 'Selecciona una billetera abajo para registrarte',
-      title: 'Registrarse con Solana',
-    },
+    web3Solana: {
+      subtitle: 'Seleccioná una cartera abajo para registrarte',
+      title: 'Registrarse con Solana',
+    },

1341-1344: Match Solana wallet-management copy to existing Web3 wallet section

This block is structurally correct, but again uses “Selecciona” + “billetera de Solana” while nearby text (e.g., subtitle__availableWallets) uses “Seleccioná” + “cartera Web3”.

For consistency within this locale:

       web3WalletsSection: {
         destructiveAction: 'Eliminar cartera',
         detailsAction__nonPrimary: undefined,
         primaryButton: 'Conectar cartera',
         title: 'Carteras Web3',
-        web3SelectSolanaWalletScreen: {
-          subtitle: 'Selecciona una billetera de Solana para conectarla a tu cuenta.',
-          title: 'Agregar una billetera de Solana',
-        },
+        web3SelectSolanaWalletScreen: {
+          subtitle: 'Seleccioná una cartera de Solana para conectarla a tu cuenta.',
+          title: 'Agregar una cartera de Solana',
+        },

968-970: Voseo nuance in new Solana error messages (optional)

The error keys and messages are correct and clear. If you want to be fully consistent with es-UY voseo (e.g., nearby “Instalá una para continuar.”), you might tweak the phrasing:

-    web3_signature_request_rejected: 'Has rechazado la solicitud de firma. Inténtalo de nuevo para continuar.',
-    web3_solana_signature_generation_failed:
-      'Se produjo un error al generar la firma. Inténtalo de nuevo para continuar.',
+    web3_signature_request_rejected: 'Rechazaste la solicitud de firma. Intentá de nuevo para continuar.',
+    web3_solana_signature_generation_failed:
+      'Ocurrió un error al generar la firma. Intentá de nuevo para continuar.',

Purely stylistic; fine to keep as-is if you prefer more neutral wording.


1380-1385: Ensure wallet-availability message matches es‑UY terminology and voseo

Keys/placeholders look correct (walletName, solanaWalletsLink). Same optional consistency suggestion around “billeteras” vs “carteras” and “Instala” vs “Instalá”:

-  web3SolanaWalletButtons: {
-    connect: 'Conectar con {{walletName}}',
-    continue: 'Continuar con {{walletName}}',
-    noneAvailable:
-      'No se detectaron billeteras Web3 de Solana. Instala una {{ solanaWalletsLink || link("wallet extension") }} compatible con Web3.',
-  },
+  web3SolanaWalletButtons: {
+    connect: 'Conectar con {{walletName}}',
+    continue: 'Continuar con {{walletName}}',
+    noneAvailable:
+      'No se detectaron carteras Web3 de Solana. Instalá una {{ solanaWalletsLink || link("wallet extension") }} compatible con Web3.',
+  },

(You may also want to localize the inner "wallet extension" label in a follow-up if other es-* locales do so.)

packages/ui/src/components/UserProfile/Web3Form.tsx (1)

16-24: Consider explicit component return type and stricter error typing

To better align with the TS guidelines for public APIs, you could:

  • Give AddWeb3WalletActionMenu an explicit return type (e.g. (): JSX.Element | null).
  • Change catch (err: any) to catch (err: unknown) and narrow via your existing getFieldError / handleError utilities.

This would tighten types without changing behavior.

Also applies to: 41-43, 65-73

packages/shared/src/types/signInCommon.ts (1)

196-198: New SignInAuthenticateWithSolanaParams type is fine but could be tightened later

Defining a dedicated SignInAuthenticateWithSolanaParams { walletName: string } cleanly exposes the extra Solana requirement for sign‑in flows. If you later introduce a shared Solana wallet name type (e.g. from a web3Wallet types module), consider reusing it here instead of plain string to keep wallet names consistent across sign‑in and sign‑up.

packages/shared/src/types/signUpCommon.ts (1)

114-121: Web3/Solana sign-up param types are coherent

Making legalAccepted part of SignUpAuthenticateWithWeb3Params and layering SignUpAuthenticateWithSolanaParams = SignUpAuthenticateWithWeb3Params & { walletName: string } gives a clear, reusable shape for Solana without disturbing existing helpers. As with the sign‑in side, you might later narrow walletName to a shared wallet-name type, but the current approach is consistent and safe.

packages/shared/src/internal/clerk-js/web3.ts (2)

140-193: Tighten Solana walletName guard in getWeb3Wallet.

errorThrower.throw already throws and never returns, so the return; that follows is effectively dead code and slightly obscures control flow.

   async function getWeb3Wallet(provider: Web3Provider, walletName?: string) {
@@
-    if (provider === 'solana') {
-      if (!walletName || walletName.length === 0) {
-        errorThrower.throw('Wallet name must be provided to get Solana wallet provider');
-        return;
-      }
-      return await getInjectedWeb3SolanaProviders().get(walletName);
-    }
+    if (provider === 'solana') {
+      if (!walletName || walletName.length === 0) {
+        errorThrower.throw('Wallet name must be provided to get Solana wallet provider');
+      }
+      return await getInjectedWeb3SolanaProviders().get(walletName);
+    }

This makes it clearer that the Solana branch either throws or returns a provider. As per coding guidelines, keeping error paths explicit improves maintainability.


68-93: Use error code 4001 instead of message string matching for Solana user rejection detection.

The current implementation detects user rejection by checking if the error message includes "User rejected the request.". The Solana Wallet Standard (implemented by Phantom, Solflare, and other wallet adapters) exposes a stable error code 4001 for user rejection. Update the error handling to check err.code === 4001 instead of relying on message text matching:

if (err && err.code === 4001) {
  throw new ClerkRuntimeError('Web3 signature request was rejected by the user.', {
    code: 'web3_signature_request_rejected',
  });
}

This aligns with the coding guidelines preference for structured error codes over message parsing and makes the error handling robust to wallet adapter or locale changes.

packages/ui/src/elements/Web3SolanaWalletButtons.tsx (2)

116-124: Simplify gridTemplateColumns; current wallets.length < 1 branch is effectively dead.

Because you early-return when installedWallets.length === 0, the wallets.length < 1 ternary here never takes the first branch. You can simplify to a single repeat expression based on row.length and rowIndex, which also makes intent clearer:

-            gridTemplateColumns:
-              wallets.length < 1
-                ? `repeat(1, minmax(0, 1fr))`
-                : `repeat(${row.length}, ${
-                    rowIndex === 0
-                      ? `minmax(0, 1fr)`
-                      : // Calculate the width of each button based on the width of the buttons within the first row.
-                        // t.sizes.$2 is used here to represent the gap defined on the Grid component.
-                        `minmax(0, calc((100% - (${strategyRowOneLength} - 1) * ${t.sizes.$2}) / ${strategyRowOneLength}))`
-                  })`,
+            gridTemplateColumns: `repeat(${row.length}, ${
+              rowIndex === 0
+                ? `minmax(0, 1fr)`
+                : // Calculate the width of each button based on the width of the buttons within the first row.
+                  // t.sizes.$2 is used here to represent the gap defined on the Grid component.
+                  `minmax(0, calc((100% - (${strategyRowOneLength} - 1) * ${t.sizes.$2}) / ${strategyRowOneLength}))`
+            })`,

195-262: WalletButtonBlock semantics look good; optional: also set aria-label for consistency.

This variant already exposes the wallet name as visible text, so it’s accessible. If you want stricter consistency with WalletButtonIcon, you could also set aria-label={label} on SimpleButton, but that’s optional.

Comment on lines +1372 to +1377
web3SolanaWalletButtons: {
connect: 'Poveži se s {{walletName}}',
continue: 'Nastavi s {{walletName}}',
noneAvailable:
'Nisu otkrivene Solana Web3 novčanike. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
},
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 | 🟡 Minor

Fix grammatical error in the noneAvailable message.

Line 1375-1376 contains a grammatical mismatch in Croatian. The feminine plural form "otkrivene" doesn't agree with the masculine noun "novčanike" (which should be in nominative case "novčanici" as the subject).

Apply this diff to correct the grammar:

     noneAvailable:
-      'Nisu otkrivene Solana Web3 novčanike. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
+      'Nisu otkriveni Solana Web3 novčanici. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
📝 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
web3SolanaWalletButtons: {
connect: 'Poveži se s {{walletName}}',
continue: 'Nastavi s {{walletName}}',
noneAvailable:
'Nisu otkrivene Solana Web3 novčanike. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
},
web3SolanaWalletButtons: {
connect: 'Poveži se s {{walletName}}',
continue: 'Nastavi s {{walletName}}',
noneAvailable:
'Nisu otkriveni Solana Web3 novčanici. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
},
🤖 Prompt for AI Agents
In packages/localizations/src/hr-HR.ts around lines 1372 to 1377, the
noneAvailable Croatian string uses the feminine plural "otkrivene" which
disagrees with the masculine plural noun "novčanike/novčanici"; update the
message to use the correct masculine plural form and case while preserving
placeholders and the link expression. Replace the string with a grammatically
correct sentence such as: "Nisu otkriveni Solana Web3 novčanici. Instalirajte {{
solanaWalletsLink || link(\"wallet extension\") }} s podrškom za Web3." ensuring
escaping of any quotes as required by the file.

Comment on lines +763 to +766
web3Solana: {
subtitle: 'Selectați un portofel mai jos pentru a vă conecta',
title: 'Conectare cu Solana',
},
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 | 🟡 Minor

Inconsistent register: formal vs. informal Romanian.

The new Solana sign-in strings use the formal register ("Selectați", "vă conecta"), but the rest of the file consistently uses the informal register (e.g., Line 753: "Te rugăm să te autentifici"). This creates an inconsistent user experience.

Apply this diff to align with the informal register used throughout the file:

     web3Solana: {
-      subtitle: 'Selectați un portofel mai jos pentru a vă conecta',
+      subtitle: 'Selectează un portofel mai jos pentru a te conecta',
       title: 'Conectare cu Solana',
     },
📝 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
web3Solana: {
subtitle: 'Selectați un portofel mai jos pentru a conecta',
title: 'Conectare cu Solana',
},
web3Solana: {
subtitle: 'Selectează un portofel mai jos pentru a te conecta',
title: 'Conectare cu Solana',
},
🤖 Prompt for AI Agents
In packages/localizations/src/ro-RO.ts around lines 763 to 766, the web3Solana
strings use the formal register ("Selectați", "vă conecta") whereas the file
uses informal Romanian; replace the subtitle with the informal phrasing
"Selectează un portofel mai jos pentru a te conecta" (keep the title "Conectare
cu Solana") so the register matches the rest of the file.

Comment on lines +860 to +863
web3Solana: {
subtitle: 'Selectați un portofel mai jos pentru a vă înregistra',
title: 'Înregistrare cu Solana',
},
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 | 🟡 Minor

Same register inconsistency in sign-up strings.

This block also uses the formal register, inconsistent with the rest of the file.

Apply this diff:

     web3Solana: {
-      subtitle: 'Selectați un portofel mai jos pentru a vă înregistra',
+      subtitle: 'Selectează un portofel mai jos pentru a te înregistra',
       title: 'Înregistrare cu Solana',
     },
📝 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
web3Solana: {
subtitle: 'Selectați un portofel mai jos pentru a înregistra',
title: 'Înregistrare cu Solana',
},
web3Solana: {
subtitle: 'Selectează un portofel mai jos pentru a te înregistra',
title: 'Înregistrare cu Solana',
},
🤖 Prompt for AI Agents
In packages/localizations/src/ro-RO.ts around lines 860 to 863, the web3Solana
block uses the formal register ("Înregistrare cu Solana", "Selectați un portofel
mai jos pentru a vă înregistra") which is inconsistent with the rest of the
file; change these to the informal forms used elsewhere: set title to
"Înregistrează-te cu Solana" and subtitle to "Selectează un portofel mai jos
pentru a te înregistra". Ensure spacing and punctuation match surrounding
entries.

Comment on lines +1344 to +1347
web3SelectSolanaWalletScreen: {
subtitle: 'Selectați un portofel Solana pentru a-l conecta la contul dvs.',
title: 'Adăugați un portofel Solana',
},
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 | 🟡 Minor

Formal register used in wallet screen strings.

Inconsistent with the surrounding content (e.g., Line 1362: 'Selectează un portofel web3 pentru a-l conecta la cont.').

Apply this diff:

         web3SelectSolanaWalletScreen: {
-          subtitle: 'Selectați un portofel Solana pentru a-l conecta la contul dvs.',
-          title: 'Adăugați un portofel Solana',
+          subtitle: 'Selectează un portofel Solana pentru a-l conecta la contul tău.',
+          title: 'Adaugă un portofel Solana',
         },
📝 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
web3SelectSolanaWalletScreen: {
subtitle: 'Selectați un portofel Solana pentru a-l conecta la contul dvs.',
title: 'Adăugați un portofel Solana',
},
web3SelectSolanaWalletScreen: {
subtitle: 'Selectează un portofel Solana pentru a-l conecta la contul tău.',
title: 'Adaugă un portofel Solana',
},
🤖 Prompt for AI Agents
In packages/localizations/src/ro-RO.ts around lines 1344 to 1347, the wallet
screen strings use the formal register; change them to the informal register to
match surrounding content. Replace the subtitle with "Selectează un portofel
Solana pentru a-l conecta la cont." and the title with "Adaugă un portofel
Solana".

Comment on lines +1383 to +1388
web3SolanaWalletButtons: {
connect: 'Conectează cu {{walletName}}',
continue: 'Continuă cu {{walletName}}',
noneAvailable:
'Nu s-au detectat portofele Solana Web3. Instalați un {{ solanaWalletsLink || link("wallet extension") }} compatibil cu Web3.',
},
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 | 🟡 Minor

Mixed register and untranslated English text.

Two issues:

  1. noneAvailable uses formal ("Instalați") while connect/continue use informal — inconsistent within the same block.
  2. The fallback text "wallet extension" is in English and should be translated.

Apply this diff:

 web3SolanaWalletButtons: {
   connect: 'Conectează cu {{walletName}}',
   continue: 'Continuă cu {{walletName}}',
   noneAvailable:
-    'Nu s-au detectat portofele Solana Web3. Instalați un {{ solanaWalletsLink || link("wallet extension") }} compatibil cu Web3.',
+    'Nu s-au detectat portofele Solana Web3. Instalează o {{ solanaWalletsLink || link("extensie de portofel") }} compatibilă cu Web3.',
 },
🤖 Prompt for AI Agents
In packages/localizations/src/ro-RO.ts around lines 1383 to 1388, the
web3SolanaWalletButtons block mixes formal and informal register and leaves the
fallback link text in English; change "Instalați" to the informal "Instalează"
to match "Conectează" / "Continuă" and translate the fallback "wallet extension"
to Romanian (e.g., "extensie pentru portofel") so the noneAvailable string
becomes informal and fully localized.

Comment on lines +265 to +267
export const Web3SolanaWalletButtons = (props: Web3WalletButtonsProps) => {
const network = MAINNET_ENDPOINT;
const wallets = useMemo(() => [], [network]);
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 | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's find and examine the target file
find . -name "Web3SolanaWalletButtons.tsx" -type f

Repository: clerk/javascript

Length of output: 176


🏁 Script executed:

# Check the package.json for Solana dependencies
find . -name "package.json" -type f | head -20 | xargs grep -l "@solana/wallet-standard" 2>/dev/null | head -5

Repository: clerk/javascript

Length of output: 176


🏁 Script executed:

# Search for MAINNET_ENDPOINT usage in the codebase
rg "MAINNET_ENDPOINT" --type ts --type tsx -B 2 -A 2

Repository: clerk/javascript

Length of output: 176


🏁 Script executed:

# Let's also check how this file imports from @solana packages
rg "@solana" packages/ui/src/elements/Web3SolanaWalletButtons.tsx 2>/dev/null

Repository: clerk/javascript

Length of output: 176


🌐 Web query:

@solana/wallet-standard MAINNET_ENDPOINT constant export

💡 Result:

Short answer: No — the @solana/wallet-standard JavaScript package does not export a MAINNET_ENDPOINT constant. The Wallet Standard uses chain identifiers (e.g. "solana:mainnet"/"solana:devnet") rather than hard-coded RPC endpoint constants; many tooling/docs use the canonical RPC URL https://api.mainnet-beta.solana.com when an RPC is needed. [1][2][3]

Sources:

  • @solana/wallet-standard (npm) package info. [1]
  • Wallet Standard / Solana docs referencing chain identifier "solana:mainnet". [2]
  • Common Solana RPC endpoint (https://api.mainnet-beta.solana.com) used in docs and examples. [3]

🌐 Web query:

@solana/wallet-standard npm package API documentation

💡 Result:

You can find the package and API sources here:

  • @solana/wallet-standard npm package (package page + versions). [1]
  • Solana Wallet Standard repository (Solana-specific extensions / repo on GitHub). [2]
  • Solana docs showing Wallet Standard usage (Wallet Connection / Commerce Kit). [3]

References

  1. @solana/wallet-standard — npm package page. [npmjs.com/package/@solana/wallet-standard]
  2. anza-xyz / wallet-standard — GitHub (Solana extensions to the Wallet Standard). [github.com/anza-xyz/wallet-standard]
  3. Solana docs — Wallet Connection (Wallet Standard usage in Commerce Kit). [launch.solana.com/docs/commerce-kit/quickstart/wallet-connection]

Remove the non-existent MAINNET_ENDPOINT import — this constant does not exist in @solana/wallet-standard.

The @solana/wallet-standard package does not export a MAINNET_ENDPOINT constant. The Wallet Standard instead uses chain identifiers (e.g., "solana:mainnet", "solana:devnet"). If an RPC endpoint is required, use the canonical Solana mainnet endpoint https://api.mainnet-beta.solana.com or make it configurable via props/environment variables to support devnet and testnet environments.

🤖 Prompt for AI Agents
In packages/ui/src/elements/Web3SolanaWalletButtons.tsx around lines 265 to 267,
remove references to the non-existent MAINNET_ENDPOINT import from
@solana/wallet-standard and stop using it directly; instead, provide a concrete
RPC endpoint or make it configurable by accepting an endpoint prop (or reading
from an env/config) and defaulting to the canonical Solana mainnet RPC
"https://api.mainnet-beta.solana.com" (or use chain identifier strings like
"solana:mainnet" if the wallet APIs require that), update useMemo to depend on
the chosen configurable endpoint/chain identifier, and ensure imports and types
are adjusted accordingly.

kduprey and others added 4 commits December 15, 2025 12:09
…ure support (#7293)

Signed-off-by: Kenton Duprey <[email protected]>
Co-authored-by: Dylan Staley <[email protected]>
Signed-off-by: Kenton Duprey <[email protected]>
…a Solana enabled wallet via `<UserProfile />` (#7435)

Signed-off-by: Kenton Duprey <[email protected]>
Signed-off-by: Kenton Duprey <[email protected]>
@kduprey kduprey force-pushed the kenton/user-4212-add-solana-support-to-core-3 branch from 4a6460a to bca9f40 Compare December 15, 2025 17:09
@kduprey kduprey changed the title feat(clerk-js,clerk-react,localizations,shared,ui): Add Solana feature support to core 3 feat(clerk-js,react,localizations,shared,ui): Add Solana feature support to core 3 Dec 15, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

♻️ Duplicate comments (15)
packages/localizations/src/hr-HR.ts (1)

1372-1377: Fix grammatical error in the noneAvailable message.

Lines 1375-1376 contain a grammatical mismatch in Croatian. The feminine plural form "otkrivene" doesn't agree with the masculine noun "novčanike" (which should be in nominative case "novčanici" as the subject).

Apply this diff to correct the grammar:

     noneAvailable:
-      'Nisu otkrivene Solana Web3 novčanike. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
+      'Nisu otkriveni Solana Web3 novčanici. Instalirajte {{ solanaWalletsLink || link("wallet extension") }} s podrškom za Web3.',
packages/ui/src/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx (1)

70-70: Fix the signUpContinueUrl path to match sibling components.

The path '../create/continue' in the combined-flow condition is inconsistent with SignInSocialButtons.tsx, which uses 'create/continue'. Both components are siblings in the same routing context, so using '../' navigates to the wrong step.

Apply this diff:

-                      signUpContinueUrl: ctx.isCombinedFlow ? '../create/continue' : ctx.signUpContinueUrl,
+                      signUpContinueUrl: ctx.isCombinedFlow ? 'create/continue' : ctx.signUpContinueUrl,
packages/localizations/src/ro-RO.ts (5)

763-766: Align sign-in Solana strings with informal register used elsewhere.

Most of this file uses the informal register (e.g., Line 753: “Te rugăm să te autentifici”), but this block uses formal “Selectați” / “vă conecta”, which is inconsistent.

     web3Solana: {
-      subtitle: 'Selectați un portofel mai jos pentru a vă conecta',
+      subtitle: 'Selectează un portofel mai jos pentru a te conecta',
       title: 'Conectare cu Solana',
     },

860-863: Use informal register for sign-up Solana copy.

Same inconsistency here: formal “Selectați” / “vă înregistra” and nominal title vs. informal style used elsewhere.

     web3Solana: {
-      subtitle: 'Selectați un portofel mai jos pentru a vă înregistra',
-      title: 'Înregistrare cu Solana',
+      subtitle: 'Selectează un portofel mai jos pentru a te înregistra',
+      title: 'Înregistrează-te cu Solana',
     },

973-975: Switch Solana error messages to informal register to match surrounding errors.

Nearby errors (e.g., Line 972) use informal “Te rugăm…”, but these use formal “Ați” / “Încercați”.

-    web3_signature_request_rejected: 'Ați respins solicitarea de semnătură. Încercați din nou pentru a continua.',
-    web3_solana_signature_generation_failed:
-      'A apărut o eroare la generarea semnăturii. Încercați din nou pentru a continua.',
+    web3_signature_request_rejected: 'Ai respins solicitarea de semnătură. Încearcă din nou pentru a continua.',
+    web3_solana_signature_generation_failed:
+      'A apărut o eroare la generarea semnăturii. Încearcă din nou pentru a continua.',

1344-1347: Update Solana wallet selection screen to informal register.

This block uses formal “Selectați”, “contul dvs.”, “Adăugați”, unlike the informal style in web3WalletPage just below.

         web3SelectSolanaWalletScreen: {
-          subtitle: 'Selectați un portofel Solana pentru a-l conecta la contul dvs.',
-          title: 'Adăugați un portofel Solana',
+          subtitle: 'Selectează un portofel Solana pentru a-l conecta la contul tău.',
+          title: 'Adaugă un portofel Solana',
         },

1383-1388: Fix mixed register and untranslated “wallet extension” in Solana wallet buttons.

connect/continue are informal, but noneAvailable uses formal “Instalați” and leaves “wallet extension” in English.

   web3SolanaWalletButtons: {
     connect: 'Conectează cu {{walletName}}',
     continue: 'Continuă cu {{walletName}}',
     noneAvailable:
-      'Nu s-au detectat portofele Solana Web3. Instalați un {{ solanaWalletsLink || link("wallet extension") }} compatibil cu Web3.',
+      'Nu s-au detectat portofele Solana Web3. Instalează o {{ solanaWalletsLink || link("extensie de portofel") }} compatibilă cu Web3.',
   },
packages/ui/src/common/WalletInitialIcon.tsx (1)

39-39: Add safety check for empty value string.

Accessing value[0] without checking if the string is non-empty will cause a runtime error (undefined.toUpperCase()) if an empty string is passed.

Apply this diff to add a safety check:

-        {value[0].toUpperCase()}
+        {value[0]?.toUpperCase() ?? ''}
packages/localizations/src/kk-KZ.ts (1)

1345-1350: English wallet extension fallback should be localized (same systemic issue as earlier review)

noneAvailable still falls back to the English phrase link("wallet extension"), so users without solanaWalletsLink see English text inside an otherwise Kazakh string. Please translate the fallback label while preserving the {{ solanaWalletsLink || link(...) }} pattern, consistent with the rest of this locale and the earlier comment on this issue.

packages/localizations/src/ja-JP.ts (1)

1378-1383: Localize wallet extension fallback inside noneAvailable

noneAvailable currently uses link("wallet extension") as an English fallback. This mirrors the systemic issue already noted in a previous review: if solanaWalletsLink is absent, users see English text in a Japanese string. Please replace the fallback label with a Japanese phrase (e.g., a translation of “wallet extension”) while keeping the template structure.

packages/localizations/src/fr-FR.ts (1)

1391-1396: Translate wallet extension fallback in noneAvailable

In web3SolanaWalletButtons.noneAvailable, the fallback link("wallet extension") remains in English. As already raised in a prior review, this yields English text when solanaWalletsLink is missing. Please switch that fallback label to French (e.g., an “extension de portefeuille” equivalent) while preserving the interpolation.

packages/localizations/src/ru-RU.ts (1)

1389-1394: English wallet extension fallback persists; align with earlier review

web3SolanaWalletButtons.noneAvailable still uses link("wallet extension") in English. This is the same systemic localization gap already called out in a previous review: when solanaWalletsLink is absent, Russian users see an English phrase embedded in the message. Please replace the fallback text with a Russian equivalent while preserving the template.

packages/localizations/src/he-IL.ts (1)

1343-1348: Localize wallet extension fallback in noneAvailable

web3SolanaWalletButtons.noneAvailable still falls back to the English link("wallet extension"). As previously noted for this PR, that causes English text to appear in localized UI when solanaWalletsLink is not provided. Please replace the fallback label with a Hebrew phrase while keeping the interpolation intact.

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

361-371: Document authenticateWithSolana public API with JSDoc

authenticateWithSolana is a new public method on SignUp and should be documented per the project’s JSDoc requirement for public APIs. A brief doc similar to the other authentication helpers will make its usage clearer to SDK consumers and keep generated docs accurate.

For example:

  /**
   * Authenticates a user during sign-up using a Solana Web3 wallet.
   *
   * @param params - Configuration for Solana authentication.
   * @param params.walletName - The Solana wallet to use (e.g. "phantom", "solflare").
   * @param params.unsafeMetadata - Optional metadata to attach to the sign-up.
   * @param params.legalAccepted - Whether the user has accepted legal terms.
   * @returns A promise that resolves to the updated SignUp resource.
   */
  public authenticateWithSolana = async (params: SignUpAuthenticateWithSolanaParams): Promise<SignUpResource> => {
    
  };

As per coding guidelines, all public APIs must be documented with JSDoc.

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

454-462: Add JSDoc for authenticateWithSolana on SignIn

authenticateWithSolana is a new public entrypoint on SignIn and should be documented like the other authentication helpers.

Something along these lines would satisfy the guidelines:

  /**
   * Authenticates a user using a Solana Web3 wallet.
   *
   * @param params - Configuration for Solana authentication.
   * @param params.walletName - The Solana wallet to use for authentication.
   * @returns A promise that resolves to the updated SignIn resource.
   */
  public authenticateWithSolana = async (params: SignInAuthenticateWithSolanaParams): Promise<SignInResource> => {
    
  };

As per coding guidelines, all public APIs must be documented with JSDoc.

🧹 Nitpick comments (20)
packages/localizations/src/vi-VN.ts (1)

1374-1379: Wallet button strings are correct; consider localizing “wallet extension”

Keys and placeholders ({{walletName}}, {{ solanaWalletsLink || link("…") }}) look correct; messages read well. As an optional polish, you might localize the linked anchor text instead of "wallet extension":

-      'Không phát hiện ví Solana Web3 nào. Vui lòng cài đặt {{ solanaWalletsLink || link("wallet extension") }} hỗ trợ Web3.',
+      'Không phát hiện ví Solana Web3 nào. Vui lòng cài đặt {{ solanaWalletsLink || link("tiện ích ví") }} hỗ trợ Web3.',
packages/localizations/src/nl-NL.ts (1)

752-755: Solana wallet flow translations look good; minor terminology consistency nit

The Solana sign‑in/sign‑up/profile and button texts read well and keep placeholders like {{walletName}} and {{ solanaWalletsLink || link("wallet extension") }} intact. One tiny nit: you alternate between “wallet”, “Solana‑wallet” and “(web3) portefeuille” elsewhere in this file. If you want maximum consistency, consider standardizing on either “wallet”/“Solana‑wallet” or “(web3) portefeuille” across these new keys, but this is purely cosmetic.

Also applies to: 847-850, 1326-1329, 1365-1370

packages/localizations/src/nl-BE.ts (1)

1326-1329: Solana wallet‑selection screen copy is accurate; minor terminology nit

Title/subtitle correctly describe adding a Solana wallet and match other locales. You might optionally align terminology with nearby strings (either consistently “wallet” or “portefeuille”) for a slightly more uniform UX, but it’s not blocking.

packages/localizations/src/hi-IN.ts (1)

1378-1383: Consider translating "wallet extension" for consistency.

The connect and continue translations are good. However, in noneAvailable, the link text "wallet extension" is kept in English, while:

  • Line 808 uses translated Hindi text in similar link() patterns (e.g., "गोपनीयता नीति")
  • Line 965 uses "वॉलेट एक्सटेंशन" (Hindi transliteration) for the same term

For consistency, consider using the Hindi transliteration:

  noneAvailable:
-    'कोई Solana Web3 वॉलेट नहीं मिला। कृपया Web3 समर्थित {{ solanaWalletsLink || link("wallet extension") }} इंस्टॉल करें।',
+    'कोई Solana Web3 वॉलेट नहीं मिला। कृपया Web3 समर्थित {{ solanaWalletsLink || link("वॉलेट एक्सटेंशन") }} इंस्टॉल करें।',
packages/ui/src/components/SignIn/SignInFactorOneSolanaWalletsCard.tsx (2)

21-21: Add explicit return type annotation.

The component function lacks an explicit return type. As per coding guidelines, functions should define explicit return types for clarity and type safety.

Apply this diff:

-const SignInFactorOneSolanaWalletsCardInner = () => {
+const SignInFactorOneSolanaWalletsCardInner = (): React.JSX.Element => {

92-94: Add JSDoc for the public API.

The exported component lacks JSDoc documentation. As per coding guidelines, public APIs should be documented with comprehensive JSDoc comments.

Apply this diff:

+/**
+ * SignIn card component for authenticating with Solana Web3 wallets.
+ * Displays wallet selection UI and handles Solana signature-based authentication.
+ * 
+ * @returns A wrapped component with redirect and card state providers
+ */
 export const SignInFactorOneSolanaWalletsCard = withRedirectToSignInTask(
   withRedirectToAfterSignIn(withCardStateProvider(SignInFactorOneSolanaWalletsCardInner)),
 );
packages/ui/src/components/SignUp/SignUpStartSolanaWalletsCard.tsx (2)

21-21: Add explicit return type annotation.

The component function lacks an explicit return type. As per coding guidelines, functions should define explicit return types for clarity and type safety.

Apply this diff:

-const SignUpStartSolanaWalletsCardInner = () => {
+const SignUpStartSolanaWalletsCardInner = (): React.JSX.Element => {

91-93: Add JSDoc for the public API.

The exported component lacks JSDoc documentation. As per coding guidelines, public APIs should be documented with comprehensive JSDoc comments.

Apply this diff:

+/**
+ * SignUp card component for authenticating with Solana Web3 wallets.
+ * Displays wallet selection UI and handles Solana signature-based authentication during sign-up.
+ * 
+ * @returns A wrapped component with redirect and card state providers
+ */
 export const SignUpStartSolanaWalletsCard = withRedirectToSignUpTask(
   withRedirectToAfterSignUp(withCardStateProvider(SignUpStartSolanaWalletsCardInner)),
 );
packages/localizations/src/fi-FI.ts (1)

1368-1373: Consider minor grammatical refinement for "continue" button text.

The translations are functional and understandable. However, for improved grammatical consistency with the rest of the file, line 1370 could be refined:

  • Current: 'Jatka {{walletName}}'
  • Suggestion: 'Jatka {{walletName}}:lla' or 'Jatka {{walletName}}:n kanssa'

This would align better with the pattern used in line 853 ('Jatka palvelun {{provider|titleize}} avulla'), which includes a preposition/postposition for "with" in Finnish.

Apply this diff if you want to improve grammatical consistency:

 web3SolanaWalletButtons: {
   connect: 'Yhdistä {{walletName}}',
-  continue: 'Jatka {{walletName}}',
+  continue: 'Jatka {{walletName}}:lla',
   noneAvailable:
     'Solana Web3 -lompakoita ei havaittu. Asenna Web3-yhteensopiva {{ solanaWalletsLink || link("wallet extension") }}.',
 },

Note: This is a minor grammatical preference rather than a critical issue. The current translation is still understandable.

packages/localizations/src/en-GB.ts (1)

1371-1376: Consider tightening “Web3 supported” phrasing for readability

The last sentence reads a bit awkwardly as “Web3 supported …”. For slightly smoother wording you could hyphenate “Web3-supported”:

-    noneAvailable:
-      'No Solana Web3 wallets detected. Please install a Web3 supported {{ solanaWalletsLink || link("wallet extension") }}.',
+    noneAvailable:
+      'No Solana Web3 wallets detected. Please install a Web3-supported {{ solanaWalletsLink || link("wallet extension") }}.',

Purely stylistic; no functional impact.

packages/localizations/src/cs-CZ.ts (1)

1380-1385: Consider localizing the fallback “wallet extension” link label

The web3SolanaWalletButtons.noneAvailable string is fine functionally and placeholders look correct, but the fallback link label inside link("wallet extension") is still English in an otherwise Czech sentence. You may want to switch that to a Czech phrase (similar to how other link("…") usages in this file are localized) to keep the UI fully localized.

packages/localizations/src/id-ID.ts (1)

1365-1370: Root Solana wallet button labels look good; consider localizing link fallback text

The web3SolanaWalletButtons labels are clear and consistent with other provider button texts. One optional improvement: the fallback link label "wallet extension" is still in English; you may want to localize it, e.g.:

-      'Tidak ada dompet Solana Web3 yang terdeteksi. Silakan instal {{ solanaWalletsLink || link("wallet extension") }} yang mendukung Web3.',
+      'Tidak ada dompet Solana Web3 yang terdeteksi. Silakan instal {{ solanaWalletsLink || link("ekstensi dompet") }} yang mendukung Web3.',
packages/localizations/src/th-TH.ts (1)

1358-1363: Root Solana wallet button labels are correct; consider localizing link text

The web3SolanaWalletButtons block is structurally sound and uses {{walletName}} and {{ solanaWalletsLink || link("wallet extension") }} consistently with other locales. One optional improvement: you might want to localize the "wallet extension" label inside the link to Thai (as is done for policy/terms link labels) for a more native experience, unless you intentionally prefer the English term here.

packages/localizations/src/be-BY.ts (2)

1337-1340: Solana wallet‑selection screen wiring is consistent; consider terminology tweak

The new web3SelectSolanaWalletScreen object under userProfile.start.web3WalletsSection is correctly nested and uses clear copy describing adding/connecting a Solana wallet.

Minor nit: elsewhere in this file the concept of “account” is often translated as “ўліковы запіс”; here the subtitle uses “акаўнта”. For consistency, you might consider aligning the term with the dominant choice in this locale, if that matches your translator’s preference.


1376-1381: web3SolanaWalletButtons placeholders and syntax look good

The web3SolanaWalletButtons block is well‑formed, and the interpolation placeholders match existing patterns:

  • {{walletName}} is used in both connect and continue.
  • {{ solanaWalletsLink || link("wallet extension") }} mirrors the same link() helper style used earlier in this file.

One optional improvement: the visible link text "wallet extension" is still in English; if other locales localize that helper text, you may want to do the same here for consistency.

packages/ui/src/common/WalletInitialIcon.tsx (1)

5-11: Consider adding JSDoc for value prop.

The id prop has JSDoc documentation, but value does not. For consistency and clarity, consider documenting what value represents.

 type WalletInitialIconProps = PropsOfComponent<typeof Box> & {
+  /**
+   * The wallet name to display the initial of
+   */
   value: string;
   /**
    * The wallet provider name
    */
   id: string;
 };
packages/shared/src/internal/clerk-js/web3.ts (1)

68-92: Consider making Solana “user rejected” detection more robust (optional)

generateWeb3Signature relies on err.message.includes('User rejected the request.') to classify rejections, which may be brittle across wallet implementations and future library versions. If the Solana adapters expose a stable error code or type for user cancellations, it would be more robust to key off that instead of a hard-coded message fragment.

Check the error shape emitted by the Solana wallet adapters you target (e.g. via their docs or a quick console.log in a local build) to see if there is a stable code/field you can branch on instead of the message text.

packages/localizations/src/en-US.ts (1)

846-849: Consider adding noAvailableWallets for sign‑up Solana parity

signUp.web3Solana defines title and subtitle, but the type also includes noAvailableWallets. It’s optional (via DeepPartial), but adding an explicit noAvailableWallets string here would keep the default en-US resource self‑contained and symmetric with the type.

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

260-309: Wallet‑name aware Web3 sign‑up flow matches shared Solana types

  • Adding walletName to the authenticateWithWeb3 params and threading it through to generateSignature keeps the sign‑up Web3 flow aligned with the new GenerateSignature contract and Solana support.
  • The convenience wrappers (authenticateWithCoinbaseWallet, authenticateWithBase, authenticateWithOKXWallet) now consistently use SignUpAuthenticateWithWeb3Params, which matches the public SignUpResource type.

One improvement to consider: for parity with SignIn.authenticateWithWeb3, you might add a small runtime guard here:

const provider = strategy.replace('web3_', '').replace('_signature', '') as Web3Provider;

if (!(typeof generateSignature === 'function')) {
  clerkMissingOptionError('generateSignature');
}

+ if (provider === 'solana' && !walletName) {
+   clerkMissingOptionError('walletName');
+ }

This would give developers a clearer error if they ever call authenticateWithWeb3 directly using the Solana strategy but forget to supply walletName, even if the type system already discourages that.

Also applies to: 326-337, 339-359

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

368-416: Minor consistency nit: coinbase retry includes walletName too

In authenticateWithWeb3, the Coinbase retry path now also passes walletName:

signature = await generateSignature({ identifier, nonce: message, provider, walletName });

This is functionally fine given the new GenerateSignature shape and that Coinbase ignores unknown params, but for strict parity with the Future path (which omits walletName on retry) you could simplify this to:

-        signature = await generateSignature({ identifier, nonce: message, provider, walletName });
+        signature = await generateSignature({ identifier, nonce: message, provider });

Not required, but would keep both code paths visually aligned.

Comment on lines +1376 to +1381
web3SolanaWalletButtons: {
connect: 'Połącz z {{walletName}}',
continue: 'Kontynuuj z {{walletName}}',
noneAvailable:
'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("wallet extension") }} obsługujący Web3.',
},
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 | 🟡 Minor

Translate the fallback link text to Polish.

The fallback text "wallet extension" in line 1380 should be translated to Polish to maintain consistency with other link() usages in this file (see lines 808-809, which translate fallback text).

Apply this diff:

     noneAvailable:
-      'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("wallet extension") }} obsługujący Web3.',
+      'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("rozszerzenie portfela") }} obsługujący Web3.',

Note: "rozszerzenie portfela" = "wallet extension" in Polish.

📝 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
web3SolanaWalletButtons: {
connect: 'Połącz z {{walletName}}',
continue: 'Kontynuuj z {{walletName}}',
noneAvailable:
'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("wallet extension") }} obsługujący Web3.',
},
web3SolanaWalletButtons: {
connect: 'Połącz z {{walletName}}',
continue: 'Kontynuuj z {{walletName}}',
noneAvailable:
'Nie wykryto portfeli Solana Web3. Zainstaluj {{ solanaWalletsLink || link("rozszerzenie portfela") }} obsługujący Web3.',
},
🤖 Prompt for AI Agents
In packages/localizations/src/pl-PL.ts around lines 1376 to 1381, the fallback
text "wallet extension" inside link(...) is still in English; replace it with
the Polish translation "rozszerzenie portfela" so the fallback becomes
link("rozszerzenie portfela") to match other translations and maintain
consistency.

{ "path": "./dist/ui.browser.js", "maxSize": "19.5KB" },
{ "path": "./dist/framework*.js", "maxSize": "44KB" },
{ "path": "./dist/vendors*.js", "maxSize": "43KB" },
{ "path": "./dist/vendors*.js", "maxSize": "143KB" },
Copy link
Contributor

Choose a reason for hiding this comment

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

Driveby-comment: This seems like an awfully big increase for what I expect will be a rarely used feature? 🤔 Or does this end up in a separate chunk that gets lazy-loaded somehow?

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.

3 participants