Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

fix(clerk-js,clerk-react,types): Optimize Coinbase SDK loading #4786

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

nikospapcom
Copy link
Member

@nikospapcom nikospapcom commented Dec 16, 2024

Introduce new method prefetchDependencies to load Coinbase SDK instead of loading the SDK when click the Coinbase button in <SignIn/> / <SignUp />. This change avoid the Safari to block the Coinbase popup

Description

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:

Copy link

vercel bot commented Dec 16, 2024

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

Name Status Preview Comments Updated (UTC)
clerk-js-sandbox ✅ Ready (Inspect) Visit Preview 💬 Add feedback Dec 17, 2024 2:21pm

Copy link

changeset-bot bot commented Dec 16, 2024

🦋 Changeset detected

Latest commit: a83056f

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

This PR includes changesets to release 23 packages
Name Type
@clerk/clerk-js Patch
@clerk/clerk-react Patch
@clerk/types Patch
@clerk/chrome-extension Patch
@clerk/clerk-expo Patch
@clerk/elements Patch
@clerk/nextjs Patch
@clerk/react-router Patch
@clerk/remix Patch
@clerk/tanstack-start Patch
@clerk/astro Patch
@clerk/backend Patch
@clerk/expo-passkeys Patch
@clerk/express Patch
@clerk/fastify Patch
@clerk/localizations Patch
@clerk/nuxt Patch
@clerk/clerk-sdk-node Patch
@clerk/shared Patch
@clerk/testing Patch
@clerk/themes Patch
@clerk/ui 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

@nikospapcom
Copy link
Member Author

!snapshot

@clerk-cookie
Copy link
Collaborator

Hey @nikospapcom - the snapshot version command generated the following package versions:

Package Version
@clerk/astro 2.1.3-snapshot.v20241217094601
@clerk/backend 1.21.3-snapshot.v20241217094601
@clerk/chrome-extension 2.1.4-snapshot.v20241217094601
@clerk/clerk-js 5.43.1-snapshot.v20241217094601
@clerk/elements 0.22.3-snapshot.v20241217094601
@clerk/clerk-expo 2.6.3-snapshot.v20241217094601
@clerk/expo-passkeys 0.1.3-snapshot.v20241217094601
@clerk/express 1.3.30-snapshot.v20241217094601
@clerk/fastify 2.1.3-snapshot.v20241217094601
@clerk/localizations 3.9.4-snapshot.v20241217094601
@clerk/nextjs 6.9.4-snapshot.v20241217094601
@clerk/nuxt 0.1.4-snapshot.v20241217094601
@clerk/clerk-react 5.20.3-snapshot.v20241217094601
@clerk/react-router 0.1.3-snapshot.v20241217094601
@clerk/remix 4.4.4-snapshot.v20241217094601
@clerk/clerk-sdk-node 5.1.3-snapshot.v20241217094601
@clerk/shared 2.20.3-snapshot.v20241217094601
@clerk/tanstack-start 0.8.3-snapshot.v20241217094601
@clerk/testing 1.4.3-snapshot.v20241217094601
@clerk/themes 2.2.3-snapshot.v20241217094601
@clerk/types 4.39.5-snapshot.v20241217094601
@clerk/ui 0.3.4-snapshot.v20241217094601
@clerk/vue 0.1.4-snapshot.v20241217094601

Tip: Use the snippet copy button below to quickly install the required packages.
@clerk/astro

npm i @clerk/astro@2.1.3-snapshot.v20241217094601 --save-exact

@clerk/backend

npm i @clerk/backend@1.21.3-snapshot.v20241217094601 --save-exact

@clerk/chrome-extension

npm i @clerk/chrome-extension@2.1.4-snapshot.v20241217094601 --save-exact

@clerk/clerk-js

npm i @clerk/clerk-js@5.43.1-snapshot.v20241217094601 --save-exact

@clerk/elements

npm i @clerk/elements@0.22.3-snapshot.v20241217094601 --save-exact

@clerk/clerk-expo

npm i @clerk/clerk-expo@2.6.3-snapshot.v20241217094601 --save-exact

@clerk/expo-passkeys

npm i @clerk/expo-passkeys@0.1.3-snapshot.v20241217094601 --save-exact

@clerk/express

npm i @clerk/express@1.3.30-snapshot.v20241217094601 --save-exact

@clerk/fastify

npm i @clerk/fastify@2.1.3-snapshot.v20241217094601 --save-exact

@clerk/localizations

npm i @clerk/localizations@3.9.4-snapshot.v20241217094601 --save-exact

@clerk/nextjs

npm i @clerk/nextjs@6.9.4-snapshot.v20241217094601 --save-exact

@clerk/nuxt

npm i @clerk/nuxt@0.1.4-snapshot.v20241217094601 --save-exact

@clerk/clerk-react

npm i @clerk/clerk-react@5.20.3-snapshot.v20241217094601 --save-exact

@clerk/react-router

npm i @clerk/react-router@0.1.3-snapshot.v20241217094601 --save-exact

@clerk/remix

npm i @clerk/remix@4.4.4-snapshot.v20241217094601 --save-exact

@clerk/clerk-sdk-node

npm i @clerk/clerk-sdk-node@5.1.3-snapshot.v20241217094601 --save-exact

@clerk/shared

npm i @clerk/shared@2.20.3-snapshot.v20241217094601 --save-exact

@clerk/tanstack-start

npm i @clerk/tanstack-start@0.8.3-snapshot.v20241217094601 --save-exact

@clerk/testing

npm i @clerk/testing@1.4.3-snapshot.v20241217094601 --save-exact

@clerk/themes

npm i @clerk/themes@2.2.3-snapshot.v20241217094601 --save-exact

@clerk/types

npm i @clerk/types@4.39.5-snapshot.v20241217094601 --save-exact

@clerk/ui

npm i @clerk/ui@0.3.4-snapshot.v20241217094601 --save-exact

@clerk/vue

npm i @clerk/vue@0.1.4-snapshot.v20241217094601 --save-exact

@nikospapcom nikospapcom changed the title fix(clerk-js,clerk-react,types,elements): Optimize Coinbase SDK loading fix(clerk-js,clerk-react,types): Optimize Coinbase SDK loading Dec 17, 2024
@nikospapcom nikospapcom force-pushed the nikospap/user-1159-safari-blocks-coinbase-wallet-popup branch from a276304 to 315564b Compare December 17, 2024 11:43
@nikospapcom nikospapcom marked this pull request as ready for review December 17, 2024 11:43
Comment on lines 254 to 266
get isCoinbaseWalletEnabled(): boolean {
const attributes = this.environment?.userSettings.attributes;
if (!attributes) {
return false;
}

const findWeb3Attributes = Object.entries(attributes)
.filter(([name, attr]) => attr.used_for_first_factor && name.startsWith('web3'))
.map(([, desc]) => desc.first_factors)
.flat() as any as Web3Strategy[];

return findWeb3Attributes.includes('web3_coinbase_wallet_signature');
}
Copy link
Member

Choose a reason for hiding this comment

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

❓Should we make this private ? Since we don't want any api changes atm

@@ -1654,6 +1672,16 @@ export class Clerk implements ClerkInterface {
this.environment = environment;
}

public prefetchDependencies = async (): Promise<void> => {
Copy link
Member

Choose a reason for hiding this comment

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

I believe this can be private, and don't need to call it from IsomorphicClerk.

@@ -180,6 +183,7 @@ export class Clerk implements ClerkInterface {
protected internal_last_error: ClerkAPIError | null = null;
// converted to protected environment to support `updateEnvironment` type assertion
protected environment?: EnvironmentResource | null;
private __promise = createDeferredPromise();
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
private __promise = createDeferredPromise();
#coinbaseSDKResolvers = createDeferredPromise();

@@ -1654,6 +1672,16 @@ export class Clerk implements ClerkInterface {
this.environment = environment;
}

public prefetchDependencies = async (): Promise<void> => {
if (this.isCoinbaseWalletEnabled) {
window.__clerk_coinbase_sdk = this.__promise.promise as Promise<typeof CoinbaseWalletSDK>;
Copy link
Member

Choose a reason for hiding this comment

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

maybe this need to move inside the constructor.

Also

Suggested change
window.__clerk_coinbase_sdk = this.__promise.promise as Promise<typeof CoinbaseWalletSDK>;
window.__clerk_coinbase_sdk = this.#coinbaseSDKResolvers.promise as Promise<typeof CoinbaseWalletSDK>;

Comment on lines 1679 to 1681
await import('@coinbase/wallet-sdk').then(mod => {
this.__promise.resolve(mod.CoinbaseWalletSDK);
});
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
await import('@coinbase/wallet-sdk').then(mod => {
this.__promise.resolve(mod.CoinbaseWalletSDK);
});
await import('@coinbase/wallet-sdk').then(mod => {
this.#coinbaseSDKResolvers.resolve(mod.CoinbaseWalletSDK);
});

@@ -71,7 +71,7 @@ export async function generateSignatureWithOKXWallet(params: GenerateSignaturePa

async function getEthereumProvider(provider: Web3Provider) {
if (provider === 'coinbase_wallet') {
const CoinbaseWalletSDK = await import('@coinbase/wallet-sdk').then(mod => mod.CoinbaseWalletSDK);
const CoinbaseWalletSDK = await window.__clerk_coinbase_sdk;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
const CoinbaseWalletSDK = await window.__clerk_coinbase_sdk;
const CoinbaseWalletSDK = await window.__clerk_coinbase_sdk.catch(()=>null)
// example error
if(!CoinbaseWalletSDK) { throw "Coinbase SDK failed to load" }

Comment on lines 1219 to 1227

prefetchDependencies = async (): Promise<void> => {
const callback = () => this.clerkjs?.prefetchDependencies();
if (this.clerkjs && this.#loaded) {
return callback() as Promise<void>;
} else {
this.premountMethodCalls.set('prefetchDependencies', callback);
}
};
Copy link
Member

Choose a reason for hiding this comment

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

🧹🧹 we don't really need these with this approach

@@ -1654,6 +1672,16 @@ export class Clerk implements ClerkInterface {
this.environment = environment;
}

public prefetchDependencies = async (): Promise<void> => {
if (this.isCoinbaseWalletEnabled) {
Copy link
Member

Choose a reason for hiding this comment

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

As an optimization we should add the follwing

if(signedIn && singleMode) then don't load the sdk

Copy link
Member Author

Choose a reason for hiding this comment

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

@panteliselef we need to load when user in signedIn because users can connect the wallet through <UserProfile />

Instead of lazy loading the Coinbase SDK in getEthereumProvider(), move loading when the SignIn/SignUp components mount. This fix avoid the Safari to block the Coinbase popup
@nikospapcom nikospapcom force-pushed the nikospap/user-1159-safari-blocks-coinbase-wallet-popup branch from c5315fd to a83056f Compare December 17, 2024 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants