@walletconnect/ethereum-provider 2.19.2 → 2.19.4-canary-ak-1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,7 +15,8 @@ import { EthereumProvider } from "@walletconnect/ethereum-provider";
15
15
 
16
16
  const provider = await EthereumProvider.init({
17
17
  projectId, // REQUIRED your projectId
18
- chains, // REQUIRED chain ids
18
+ chains, // DEPRECATED, use `optionalChains` instead
19
+ optionalChains, // REQUIRED optional chain ids e.g. 1 (Ethereum), 10 (Optimism), 42161 (Arbitrum)
19
20
  showQrModal, // REQUIRED set to "true" to use @walletconnect/modal,
20
21
  methods, // OPTIONAL ethereum methods
21
22
  events, // OPTIONAL ethereum events
@@ -82,3 +83,142 @@ provider.on("disconnect", handler);
82
83
  ## Supported WalletConnectModal options (qrModalOptions)
83
84
 
84
85
  Please reference [up to date documentation](https://docs.walletconnect.com/2.0/web/web3modal/html/ethereum-provider/options) for `WalletConnectModal`
86
+
87
+ ## Usage with SSR Frameworks (e.g., Next.js)
88
+
89
+ The Ethereum Provider interacts with browser-specific APIs (like `window`, `document`, `localStorage`) which are not available during Server-Side Rendering (SSR). Attempting to import or initialize the provider directly in code that runs on the server will cause errors (e.g., `ReferenceError: HTMLElement is not defined`).
90
+
91
+ To use `@walletconnect/ethereum-provider` with frameworks like Next.js (using the App Router or Pages Router), you must ensure that the library is only imported and used on the client-side.
92
+
93
+ **Recommended Approach (Next.js):**
94
+
95
+ 1. **Isolate Usage:** Create a dedicated React component (e.g., `WalletConnectProvider.tsx` or `Web3Provider.tsx`) that handles the initialization and interaction with the `EthereumProvider`. Mark this component as a Client Component using the `"use client";` directive at the top of the file.
96
+ 2. **Dynamic Import:** In the parent component (which could be a Server Component page or another Client Component), import your dedicated component dynamically with SSR disabled.
97
+
98
+ **Example (`src/app/page.tsx` or similar):**
99
+
100
+ ```typescript
101
+ // src/app/page.tsx (or your main layout/page)
102
+ "use client"; // Required if the page itself uses the dynamic import directly
103
+
104
+ import dynamic from 'next/dynamic';
105
+ import { Suspense } from 'react'; // Optional: Add loading UI
106
+
107
+ // Dynamically import the component that uses EthereumProvider
108
+ const WalletConnectLogic = dynamic(
109
+ () => import('@/components/WalletConnectLogic'), // Path to your client component
110
+ {
111
+ ssr: false, // This is crucial to prevent server-side execution
112
+ // Optional: Display a loading state while the component is loading
113
+ // loading: () => <p>Loading WalletConnect...</p>,
114
+ }
115
+ );
116
+
117
+ export default function Home() {
118
+ return (
119
+ <div>
120
+ {/* Other page content */}
121
+ <Suspense fallback={<p>Loading WalletConnect...</p>}> {/* Optional Suspense boundary */}
122
+ <WalletConnectLogic />
123
+ </Suspense>
124
+ {/* Other page content */}
125
+ </div>
126
+ );
127
+ }
128
+ ```
129
+
130
+ **Example (`src/components/WalletConnectLogic.tsx`):**
131
+
132
+ ```typescript
133
+ // src/components/WalletConnectLogic.tsx
134
+ "use client"; // Mark this component as client-side only
135
+
136
+ import { EthereumProvider } from "@walletconnect/ethereum-provider";
137
+ import { useEffect, useState, useCallback } from "react";
138
+
139
+ // Your WalletConnect Project ID
140
+ const projectId = process.env.NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID!;
141
+
142
+ let provider: Awaited<ReturnType<typeof EthereumProvider.init>> | null = null;
143
+
144
+ export default function WalletConnectLogic() {
145
+ const [account, setAccount] = useState<string | null>(null);
146
+ // ... other state (isConnected, chainId, etc.)
147
+
148
+ const initialize = useCallback(async () => {
149
+ if (!projectId) {
150
+ throw new Error("Missing NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID");
151
+ }
152
+ if (provider) return; // Already initialized
153
+
154
+ try {
155
+ provider = await EthereumProvider.init({
156
+ projectId: projectId,
157
+ optionalChains: [1, 10, 137], // Example chains
158
+ showQrModal: true,
159
+ metadata: { /* ... your metadata ... */ }
160
+ // ... other options
161
+ });
162
+
163
+ // --- Add event listeners ---
164
+ provider.on("connect", (info: { chainId: string }) => {
165
+ console.log("connect", info);
166
+ // Set initial account/chain state
167
+ });
168
+ provider.on("accountsChanged", (accounts: string[]) => {
169
+ console.log("accountsChanged", accounts);
170
+ setAccount(accounts[0] ?? null);
171
+ });
172
+ // ... other listeners (disconnect, chainChanged)
173
+
174
+ // Check for existing session
175
+ if (provider.session && provider.accounts.length > 0) {
176
+ setAccount(provider.accounts[0]);
177
+ // set chainId, isConnected etc.
178
+ }
179
+
180
+ } catch (error) {
181
+ console.error("Failed to initialize WalletConnect Provider", error);
182
+ }
183
+ }, []);
184
+
185
+ useEffect(() => {
186
+ // Initialize provider on component mount (client-side)
187
+ initialize();
188
+
189
+ // Optional: Cleanup listeners on unmount
190
+ return () => {
191
+ // provider?.off(...);
192
+ };
193
+ }, [initialize]);
194
+
195
+ const connectWallet = useCallback(async () => {
196
+ if (!provider) {
197
+ console.error("Provider not initialized");
198
+ return;
199
+ }
200
+ try {
201
+ await provider.connect();
202
+ } catch (error) {
203
+ console.error("Failed to connect:", error);
204
+ }
205
+ }, []);
206
+
207
+ // ... other functions (disconnect, signMessage, etc.)
208
+
209
+ return (
210
+ <div>
211
+ {/* Your Connect/Disconnect buttons, account display, etc. */}
212
+ {!account ? (
213
+ <button onClick={connectWallet}>Connect Wallet</button>
214
+ ) : (
215
+ <p>Connected: {account}</p>
216
+ )}
217
+ {/* ... */}
218
+ </div>
219
+ );
220
+ }
221
+
222
+ ```
223
+
224
+ This pattern ensures the provider code only runs in the browser, avoiding SSR compatibility issues. Similar approaches (lazy loading components that use browser APIs) exist for other SSR frameworks.