-
Notifications
You must be signed in to change notification settings - Fork 18
fix: production build lazyload walletconnect #260
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
+129
−25
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,28 +1,149 @@ | ||
| import { createAppKit } from "@reown/appkit/vue"; | ||
| import { WagmiAdapter } from "@reown/appkit-adapter-wagmi"; | ||
|
|
||
| // Singleton initialization state | ||
| let initializationPromise: Promise<void> | null = null; | ||
| let wagmiAdapterInstance: WagmiAdapter | null = null; | ||
|
|
||
| // Cached metadata and chain configuration | ||
| let cachedMetadata: ReturnType<typeof createMetadata> | null = null; | ||
| let cachedPlainChain: ReturnType<typeof createPlainChain> | null = null; | ||
|
|
||
| /** | ||
| * Creates metadata configuration for AppKit. | ||
| * Cached to avoid recreation on every call. | ||
| */ | ||
| function createMetadata(origin: string) { | ||
| if (!cachedMetadata) { | ||
| cachedMetadata = { | ||
| name: "ZKsync SSO Auth Server", | ||
| description: "ZKsync SSO Auth Server", | ||
| url: origin, | ||
| icons: [`${origin}/icon-512.png`], | ||
| }; | ||
| } | ||
| return cachedMetadata; | ||
| } | ||
|
|
||
| /** | ||
| * Creates plain chain object to avoid Viem Proxy serialization issues. | ||
| * Cached to avoid recreation and unnecessary property access on defaultChain. | ||
| */ | ||
| function createPlainChain(defaultChain: ReturnType<typeof useClientStore>["defaultChain"]) { | ||
| if (!cachedPlainChain) { | ||
| cachedPlainChain = { | ||
| id: defaultChain.id, | ||
| name: defaultChain.name, | ||
| nativeCurrency: { | ||
| name: defaultChain.nativeCurrency.name, | ||
| symbol: defaultChain.nativeCurrency.symbol, | ||
| decimals: defaultChain.nativeCurrency.decimals, | ||
| }, | ||
| rpcUrls: { | ||
| default: { | ||
| http: [...defaultChain.rpcUrls.default.http], | ||
| }, | ||
| }, | ||
| blockExplorers: defaultChain.blockExplorers | ||
| ? { | ||
| default: { | ||
| name: defaultChain.blockExplorers.default.name, | ||
| url: defaultChain.blockExplorers.default.url, | ||
| }, | ||
| } | ||
| : undefined, | ||
| }; | ||
| } | ||
| return cachedPlainChain; | ||
| } | ||
cpb8010 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /** | ||
| * Initializes AppKit with proper singleton pattern to prevent race conditions. | ||
| * Uses Promise-based locking to ensure only one initialization occurs. | ||
| */ | ||
| async function initializeAppKit( | ||
| projectId: string, | ||
| metadata: ReturnType<typeof createMetadata>, | ||
| plainChain: ReturnType<typeof createPlainChain>, | ||
| ) { | ||
| if (initializationPromise) { | ||
| // Another initialization is in progress, wait for it | ||
| await initializationPromise; | ||
| return; | ||
| } | ||
|
|
||
| if (wagmiAdapterInstance) { | ||
| // Already initialized | ||
| return; | ||
| } | ||
|
|
||
| // Create new initialization promise | ||
| initializationPromise = (async () => { | ||
| try { | ||
| wagmiAdapterInstance = new WagmiAdapter({ | ||
| networks: [plainChain], | ||
| projectId, | ||
| }); | ||
|
|
||
| createAppKit({ | ||
| adapters: [wagmiAdapterInstance], | ||
| networks: [plainChain], | ||
| projectId, | ||
| metadata, | ||
| }); | ||
| } catch (error) { | ||
| console.warn("Failed to initialize AppKit:", error); | ||
| wagmiAdapterInstance = null; | ||
| throw error; | ||
| } finally { | ||
| initializationPromise = null; | ||
| } | ||
| })(); | ||
|
|
||
| await initializationPromise; | ||
| } | ||
|
|
||
| /** | ||
| * Composable for accessing AppKit functionality. | ||
| * Implements lazy initialization on first call to avoid SSR issues. | ||
| * | ||
| * Note: wagmiConfig and wagmiAdapter may be null/undefined during SSR or before | ||
| * the first client-side call. Consuming code should handle these cases. | ||
| */ | ||
| export const useAppKit = () => { | ||
| const runtimeConfig = useRuntimeConfig(); | ||
| const { defaultChain } = useClientStore(); | ||
|
|
||
| const projectId = runtimeConfig.public.appKitProjectId; | ||
| const metadata = { | ||
| name: "ZKsync SSO Auth Server", | ||
| description: "ZKsync SSO Auth Server", | ||
| url: window.location.origin, | ||
| icons: [new URL("/icon-512.png", window.location.origin).toString()], | ||
| }; | ||
| const origin = typeof window !== "undefined" ? window.location.origin : "https://auth.zksync.dev"; | ||
cpb8010 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| const wagmiAdapter = new WagmiAdapter({ | ||
| networks: [defaultChain], | ||
| projectId, | ||
| }); | ||
| const metadata = createMetadata(origin); | ||
| const plainChain = createPlainChain(defaultChain); | ||
|
|
||
| const wagmiConfig = wagmiAdapter.wagmiConfig; | ||
| // Lazy initialization - only create AppKit when first used on client | ||
| if (typeof window !== "undefined" && !wagmiAdapterInstance && !initializationPromise) { | ||
| // Fire and forget - initialization happens asynchronously | ||
| initializeAppKit(projectId, metadata, plainChain).catch((error) => { | ||
| console.warn("AppKit initialization failed:", error); | ||
| }); | ||
| } | ||
cpb8010 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const wagmiConfig = wagmiAdapterInstance?.wagmiConfig; | ||
|
|
||
| return { | ||
| metadata, | ||
| projectId, | ||
| wagmiAdapter, | ||
| wagmiAdapter: wagmiAdapterInstance, | ||
| wagmiConfig, | ||
| }; | ||
cpb8010 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }; | ||
|
|
||
| // HMR cleanup - reset state on hot module replacement | ||
| if (import.meta.hot) { | ||
| import.meta.hot.dispose(() => { | ||
| initializationPromise = null; | ||
| wagmiAdapterInstance = null; | ||
| cachedMetadata = null; | ||
| cachedPlainChain = null; | ||
| }); | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.