@b3dotfun/sdk 0.0.82-alpha.0 → 0.0.82-alpha.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.
@@ -4,13 +4,9 @@ import { toast, useAccountWallet, WalletImage } from "@b3dotfun/sdk/global-accou
4
4
  import { cn } from "@b3dotfun/sdk/shared/utils/cn";
5
5
  import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
6
6
  import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
7
- import { WalletCoinbase, WalletMetamask, WalletRainbow, WalletWalletConnect } from "@web3icons/react";
8
7
  import { ChevronLeft, ChevronRightCircle, Wallet, X, ZapIcon } from "lucide-react";
9
- import { useState } from "react";
10
- import { createPortal } from "react-dom";
11
- import { useSetActiveWallet, useWalletInfo } from "thirdweb/react";
12
- import { createWallet, WalletId } from "thirdweb/wallets";
13
- import { useAccount, useConnect, useDisconnect, useWalletClient } from "wagmi";
8
+ import { useConnectModal, useSetActiveWallet, useWalletInfo } from "thirdweb/react";
9
+ import { useAccount, useDisconnect } from "wagmi";
14
10
  import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
15
11
 
16
12
  export enum CryptoPaymentMethodType {
@@ -37,126 +33,28 @@ export function CryptoPaymentMethod({
37
33
  }: CryptoPaymentMethodProps) {
38
34
  const { connectedEOAWallet: connectedEOAWallet, connectedSmartWallet: connectedSmartWallet } = useAccountWallet();
39
35
  const { connector, address } = useAccount();
40
- const { connect, connectors, isPending } = useConnect();
41
36
  const { disconnect } = useDisconnect();
42
- const { data: walletClient } = useWalletClient();
43
- const [showWalletModal, setShowWalletModal] = useState(false);
37
+ const { connect: openConnectModal } = useConnectModal();
44
38
  const setActiveWallet = useSetActiveWallet();
45
39
  const { data: eoaWalletInfo } = useWalletInfo(connectedEOAWallet?.id);
46
40
 
47
- const isConnected = !!connectedEOAWallet;
48
41
  const globalAddress = connectedSmartWallet?.getAccount()?.address;
49
42
 
50
43
  // Use custom hook to determine wallet display logic
51
44
  const { shouldShowConnectedEOA, shouldShowWagmiWallet } = useConnectedWalletDisplay(selectedPaymentMethod);
52
- console.log("shouldShowWagmiWallet :", shouldShowWagmiWallet);
53
45
 
54
- // Map wagmi connector names to thirdweb wallet IDs
55
- const getThirdwebWalletId = (connectorName: string): WalletId | null => {
56
- const walletMap: Record<string, WalletId> = {
57
- MetaMask: "io.metamask",
58
- "Coinbase Wallet": "com.coinbase.wallet",
59
- Rainbow: "me.rainbow",
60
- WalletConnect: "walletConnect",
61
- Phantom: "app.phantom",
62
- };
63
- return walletMap[connectorName] || null;
64
- };
65
-
66
- // Create thirdweb wallet from wagmi connector
67
- const createThirdwebWalletFromConnector = async (connectorName: string) => {
68
- const walletId = getThirdwebWalletId(connectorName);
69
- if (!walletId) {
70
- console.warn(`No thirdweb wallet ID found for connector: ${connectorName}`);
71
- return null;
72
- }
73
-
74
- try {
75
- const thirdwebWallet = createWallet(walletId);
76
- // Connect the wallet to sync with the existing wagmi connection
77
- await thirdwebWallet.connect({ client });
78
- return thirdwebWallet;
79
- } catch (error) {
80
- console.error(`Failed to create thirdweb wallet for ${connectorName}:`, error);
81
- return null;
82
- }
83
- };
84
-
85
- // Define available wallet connectors
86
- const availableConnectors = connectors.filter(connector =>
87
- ["MetaMask", "WalletConnect", "Coinbase Wallet", "Rainbow", "Phantom"].includes(connector.name),
88
- );
89
-
90
- // Define wallet options with icons and info
91
- const walletOptions = [
92
- {
93
- id: "metamask",
94
- name: "MetaMask",
95
- icon: <WalletMetamask size={48} />,
96
- description: "Connect using MetaMask browser extension",
97
- connector: availableConnectors.find(c => c.name === "MetaMask"),
98
- },
99
- {
100
- id: "coinbase",
101
- name: "Coinbase Wallet",
102
- icon: <WalletCoinbase size={48} />,
103
- description: "Connect using Coinbase Wallet",
104
- connector: availableConnectors.find(c => c.name === "Coinbase Wallet"),
105
- },
106
- {
107
- id: "rainbow",
108
- name: "Rainbow",
109
- icon: <WalletRainbow size={48} />,
110
- description: "Connect using Rainbow wallet",
111
- connector: availableConnectors.find(c => c.name === "Rainbow"),
112
- },
113
- {
114
- id: "walletconnect",
115
- name: "WalletConnect",
116
- icon: <WalletWalletConnect size={48} />,
117
- description: "Connect using WalletConnect protocol",
118
- connector: availableConnectors.find(c => c.name === "WalletConnect"),
119
- },
120
- ].filter(wallet => wallet.connector); // Only show wallets that have available connectors
121
-
122
- // Reset modal state when closing
123
- const handleCloseModal = () => {
124
- setShowWalletModal(false);
125
- };
126
-
127
- // Function to request wallet permissions for specific wallet
128
- const requestWalletPermissions = async (walletConnector?: any) => {
46
+ // Handle wallet connection using thirdweb modal
47
+ const handleConnectWallet = async () => {
129
48
  try {
130
- // If a specific wallet connector is provided and it's different from current
131
- if (walletConnector && connector?.name !== walletConnector.name) {
132
- // Disconnect current and connect to the selected wallet
133
- // if (isConnected) {
134
- // disconnect();
135
- // // Small delay to ensure disconnection
136
- // await new Promise(resolve => setTimeout(resolve, 100));
137
- // }
138
- await connect({ connector: walletConnector });
139
- setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
140
- onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
141
- toast.success(`Connected to ${walletConnector.name}`);
142
- return;
143
- }
144
-
145
- // If same wallet or no specific wallet, request permissions for account switching
146
- if (walletClient && "request" in walletClient) {
147
- await walletClient.request({
148
- method: "wallet_requestPermissions",
149
- params: [{ eth_accounts: {} }],
150
- });
151
- toast.success("Account selection completed");
49
+ const wallet = await openConnectModal({ client, setActive: false });
50
+ if (wallet) {
51
+ // setActiveWallet(wallet);
152
52
  setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
153
53
  onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
154
- } else {
155
- // Fallback: show modal for manual wallet selection
156
- setShowWalletModal(true);
54
+ toast.success("Wallet connected");
157
55
  }
158
56
  } catch (error) {
159
- console.error("Failed to request wallet permissions:", error);
57
+ console.error("Failed to connect wallet:", error);
160
58
  if (error && typeof error === "object" && "message" in error) {
161
59
  const errorMessage = (error as any).message.toLowerCase();
162
60
  if (
@@ -164,12 +62,10 @@ export function CryptoPaymentMethod({
164
62
  errorMessage.includes("denied") ||
165
63
  errorMessage.includes("cancelled")
166
64
  ) {
167
- toast.error("Account selection cancelled");
65
+ // User cancelled - no toast needed
168
66
  } else {
169
- toast.error("Failed to open account selection");
67
+ toast.error("Failed to connect wallet");
170
68
  }
171
- } else {
172
- toast.error("Failed to open account selection");
173
69
  }
174
70
  }
175
71
  };
@@ -297,18 +193,9 @@ export function CryptoPaymentMethod({
297
193
 
298
194
  {shouldShowWagmiWallet && (
299
195
  <button
300
- onClick={async () => {
196
+ onClick={() => {
301
197
  setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
302
198
  onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
303
-
304
- // Create thirdweb wallet from wagmi connector
305
- if (connector?.name) {
306
- const thirdwebWallet = await createThirdwebWalletFromConnector(connector.name);
307
- if (thirdwebWallet) {
308
- setActiveWallet(thirdwebWallet);
309
- }
310
- }
311
-
312
199
  toast.success(`Selected ${connector?.name || "wallet"}`);
313
200
  }}
314
201
  className={cn(
@@ -398,10 +285,7 @@ export function CryptoPaymentMethod({
398
285
  <div className="space-y-3">
399
286
  {/* Connect Wallet Section */}
400
287
  <button
401
- onClick={() => {
402
- // Always show wallet selection modal first
403
- setShowWalletModal(true);
404
- }}
288
+ onClick={handleConnectWallet}
405
289
  className="crypto-payment-method-connect-wallet bg-as-surface-primary border-as-border-secondary hover:border-as-secondary/80 group flex w-full items-center justify-between gap-4 rounded-xl border px-4 py-3.5 transition-all duration-200 hover:shadow-md"
406
290
  >
407
291
  <div className="flex items-center gap-3">
@@ -438,75 +322,6 @@ export function CryptoPaymentMethod({
438
322
  </div>
439
323
  </div>
440
324
  </div>
441
-
442
- {/* Wallet Connection Modal */}
443
- {showWalletModal &&
444
- createPortal(
445
- <div className="wallet-connection-modal pointer-events-auto fixed inset-0 z-[9999] flex items-center justify-center bg-black/50">
446
- <div className="max-h-[80vh] w-[400px] max-w-[90vw] overflow-auto rounded-xl bg-white p-6 dark:bg-gray-900">
447
- <div className="mb-4 flex items-center justify-between">
448
- <h3 className="text-lg font-semibold text-gray-900 dark:text-white">
449
- {isConnected ? "Switch wallet or account" : "Choose wallet to connect"}
450
- </h3>
451
- <button
452
- onClick={handleCloseModal}
453
- className="text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200"
454
- >
455
- <X className="h-5 w-5" />
456
- </button>
457
- </div>
458
-
459
- <div className="space-y-4">
460
- {/* Custom wallet options */}
461
- <div className="space-y-3">
462
- {walletOptions.map(walletOption => {
463
- const isCurrentWallet = isConnected && connector?.name === walletOption.connector?.name;
464
-
465
- return (
466
- <button
467
- key={walletOption.id}
468
- onClick={async () => {
469
- handleCloseModal();
470
- await requestWalletPermissions(walletOption.connector);
471
- }}
472
- disabled={isPending}
473
- className={`wallet-option w-full rounded-xl border p-4 text-left transition-all hover:shadow-md disabled:opacity-50 ${
474
- isCurrentWallet
475
- ? "wallet-option--active border-blue-500 bg-blue-50 dark:bg-blue-900/20"
476
- : "border-gray-200 bg-white hover:border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:hover:border-gray-500"
477
- }`}
478
- >
479
- <div className="flex items-center justify-between">
480
- <div className="flex items-center gap-3">
481
- {walletOption.icon}
482
-
483
- <div>
484
- <div className="wallet-option-name flex items-center gap-2">
485
- <div className="text-sm font-semibold text-gray-900 dark:text-white">
486
- {walletOption.name}
487
- </div>
488
- {isCurrentWallet && (
489
- <span className="rounded-full bg-blue-100 px-2 py-0.5 text-xs font-medium text-blue-700 dark:bg-blue-800 dark:text-blue-200">
490
- Connected
491
- </span>
492
- )}
493
- </div>
494
- <div className="text-xs text-gray-500 dark:text-gray-400">
495
- {isCurrentWallet ? "Switch account or reconnect" : walletOption.description}
496
- </div>
497
- </div>
498
- </div>
499
- <ChevronRightCircle className="h-5 w-5 text-gray-400" />
500
- </div>
501
- </button>
502
- );
503
- })}
504
- </div>
505
- </div>
506
- </div>
507
- </div>,
508
- typeof window !== "undefined" ? document.getElementById("b3-root") || document.body : document.body,
509
- )}
510
325
  </div>
511
326
  );
512
327
  }
@@ -151,19 +151,51 @@ export function useAuthentication(partnerId: string) {
151
151
  [activeWallet, partnerId, authenticate, setIsAuthenticated, setIsAuthenticating, setUser, setHasStartedConnecting],
152
152
  );
153
153
 
154
- const onConnect = useCallback(
155
- async (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => {
156
- debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
154
+ const logout = useCallback(
155
+ async (callback?: () => void) => {
156
+ if (activeWallet) {
157
+ debug("@@logout:activeWallet", activeWallet);
158
+ disconnect(activeWallet);
159
+ debug("@@logout:activeWallet", activeWallet);
160
+ }
157
161
 
158
- const wallet = allConnectedWallets.find(wallet => wallet.id.startsWith("ecosystem."));
162
+ // Log out of each wallet
163
+ wallets.forEach(wallet => {
164
+ console.log("@@logging out", wallet);
165
+ disconnect(wallet);
166
+ });
159
167
 
160
- if (!wallet) {
161
- throw new Error("No smart wallet found during auto-connect");
168
+ // Delete localStorage thirdweb:connected-wallet-ids
169
+ // https://npc-labs.slack.com/archives/C070E6HNG85/p1750185115273099
170
+ if (typeof localStorage !== "undefined") {
171
+ localStorage.removeItem("thirdweb:connected-wallet-ids");
172
+ localStorage.removeItem("wagmi.store");
173
+ localStorage.removeItem("lastAuthProvider");
174
+ localStorage.removeItem("b3-user");
162
175
  }
163
176
 
164
- debug("@@useAuthentication:onConnect", { wallet });
177
+ app.logout();
178
+ debug("@@logout:loggedOut");
165
179
 
180
+ setIsAuthenticated(false);
181
+ setIsConnected(false);
182
+ setUser();
183
+ callback?.();
184
+ },
185
+ [activeWallet, disconnect, wallets, setIsAuthenticated, setUser, setIsConnected],
186
+ );
187
+
188
+ const onConnect = useCallback(
189
+ async (_walleAutoConnectedWith: Wallet, allConnectedWallets: Wallet[]) => {
190
+ debug("@@useAuthentication:onConnect", { _walleAutoConnectedWith, allConnectedWallets });
166
191
  try {
192
+ const wallet = allConnectedWallets.find(wallet => wallet.id.startsWith("ecosystem."));
193
+
194
+ if (!wallet) {
195
+ throw new Error("No smart wallet found during auto-connect");
196
+ }
197
+
198
+ debug("@@useAuthentication:onConnect", { wallet });
167
199
  setHasStartedConnecting(true);
168
200
  setIsConnected(true);
169
201
  setIsAuthenticating(true);
@@ -177,6 +209,8 @@ export function useAuthentication(partnerId: string) {
177
209
  debug("@@useAuthentication:onConnect:failed", { error });
178
210
  setIsAuthenticated(false);
179
211
  setUser(undefined);
212
+
213
+ await logout();
180
214
  } finally {
181
215
  setIsAuthenticating(false);
182
216
  }
@@ -188,54 +222,21 @@ export function useAuthentication(partnerId: string) {
188
222
  });
189
223
  },
190
224
  [
191
- onConnectCallback,
192
- authenticateUser,
193
225
  isAuthenticated,
194
226
  isAuthenticating,
195
227
  isConnected,
196
- setActiveWallet,
197
228
  setHasStartedConnecting,
198
- setIsAuthenticated,
199
- setIsAuthenticating,
200
229
  setIsConnected,
230
+ setIsAuthenticating,
231
+ setActiveWallet,
232
+ authenticateUser,
233
+ onConnectCallback,
234
+ setIsAuthenticated,
201
235
  setUser,
236
+ logout,
202
237
  ],
203
238
  );
204
239
 
205
- const logout = useCallback(
206
- async (callback?: () => void) => {
207
- if (activeWallet) {
208
- debug("@@logout:activeWallet", activeWallet);
209
- disconnect(activeWallet);
210
- debug("@@logout:activeWallet", activeWallet);
211
- }
212
-
213
- // Log out of each wallet
214
- wallets.forEach(wallet => {
215
- console.log("@@logging out", wallet);
216
- disconnect(wallet);
217
- });
218
-
219
- // Delete localStorage thirdweb:connected-wallet-ids
220
- // https://npc-labs.slack.com/archives/C070E6HNG85/p1750185115273099
221
- if (typeof localStorage !== "undefined") {
222
- localStorage.removeItem("thirdweb:connected-wallet-ids");
223
- localStorage.removeItem("wagmi.store");
224
- localStorage.removeItem("lastAuthProvider");
225
- localStorage.removeItem("b3-user");
226
- }
227
-
228
- app.logout();
229
- debug("@@logout:loggedOut");
230
-
231
- setIsAuthenticated(false);
232
- setIsConnected(false);
233
- setUser();
234
- callback?.();
235
- },
236
- [activeWallet, disconnect, wallets, setIsAuthenticated, setUser, setIsConnected],
237
- );
238
-
239
240
  const { isLoading: useAutoConnectLoading } = useAutoConnect({
240
241
  client,
241
242
  wallets: [wallet],