@b3dotfun/sdk 0.1.68-alpha.10 → 0.1.68-alpha.11

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.
@@ -147,8 +147,9 @@ function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
147
147
  }
148
148
  }, [activeWallet, partnerId, authenticate, setIsAuthenticated, setIsAuthenticating, setUser, setHasStartedConnecting]);
149
149
  const logout = (0, react_2.useCallback)(async (callback) => {
150
- // Only disconnect ecosystem/smart wallets, preserve EOA wallets (e.g. MetaMask)
151
- // so they remain available after re-login.
150
+ // Disconnect ecosystem/smart wallets from the connected wallets list.
151
+ // EOA wallets (MetaMask, Coinbase Wallet) are left in the list so they can
152
+ // auto-reconnect on next login without requiring a new approval popup.
152
153
  // Use walletsRef.current (not the stale closure value) so we always get current wallets —
153
154
  // autoConnectCore captures logout from the first render when wallets is still [].
154
155
  walletsRef.current.forEach(wallet => {
@@ -157,18 +158,25 @@ function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
157
158
  disconnect(wallet);
158
159
  }
159
160
  });
160
- // Always disconnect the active wallet to clear thirdweb's activeAccountStore.
161
- // Without this, any auto-reconnected wallet (e.g. Coinbase Wallet, MetaMask)
162
- // keeps activeAccount set, and ConnectEmbed renders show=false (blank modal).
161
+ // Unconditionally disconnect the active wallet to clear thirdweb's activeAccountStore.
162
+ // This is separate from the loop above: even if the active wallet is an EOA (e.g.
163
+ // Coinbase Wallet), we must disconnect it so activeAccount becomes undefined.
164
+ // Without this, ConnectEmbed renders show=false (blank modal) because it checks
165
+ // show = !activeAccount. Note: thirdweb's disconnect() is idempotent — calling it
166
+ // on an already-disconnected wallet (from the loop above) is a no-op.
163
167
  // We use the exact reference from activeWalletRef because thirdweb's
164
168
  // onWalletDisconnect uses strict identity (===) to decide whether to clear
165
169
  // activeAccountStore.
170
+ // Tradeoff: EOA wallets (MetaMask, Coinbase Wallet) will be removed from
171
+ // connectedWallets and require a new approval popup on next login.
172
+ // This is acceptable because a working login form is more critical than
173
+ // skipping one wallet approval step.
166
174
  if (activeWalletRef.current) {
167
175
  debug("@@logout:disconnecting active wallet", activeWalletRef.current.id);
168
176
  disconnect(activeWalletRef.current);
169
177
  }
170
- // Clear user-specific storage but preserve wallet connection state
171
- // so EOA wallets (e.g. MetaMask) can auto-reconnect on next login
178
+ // Clear user-specific storage (auth tokens, cached user data).
179
+ // Thirdweb's wallet connection state is managed separately via disconnect() above.
172
180
  if (typeof localStorage !== "undefined") {
173
181
  localStorage.removeItem("lastAuthProvider");
174
182
  localStorage.removeItem("b3-user");
@@ -192,19 +200,19 @@ function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
192
200
  [disconnect, setIsAuthenticated, setIsAuthenticating, setUser, setIsConnected, onLogoutCallback]);
193
201
  const onConnect = (0, react_2.useCallback)(async (_walleAutoConnectedWith, allConnectedWallets) => {
194
202
  debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
195
- const ecosystemWalletToDisconnect = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
203
+ const connectedEcosystemWallet = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
196
204
  try {
197
- if (!ecosystemWalletToDisconnect) {
205
+ if (!connectedEcosystemWallet) {
198
206
  throw new Error("No smart wallet found during auto-connect");
199
207
  }
200
- debug("@@useAuthentication:onConnect", { wallet: ecosystemWalletToDisconnect });
208
+ debug("@@useAuthentication:onConnect", { wallet: connectedEcosystemWallet });
201
209
  setHasStartedConnecting(true);
202
210
  setIsConnected(true);
203
211
  setIsAuthenticating(true);
204
- await setActiveWallet(ecosystemWalletToDisconnect);
205
- const userAuth = await authenticateUser(ecosystemWalletToDisconnect);
212
+ await setActiveWallet(connectedEcosystemWallet);
213
+ const userAuth = await authenticateUser(connectedEcosystemWallet);
206
214
  if (userAuth && onConnectCallback) {
207
- await onConnectCallback(ecosystemWalletToDisconnect, userAuth.accessToken);
215
+ await onConnectCallback(connectedEcosystemWallet, userAuth.accessToken);
208
216
  }
209
217
  }
210
218
  catch (error) {
@@ -215,17 +223,21 @@ function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
215
223
  // We can't rely on logout()'s activeWalletRef here because it's updated
216
224
  // via useEffect (deferred until after paint), but this callback may run
217
225
  // entirely within a single React commit cycle — before the ref updates.
218
- if (ecosystemWalletToDisconnect) {
219
- debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", ecosystemWalletToDisconnect.id);
220
- disconnect(ecosystemWalletToDisconnect);
226
+ // Note: logout() below may also call disconnect() on the same wallet via
227
+ // activeWalletRef — thirdweb's disconnect() is idempotent so this is safe.
228
+ if (connectedEcosystemWallet) {
229
+ debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", connectedEcosystemWallet.id);
230
+ disconnect(connectedEcosystemWallet);
221
231
  }
222
232
  // Also disconnect the wallet that autoConnectCore set as active.
223
233
  // When only a non-ecosystem wallet (e.g. MetaMask) auto-reconnects,
224
- // ecosystemWalletToDisconnect is undefined, so the block above is skipped.
234
+ // connectedEcosystemWallet is undefined, so the block above is skipped.
225
235
  // But autoConnectCore already set this wallet as thirdweb's activeWallet,
226
236
  // leaving activeAccount set. ConnectEmbed checks show = !activeAccount,
227
237
  // so if we don't clear it, the login form renders blank.
228
- if (_walleAutoConnectedWith && _walleAutoConnectedWith !== ecosystemWalletToDisconnect) {
238
+ // Uses object identity (===) which is safe because thirdweb returns
239
+ // stable references for connected wallet instances.
240
+ if (_walleAutoConnectedWith && _walleAutoConnectedWith !== connectedEcosystemWallet) {
229
241
  debug("@@useAuthentication:onConnect:disconnecting auto-connected wallet", _walleAutoConnectedWith.id);
230
242
  disconnect(_walleAutoConnectedWith);
231
243
  }
@@ -141,8 +141,9 @@ export function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
141
141
  }
142
142
  }, [activeWallet, partnerId, authenticate, setIsAuthenticated, setIsAuthenticating, setUser, setHasStartedConnecting]);
143
143
  const logout = useCallback(async (callback) => {
144
- // Only disconnect ecosystem/smart wallets, preserve EOA wallets (e.g. MetaMask)
145
- // so they remain available after re-login.
144
+ // Disconnect ecosystem/smart wallets from the connected wallets list.
145
+ // EOA wallets (MetaMask, Coinbase Wallet) are left in the list so they can
146
+ // auto-reconnect on next login without requiring a new approval popup.
146
147
  // Use walletsRef.current (not the stale closure value) so we always get current wallets —
147
148
  // autoConnectCore captures logout from the first render when wallets is still [].
148
149
  walletsRef.current.forEach(wallet => {
@@ -151,18 +152,25 @@ export function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
151
152
  disconnect(wallet);
152
153
  }
153
154
  });
154
- // Always disconnect the active wallet to clear thirdweb's activeAccountStore.
155
- // Without this, any auto-reconnected wallet (e.g. Coinbase Wallet, MetaMask)
156
- // keeps activeAccount set, and ConnectEmbed renders show=false (blank modal).
155
+ // Unconditionally disconnect the active wallet to clear thirdweb's activeAccountStore.
156
+ // This is separate from the loop above: even if the active wallet is an EOA (e.g.
157
+ // Coinbase Wallet), we must disconnect it so activeAccount becomes undefined.
158
+ // Without this, ConnectEmbed renders show=false (blank modal) because it checks
159
+ // show = !activeAccount. Note: thirdweb's disconnect() is idempotent — calling it
160
+ // on an already-disconnected wallet (from the loop above) is a no-op.
157
161
  // We use the exact reference from activeWalletRef because thirdweb's
158
162
  // onWalletDisconnect uses strict identity (===) to decide whether to clear
159
163
  // activeAccountStore.
164
+ // Tradeoff: EOA wallets (MetaMask, Coinbase Wallet) will be removed from
165
+ // connectedWallets and require a new approval popup on next login.
166
+ // This is acceptable because a working login form is more critical than
167
+ // skipping one wallet approval step.
160
168
  if (activeWalletRef.current) {
161
169
  debug("@@logout:disconnecting active wallet", activeWalletRef.current.id);
162
170
  disconnect(activeWalletRef.current);
163
171
  }
164
- // Clear user-specific storage but preserve wallet connection state
165
- // so EOA wallets (e.g. MetaMask) can auto-reconnect on next login
172
+ // Clear user-specific storage (auth tokens, cached user data).
173
+ // Thirdweb's wallet connection state is managed separately via disconnect() above.
166
174
  if (typeof localStorage !== "undefined") {
167
175
  localStorage.removeItem("lastAuthProvider");
168
176
  localStorage.removeItem("b3-user");
@@ -186,19 +194,19 @@ export function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
186
194
  [disconnect, setIsAuthenticated, setIsAuthenticating, setUser, setIsConnected, onLogoutCallback]);
187
195
  const onConnect = useCallback(async (_walleAutoConnectedWith, allConnectedWallets) => {
188
196
  debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
189
- const ecosystemWalletToDisconnect = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
197
+ const connectedEcosystemWallet = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
190
198
  try {
191
- if (!ecosystemWalletToDisconnect) {
199
+ if (!connectedEcosystemWallet) {
192
200
  throw new Error("No smart wallet found during auto-connect");
193
201
  }
194
- debug("@@useAuthentication:onConnect", { wallet: ecosystemWalletToDisconnect });
202
+ debug("@@useAuthentication:onConnect", { wallet: connectedEcosystemWallet });
195
203
  setHasStartedConnecting(true);
196
204
  setIsConnected(true);
197
205
  setIsAuthenticating(true);
198
- await setActiveWallet(ecosystemWalletToDisconnect);
199
- const userAuth = await authenticateUser(ecosystemWalletToDisconnect);
206
+ await setActiveWallet(connectedEcosystemWallet);
207
+ const userAuth = await authenticateUser(connectedEcosystemWallet);
200
208
  if (userAuth && onConnectCallback) {
201
- await onConnectCallback(ecosystemWalletToDisconnect, userAuth.accessToken);
209
+ await onConnectCallback(connectedEcosystemWallet, userAuth.accessToken);
202
210
  }
203
211
  }
204
212
  catch (error) {
@@ -209,17 +217,21 @@ export function useAuthentication(partnerId, { skipAutoConnect = false } = {}) {
209
217
  // We can't rely on logout()'s activeWalletRef here because it's updated
210
218
  // via useEffect (deferred until after paint), but this callback may run
211
219
  // entirely within a single React commit cycle — before the ref updates.
212
- if (ecosystemWalletToDisconnect) {
213
- debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", ecosystemWalletToDisconnect.id);
214
- disconnect(ecosystemWalletToDisconnect);
220
+ // Note: logout() below may also call disconnect() on the same wallet via
221
+ // activeWalletRef — thirdweb's disconnect() is idempotent so this is safe.
222
+ if (connectedEcosystemWallet) {
223
+ debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", connectedEcosystemWallet.id);
224
+ disconnect(connectedEcosystemWallet);
215
225
  }
216
226
  // Also disconnect the wallet that autoConnectCore set as active.
217
227
  // When only a non-ecosystem wallet (e.g. MetaMask) auto-reconnects,
218
- // ecosystemWalletToDisconnect is undefined, so the block above is skipped.
228
+ // connectedEcosystemWallet is undefined, so the block above is skipped.
219
229
  // But autoConnectCore already set this wallet as thirdweb's activeWallet,
220
230
  // leaving activeAccount set. ConnectEmbed checks show = !activeAccount,
221
231
  // so if we don't clear it, the login form renders blank.
222
- if (_walleAutoConnectedWith && _walleAutoConnectedWith !== ecosystemWalletToDisconnect) {
232
+ // Uses object identity (===) which is safe because thirdweb returns
233
+ // stable references for connected wallet instances.
234
+ if (_walleAutoConnectedWith && _walleAutoConnectedWith !== connectedEcosystemWallet) {
223
235
  debug("@@useAuthentication:onConnect:disconnecting auto-connected wallet", _walleAutoConnectedWith.id);
224
236
  disconnect(_walleAutoConnectedWith);
225
237
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@b3dotfun/sdk",
3
- "version": "0.1.68-alpha.10",
3
+ "version": "0.1.68-alpha.11",
4
4
  "source": "src/index.ts",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "react-native": "./dist/cjs/index.native.js",
@@ -168,8 +168,9 @@ export function useAuthentication(partnerId: string, { skipAutoConnect = false }
168
168
 
169
169
  const logout = useCallback(
170
170
  async (callback?: () => void) => {
171
- // Only disconnect ecosystem/smart wallets, preserve EOA wallets (e.g. MetaMask)
172
- // so they remain available after re-login.
171
+ // Disconnect ecosystem/smart wallets from the connected wallets list.
172
+ // EOA wallets (MetaMask, Coinbase Wallet) are left in the list so they can
173
+ // auto-reconnect on next login without requiring a new approval popup.
173
174
  // Use walletsRef.current (not the stale closure value) so we always get current wallets —
174
175
  // autoConnectCore captures logout from the first render when wallets is still [].
175
176
  walletsRef.current.forEach(wallet => {
@@ -179,19 +180,26 @@ export function useAuthentication(partnerId: string, { skipAutoConnect = false }
179
180
  }
180
181
  });
181
182
 
182
- // Always disconnect the active wallet to clear thirdweb's activeAccountStore.
183
- // Without this, any auto-reconnected wallet (e.g. Coinbase Wallet, MetaMask)
184
- // keeps activeAccount set, and ConnectEmbed renders show=false (blank modal).
183
+ // Unconditionally disconnect the active wallet to clear thirdweb's activeAccountStore.
184
+ // This is separate from the loop above: even if the active wallet is an EOA (e.g.
185
+ // Coinbase Wallet), we must disconnect it so activeAccount becomes undefined.
186
+ // Without this, ConnectEmbed renders show=false (blank modal) because it checks
187
+ // show = !activeAccount. Note: thirdweb's disconnect() is idempotent — calling it
188
+ // on an already-disconnected wallet (from the loop above) is a no-op.
185
189
  // We use the exact reference from activeWalletRef because thirdweb's
186
190
  // onWalletDisconnect uses strict identity (===) to decide whether to clear
187
191
  // activeAccountStore.
192
+ // Tradeoff: EOA wallets (MetaMask, Coinbase Wallet) will be removed from
193
+ // connectedWallets and require a new approval popup on next login.
194
+ // This is acceptable because a working login form is more critical than
195
+ // skipping one wallet approval step.
188
196
  if (activeWalletRef.current) {
189
197
  debug("@@logout:disconnecting active wallet", activeWalletRef.current.id);
190
198
  disconnect(activeWalletRef.current);
191
199
  }
192
200
 
193
- // Clear user-specific storage but preserve wallet connection state
194
- // so EOA wallets (e.g. MetaMask) can auto-reconnect on next login
201
+ // Clear user-specific storage (auth tokens, cached user data).
202
+ // Thirdweb's wallet connection state is managed separately via disconnect() above.
195
203
  if (typeof localStorage !== "undefined") {
196
204
  localStorage.removeItem("lastAuthProvider");
197
205
  localStorage.removeItem("b3-user");
@@ -221,21 +229,21 @@ export function useAuthentication(partnerId: string, { skipAutoConnect = false }
221
229
  const onConnect = useCallback(
222
230
  async (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => {
223
231
  debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
224
- const ecosystemWalletToDisconnect = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
232
+ const connectedEcosystemWallet = allConnectedWallets.find(w => w.id.startsWith("ecosystem."));
225
233
  try {
226
- if (!ecosystemWalletToDisconnect) {
234
+ if (!connectedEcosystemWallet) {
227
235
  throw new Error("No smart wallet found during auto-connect");
228
236
  }
229
237
 
230
- debug("@@useAuthentication:onConnect", { wallet: ecosystemWalletToDisconnect });
238
+ debug("@@useAuthentication:onConnect", { wallet: connectedEcosystemWallet });
231
239
  setHasStartedConnecting(true);
232
240
  setIsConnected(true);
233
241
  setIsAuthenticating(true);
234
- await setActiveWallet(ecosystemWalletToDisconnect);
235
- const userAuth = await authenticateUser(ecosystemWalletToDisconnect);
242
+ await setActiveWallet(connectedEcosystemWallet);
243
+ const userAuth = await authenticateUser(connectedEcosystemWallet);
236
244
 
237
245
  if (userAuth && onConnectCallback) {
238
- await onConnectCallback(ecosystemWalletToDisconnect, userAuth.accessToken);
246
+ await onConnectCallback(connectedEcosystemWallet, userAuth.accessToken);
239
247
  }
240
248
  } catch (error) {
241
249
  debug("@@useAuthentication:onConnect:failed", { error });
@@ -245,17 +253,21 @@ export function useAuthentication(partnerId: string, { skipAutoConnect = false }
245
253
  // We can't rely on logout()'s activeWalletRef here because it's updated
246
254
  // via useEffect (deferred until after paint), but this callback may run
247
255
  // entirely within a single React commit cycle — before the ref updates.
248
- if (ecosystemWalletToDisconnect) {
249
- debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", ecosystemWalletToDisconnect.id);
250
- disconnect(ecosystemWalletToDisconnect);
256
+ // Note: logout() below may also call disconnect() on the same wallet via
257
+ // activeWalletRef — thirdweb's disconnect() is idempotent so this is safe.
258
+ if (connectedEcosystemWallet) {
259
+ debug("@@useAuthentication:onConnect:disconnecting ecosystem wallet", connectedEcosystemWallet.id);
260
+ disconnect(connectedEcosystemWallet);
251
261
  }
252
262
  // Also disconnect the wallet that autoConnectCore set as active.
253
263
  // When only a non-ecosystem wallet (e.g. MetaMask) auto-reconnects,
254
- // ecosystemWalletToDisconnect is undefined, so the block above is skipped.
264
+ // connectedEcosystemWallet is undefined, so the block above is skipped.
255
265
  // But autoConnectCore already set this wallet as thirdweb's activeWallet,
256
266
  // leaving activeAccount set. ConnectEmbed checks show = !activeAccount,
257
267
  // so if we don't clear it, the login form renders blank.
258
- if (_walleAutoConnectedWith && _walleAutoConnectedWith !== ecosystemWalletToDisconnect) {
268
+ // Uses object identity (===) which is safe because thirdweb returns
269
+ // stable references for connected wallet instances.
270
+ if (_walleAutoConnectedWith && _walleAutoConnectedWith !== connectedEcosystemWallet) {
259
271
  debug("@@useAuthentication:onConnect:disconnecting auto-connected wallet", _walleAutoConnectedWith.id);
260
272
  disconnect(_walleAutoConnectedWith);
261
273
  }