@b3dotfun/sdk 0.0.82 → 0.0.83-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.
- package/dist/cjs/anyspend/react/components/AnySpend.js +0 -3
- package/dist/cjs/anyspend/react/components/AnySpendCollectorClubPurchase.js +1 -1
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +0 -3
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +47 -177
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +0 -3
- package/dist/cjs/anyspend/react/providers/AnyspendProvider.js +1 -13
- package/dist/cjs/anyspend/utils/chain.d.ts +38 -0
- package/dist/cjs/anyspend/utils/chain.js +22 -1
- package/dist/cjs/anyspend/utils/token.d.ts +3 -0
- package/dist/cjs/anyspend/utils/token.js +17 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +1 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.d.ts +1 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +38 -36
- package/dist/cjs/global-account/react/hooks/useUserQuery.d.ts +1 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +0 -3
- package/dist/esm/anyspend/react/components/AnySpendCollectorClubPurchase.js +1 -1
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +0 -3
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +45 -175
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +0 -3
- package/dist/esm/anyspend/react/providers/AnyspendProvider.js +1 -13
- package/dist/esm/anyspend/utils/chain.d.ts +38 -0
- package/dist/esm/anyspend/utils/chain.js +22 -1
- package/dist/esm/anyspend/utils/token.d.ts +3 -0
- package/dist/esm/anyspend/utils/token.js +15 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +2 -2
- package/dist/esm/global-account/react/hooks/useAuthentication.d.ts +1 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.js +38 -36
- package/dist/esm/global-account/react/hooks/useUserQuery.d.ts +1 -1
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/utils/chain.d.ts +38 -0
- package/dist/types/anyspend/utils/token.d.ts +3 -0
- package/dist/types/global-account/react/hooks/useAuthentication.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useUserQuery.d.ts +1 -1
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +0 -4
- package/src/anyspend/react/components/AnySpendCollectorClubPurchase.tsx +1 -1
- package/src/anyspend/react/components/AnySpendCustom.tsx +0 -4
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +22 -253
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +0 -4
- package/src/anyspend/react/providers/AnyspendProvider.tsx +7 -22
- package/src/anyspend/utils/chain.ts +31 -1
- package/src/anyspend/utils/token.ts +17 -1
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +6 -2
- package/src/global-account/react/hooks/useAuthentication.ts +47 -46
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +0 -10
- package/dist/cjs/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +0 -73
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +0 -10
- package/dist/esm/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.js +0 -70
- package/dist/types/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.d.ts +0 -10
- package/src/anyspend/react/hooks/useAutoSetActiveWalletFromWagmi.ts +0 -80
|
@@ -44,7 +44,6 @@ import { motion } from "motion/react";
|
|
|
44
44
|
import React, { useCallback, useEffect, useMemo, useState } from "react";
|
|
45
45
|
|
|
46
46
|
import { base } from "viem/chains";
|
|
47
|
-
import { useAutoSetActiveWalletFromWagmi } from "../hooks/useAutoSetActiveWalletFromWagmi";
|
|
48
47
|
import { useCryptoPaymentMethodState } from "../hooks/useCryptoPaymentMethodState";
|
|
49
48
|
import { useRecipientAddressState } from "../hooks/useRecipientAddressState";
|
|
50
49
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "./AnySpendFingerprintWrapper";
|
|
@@ -247,9 +246,6 @@ function AnySpendCustomInner({
|
|
|
247
246
|
const searchParams = useSearchParamsSSR();
|
|
248
247
|
const router = useRouter();
|
|
249
248
|
|
|
250
|
-
// Auto-set active wallet from wagmi
|
|
251
|
-
useAutoSetActiveWalletFromWagmi();
|
|
252
|
-
|
|
253
249
|
const [activePanel, setActivePanel] = useState<PanelView>(
|
|
254
250
|
loadOrder ? PanelView.ORDER_DETAILS : PanelView.CONFIRM_ORDER,
|
|
255
251
|
);
|
|
@@ -4,13 +4,8 @@ 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 {
|
|
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, useDisconnect, useWalletInfo } from "thirdweb/react";
|
|
14
9
|
import { useConnectedWalletDisplay } from "../../hooks/useConnectedWalletDisplay";
|
|
15
10
|
|
|
16
11
|
export enum CryptoPaymentMethodType {
|
|
@@ -35,128 +30,32 @@ export function CryptoPaymentMethod({
|
|
|
35
30
|
onBack,
|
|
36
31
|
onSelectPaymentMethod,
|
|
37
32
|
}: CryptoPaymentMethodProps) {
|
|
38
|
-
const { connectedEOAWallet
|
|
39
|
-
const { connector, address } = useAccount();
|
|
40
|
-
const { connect, connectors, isPending } = useConnect();
|
|
33
|
+
const { connectedEOAWallet, connectedSmartWallet } = useAccountWallet();
|
|
41
34
|
const { disconnect } = useDisconnect();
|
|
42
|
-
const {
|
|
43
|
-
const [showWalletModal, setShowWalletModal] = useState(false);
|
|
44
|
-
const setActiveWallet = useSetActiveWallet();
|
|
35
|
+
const { connect: openConnectModal } = useConnectModal();
|
|
45
36
|
const { data: eoaWalletInfo } = useWalletInfo(connectedEOAWallet?.id);
|
|
46
37
|
|
|
47
|
-
const isConnected = !!connectedEOAWallet;
|
|
48
38
|
const globalAddress = connectedSmartWallet?.getAccount()?.address;
|
|
49
39
|
|
|
50
40
|
// Use custom hook to determine wallet display logic
|
|
51
|
-
const { shouldShowConnectedEOA
|
|
52
|
-
console.log("shouldShowWagmiWallet :", shouldShowWagmiWallet);
|
|
41
|
+
const { shouldShowConnectedEOA } = useConnectedWalletDisplay(selectedPaymentMethod);
|
|
53
42
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
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) => {
|
|
43
|
+
// Handle wallet connection using thirdweb modal
|
|
44
|
+
const handleConnectWallet = async () => {
|
|
129
45
|
try {
|
|
130
|
-
//
|
|
131
|
-
if (
|
|
132
|
-
|
|
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;
|
|
46
|
+
// Disconnect current wallet before connecting a new one
|
|
47
|
+
if (connectedEOAWallet) {
|
|
48
|
+
await disconnect(connectedEOAWallet);
|
|
143
49
|
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
await walletClient.request({
|
|
148
|
-
method: "wallet_requestPermissions",
|
|
149
|
-
params: [{ eth_accounts: {} }],
|
|
150
|
-
});
|
|
151
|
-
toast.success("Account selection completed");
|
|
50
|
+
const wallet = await openConnectModal({ client, setActive: false });
|
|
51
|
+
if (wallet) {
|
|
52
|
+
// setActiveWallet(wallet);
|
|
152
53
|
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
153
54
|
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
154
|
-
|
|
155
|
-
// Fallback: show modal for manual wallet selection
|
|
156
|
-
setShowWalletModal(true);
|
|
55
|
+
toast.success("Wallet connected");
|
|
157
56
|
}
|
|
158
57
|
} catch (error) {
|
|
159
|
-
console.error("Failed to
|
|
58
|
+
console.error("Failed to connect wallet:", error);
|
|
160
59
|
if (error && typeof error === "object" && "message" in error) {
|
|
161
60
|
const errorMessage = (error as any).message.toLowerCase();
|
|
162
61
|
if (
|
|
@@ -164,12 +63,10 @@ export function CryptoPaymentMethod({
|
|
|
164
63
|
errorMessage.includes("denied") ||
|
|
165
64
|
errorMessage.includes("cancelled")
|
|
166
65
|
) {
|
|
167
|
-
|
|
66
|
+
// User cancelled - no toast needed
|
|
168
67
|
} else {
|
|
169
|
-
toast.error("Failed to
|
|
68
|
+
toast.error("Failed to connect wallet");
|
|
170
69
|
}
|
|
171
|
-
} else {
|
|
172
|
-
toast.error("Failed to open account selection");
|
|
173
70
|
}
|
|
174
71
|
}
|
|
175
72
|
};
|
|
@@ -236,7 +133,7 @@ export function CryptoPaymentMethod({
|
|
|
236
133
|
{/* Payment Methods */}
|
|
237
134
|
<div className="crypto-payment-methods flex flex-col gap-4">
|
|
238
135
|
{/* Installed Wallets Section */}
|
|
239
|
-
{(shouldShowConnectedEOA ||
|
|
136
|
+
{(shouldShowConnectedEOA || globalAddress) && (
|
|
240
137
|
<div className="installed-wallets">
|
|
241
138
|
<h3 className="text-as-primary/80 mb-3 text-sm font-medium">Connected wallets</h3>
|
|
242
139
|
<div className="space-y-2">
|
|
@@ -247,10 +144,7 @@ export function CryptoPaymentMethod({
|
|
|
247
144
|
onClick={() => {
|
|
248
145
|
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
249
146
|
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
250
|
-
|
|
251
|
-
setActiveWallet(connectedEOAWallet);
|
|
252
|
-
}
|
|
253
|
-
toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
|
|
147
|
+
toast.success(`Selected ${eoaWalletInfo?.name || "wallet"}`);
|
|
254
148
|
}}
|
|
255
149
|
className={cn(
|
|
256
150
|
"crypto-payment-method-connect-wallet eoa-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
@@ -266,7 +160,7 @@ export function CryptoPaymentMethod({
|
|
|
266
160
|
</div>
|
|
267
161
|
<div className="flex flex-col">
|
|
268
162
|
<span className="text-as-primary font-semibold">
|
|
269
|
-
{eoaWalletInfo?.name ||
|
|
163
|
+
{eoaWalletInfo?.name || "Connected Wallet"}
|
|
270
164
|
</span>
|
|
271
165
|
<span className="text-as-primary/60 text-sm">
|
|
272
166
|
{shortenAddress(connectedEOAWallet?.getAccount()?.address || "")}
|
|
@@ -280,62 +174,9 @@ export function CryptoPaymentMethod({
|
|
|
280
174
|
<button
|
|
281
175
|
onClick={e => {
|
|
282
176
|
e.stopPropagation();
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
286
|
-
setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
177
|
+
if (connectedEOAWallet) {
|
|
178
|
+
disconnect(connectedEOAWallet);
|
|
287
179
|
}
|
|
288
|
-
}}
|
|
289
|
-
className="text-as-primary/60 hover:text-as-primary/80 rounded-lg p-1.5 transition-colors"
|
|
290
|
-
>
|
|
291
|
-
<X className="h-4 w-4" />
|
|
292
|
-
</button>
|
|
293
|
-
</div>
|
|
294
|
-
</div>
|
|
295
|
-
</button>
|
|
296
|
-
)}
|
|
297
|
-
|
|
298
|
-
{shouldShowWagmiWallet && (
|
|
299
|
-
<button
|
|
300
|
-
onClick={async () => {
|
|
301
|
-
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
302
|
-
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
|
-
toast.success(`Selected ${connector?.name || "wallet"}`);
|
|
313
|
-
}}
|
|
314
|
-
className={cn(
|
|
315
|
-
"crypto-payment-method-connect-wallet wagmi-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
316
|
-
selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
317
|
-
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
318
|
-
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80",
|
|
319
|
-
)}
|
|
320
|
-
>
|
|
321
|
-
<div className="flex items-center justify-between">
|
|
322
|
-
<div className="flex items-center gap-3">
|
|
323
|
-
<div className="wallet-icon flex h-10 w-10 items-center justify-center rounded-full bg-blue-100">
|
|
324
|
-
<Wallet className="h-5 w-5 text-blue-600" />
|
|
325
|
-
</div>
|
|
326
|
-
<div className="flex flex-col">
|
|
327
|
-
<span className="text-as-primary font-semibold">{connector?.name || "Connected Wallet"}</span>
|
|
328
|
-
<span className="text-as-primary/60 text-sm">{shortenAddress(address || "")}</span>
|
|
329
|
-
</div>
|
|
330
|
-
</div>
|
|
331
|
-
<div className="flex items-center gap-2">
|
|
332
|
-
{selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET && (
|
|
333
|
-
<div className="h-2 w-2 rounded-full bg-green-500"></div>
|
|
334
|
-
)}
|
|
335
|
-
<button
|
|
336
|
-
onClick={e => {
|
|
337
|
-
e.stopPropagation();
|
|
338
|
-
disconnect();
|
|
339
180
|
toast.success("Wallet disconnected");
|
|
340
181
|
if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
341
182
|
setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
@@ -398,10 +239,7 @@ export function CryptoPaymentMethod({
|
|
|
398
239
|
<div className="space-y-3">
|
|
399
240
|
{/* Connect Wallet Section */}
|
|
400
241
|
<button
|
|
401
|
-
onClick={
|
|
402
|
-
// Always show wallet selection modal first
|
|
403
|
-
setShowWalletModal(true);
|
|
404
|
-
}}
|
|
242
|
+
onClick={handleConnectWallet}
|
|
405
243
|
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
244
|
>
|
|
407
245
|
<div className="flex items-center gap-3">
|
|
@@ -438,75 +276,6 @@ export function CryptoPaymentMethod({
|
|
|
438
276
|
</div>
|
|
439
277
|
</div>
|
|
440
278
|
</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
279
|
</div>
|
|
511
280
|
);
|
|
512
281
|
}
|
|
@@ -24,7 +24,6 @@ import { components } from "../../types/api";
|
|
|
24
24
|
import { CryptoPaymentMethodType } from "../components/common/CryptoPaymentMethod";
|
|
25
25
|
import { FiatPaymentMethod } from "../components/common/FiatPaymentMethod";
|
|
26
26
|
import { useAutoSelectCryptoPaymentMethod } from "./useAutoSelectCryptoPaymentMethod";
|
|
27
|
-
import { useAutoSetActiveWalletFromWagmi } from "./useAutoSetActiveWalletFromWagmi";
|
|
28
27
|
import { useConnectedWalletDisplay } from "./useConnectedWalletDisplay";
|
|
29
28
|
import { useCryptoPaymentMethodState } from "./useCryptoPaymentMethodState";
|
|
30
29
|
import { useRecipientAddressState } from "./useRecipientAddressState";
|
|
@@ -111,9 +110,6 @@ export function useAnyspendFlow({
|
|
|
111
110
|
const { address: globalAddress } = useAccountWallet();
|
|
112
111
|
const { walletAddress } = useConnectedWalletDisplay(effectiveCryptoPaymentMethod);
|
|
113
112
|
|
|
114
|
-
// Auto-set active wallet from wagmi
|
|
115
|
-
useAutoSetActiveWalletFromWagmi();
|
|
116
|
-
|
|
117
113
|
// Recipient address state - hook automatically manages priority: props > user selection > wallet/global
|
|
118
114
|
const { setSelectedRecipientAddress, effectiveRecipientAddress } = useRecipientAddressState({
|
|
119
115
|
recipientAddressFromProps: recipientAddress,
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { TooltipProvider } from "@b3dotfun/sdk/global-account/react";
|
|
4
|
-
import {
|
|
5
|
-
import { ReactNode, useState } from "react";
|
|
4
|
+
import { ReactNode } from "react";
|
|
6
5
|
import { FeatureFlags, FeatureFlagsProvider } from "../contexts/FeatureFlagsContext";
|
|
7
6
|
import { StripeRedirectHandler } from "./StripeRedirectHandler";
|
|
8
7
|
|
|
@@ -11,16 +10,6 @@ interface AnyspendProviderProps {
|
|
|
11
10
|
featureFlags?: FeatureFlags;
|
|
12
11
|
}
|
|
13
12
|
|
|
14
|
-
const defaultQueryClientConfig = {
|
|
15
|
-
defaultOptions: {
|
|
16
|
-
queries: {
|
|
17
|
-
refetchOnWindowFocus: false,
|
|
18
|
-
retry: false,
|
|
19
|
-
staleTime: 30000,
|
|
20
|
-
},
|
|
21
|
-
},
|
|
22
|
-
} as const;
|
|
23
|
-
|
|
24
13
|
/**
|
|
25
14
|
* AnyspendProvider is a top-level provider that wraps your application to provide
|
|
26
15
|
* query caching and state management for all Anyspend hooks.
|
|
@@ -45,16 +34,12 @@ const defaultQueryClientConfig = {
|
|
|
45
34
|
* ```
|
|
46
35
|
*/
|
|
47
36
|
export const AnyspendProvider = function AnyspendProvider({ children, featureFlags }: AnyspendProviderProps) {
|
|
48
|
-
const [queryClient] = useState(() => new QueryClient(defaultQueryClientConfig));
|
|
49
|
-
|
|
50
37
|
return (
|
|
51
|
-
<
|
|
52
|
-
<
|
|
53
|
-
<
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
</FeatureFlagsProvider>
|
|
58
|
-
</QueryClientProvider>
|
|
38
|
+
<FeatureFlagsProvider featureFlags={featureFlags}>
|
|
39
|
+
<TooltipProvider>
|
|
40
|
+
<StripeRedirectHandler />
|
|
41
|
+
{children}
|
|
42
|
+
</TooltipProvider>
|
|
43
|
+
</FeatureFlagsProvider>
|
|
59
44
|
);
|
|
60
45
|
};
|
|
@@ -15,12 +15,28 @@ import {
|
|
|
15
15
|
} from "viem";
|
|
16
16
|
import { abstract, arbitrum, avalanche, b3, base, bsc, mainnet, optimism, polygon } from "viem/chains";
|
|
17
17
|
import { ChainType, IBaseChain, IEVMChain, ISolanaChain } from "../types/chain";
|
|
18
|
-
import {
|
|
18
|
+
import {
|
|
19
|
+
getAvaxToken,
|
|
20
|
+
getBnbToken,
|
|
21
|
+
getEthToken,
|
|
22
|
+
getHyperEVMNativeToken,
|
|
23
|
+
getPolToken,
|
|
24
|
+
getSolanaToken,
|
|
25
|
+
HYPEREVM_CHAIN_ID,
|
|
26
|
+
} from "./token";
|
|
19
27
|
|
|
20
28
|
function getCustomEvmChain(chain: Chain, rpcUrl: string): Chain {
|
|
21
29
|
return defineChain({ ...chain, rpcUrls: { default: { http: [rpcUrl] } } });
|
|
22
30
|
}
|
|
23
31
|
|
|
32
|
+
export const hyperEVM = defineChain({
|
|
33
|
+
id: HYPEREVM_CHAIN_ID,
|
|
34
|
+
name: "HyperEVM",
|
|
35
|
+
nativeCurrency: { name: "HyperEVM", symbol: "HYPE", decimals: 18 },
|
|
36
|
+
rpcUrls: { default: { http: ["https://rpc.hyperliquid.xyz/evm"] } },
|
|
37
|
+
blockExplorers: { default: { name: "HyperEVM Explorer", url: "https://hyperevmscan.io/" } },
|
|
38
|
+
});
|
|
39
|
+
|
|
24
40
|
// export const b4testnet = defineChain({
|
|
25
41
|
// id: 19934,
|
|
26
42
|
// name: "B4 Testnet",
|
|
@@ -189,6 +205,20 @@ export const EVM_MAINNET: Record<number, IEVMChain> = {
|
|
|
189
205
|
coingeckoName: "abstract",
|
|
190
206
|
wethAddress: "0x3439153eb7af838ad19d56e1571fbd09333c2809",
|
|
191
207
|
},
|
|
208
|
+
[hyperEVM.id]: {
|
|
209
|
+
id: hyperEVM.id,
|
|
210
|
+
name: hyperEVM.name,
|
|
211
|
+
logoUrl: "https://s2.coinmarketcap.com/static/img/coins/64x64/32196.png",
|
|
212
|
+
type: ChainType.EVM,
|
|
213
|
+
nativeRequired: parseEther("0.01"),
|
|
214
|
+
canDepositNative: true,
|
|
215
|
+
defaultToken: getHyperEVMNativeToken(),
|
|
216
|
+
nativeToken: getHyperEVMNativeToken(),
|
|
217
|
+
viem: hyperEVM,
|
|
218
|
+
pollingInterval: 1000, // 1 second for Hyperliquid
|
|
219
|
+
coingeckoName: "hyperevm",
|
|
220
|
+
wethAddress: "0x5555555555555555555555555555555555555555",
|
|
221
|
+
},
|
|
192
222
|
};
|
|
193
223
|
|
|
194
224
|
export const EVM_TESTNET: Record<number, IEVMChain> = {
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { avalanche, bsc, polygon } from "viem/chains";
|
|
2
1
|
import { RELAY_ETH_ADDRESS, RELAY_SOL_ADDRESS, RELAY_SOLANA_MAINNET_CHAIN_ID } from "@b3dotfun/sdk/anyspend/constants";
|
|
3
2
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
3
|
+
import { avalanche, bsc, polygon } from "viem/chains";
|
|
4
|
+
|
|
5
|
+
export const HYPERLIQUID_CHAIN_ID = 1337;
|
|
6
|
+
export const HYPEREVM_CHAIN_ID = 999;
|
|
4
7
|
|
|
5
8
|
export function isNativeToken(address: string): boolean {
|
|
6
9
|
return address.toLowerCase() === RELAY_ETH_ADDRESS || address.toLowerCase() === RELAY_SOL_ADDRESS;
|
|
@@ -70,3 +73,16 @@ export function getAvaxToken(): components["schemas"]["Token"] {
|
|
|
70
73
|
},
|
|
71
74
|
};
|
|
72
75
|
}
|
|
76
|
+
|
|
77
|
+
export function getHyperEVMNativeToken(): components["schemas"]["Token"] {
|
|
78
|
+
return {
|
|
79
|
+
chainId: HYPEREVM_CHAIN_ID,
|
|
80
|
+
address: RELAY_ETH_ADDRESS,
|
|
81
|
+
symbol: "HYPE",
|
|
82
|
+
name: "HYPE",
|
|
83
|
+
decimals: 18,
|
|
84
|
+
metadata: {
|
|
85
|
+
logoURI: "https://s2.coinmarketcap.com/static/img/coins/64x64/32196.png",
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -12,7 +12,7 @@ import { loadGA4Script } from "@b3dotfun/sdk/global-account/utils/analytics";
|
|
|
12
12
|
import { debugB3React } from "@b3dotfun/sdk/shared/utils/debug";
|
|
13
13
|
import "@relayprotocol/relay-kit-ui/styles.css";
|
|
14
14
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
15
|
-
import { useCallback, useEffect, useState } from "react";
|
|
15
|
+
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
16
16
|
import {
|
|
17
17
|
getLastAuthProvider,
|
|
18
18
|
ThirdwebProvider,
|
|
@@ -92,7 +92,11 @@ export function B3Provider({
|
|
|
92
92
|
useEffect(() => {
|
|
93
93
|
setClientType(clientType);
|
|
94
94
|
}, [clientType]);
|
|
95
|
-
|
|
95
|
+
|
|
96
|
+
const wagmiConfig = useMemo(
|
|
97
|
+
() => createWagmiConfig({ partnerId, rpcUrls, connectors, overrideDefaultConnectors }),
|
|
98
|
+
[partnerId, rpcUrls, connectors, overrideDefaultConnectors],
|
|
99
|
+
);
|
|
96
100
|
|
|
97
101
|
return (
|
|
98
102
|
<ThirdwebProvider>
|
|
@@ -151,19 +151,51 @@ export function useAuthentication(partnerId: string) {
|
|
|
151
151
|
[activeWallet, partnerId, authenticate, setIsAuthenticated, setIsAuthenticating, setUser, setHasStartedConnecting],
|
|
152
152
|
);
|
|
153
153
|
|
|
154
|
-
const
|
|
155
|
-
async (
|
|
156
|
-
|
|
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
|
-
|
|
162
|
+
// Log out of each wallet
|
|
163
|
+
wallets.forEach(wallet => {
|
|
164
|
+
console.log("@@logging out", wallet);
|
|
165
|
+
disconnect(wallet);
|
|
166
|
+
});
|
|
159
167
|
|
|
160
|
-
|
|
161
|
-
|
|
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
|
-
|
|
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],
|