@b3dotfun/sdk 0.0.40-alpha.11 → 0.0.40-alpha.12
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/common/ConnectWalletPayment.js +5 -3
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +73 -3
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +8 -8
- package/dist/cjs/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +22 -20
- package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +6 -4
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +73 -3
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +8 -8
- package/dist/esm/global-account/react/hooks/useUnifiedChainSwitchAndExecute.js +22 -20
- package/package.json +1 -1
- package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +7 -4
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +124 -4
- package/src/anyspend/react/components/common/OrderDetails.tsx +8 -9
- package/src/global-account/react/hooks/useUnifiedChainSwitchAndExecute.ts +23 -21
|
@@ -12,14 +12,16 @@ const centerTruncate_1 = __importDefault(require("../../../../shared/utils/cente
|
|
|
12
12
|
const number_1 = require("../../../../shared/utils/number");
|
|
13
13
|
const framer_motion_1 = require("framer-motion");
|
|
14
14
|
const lucide_react_1 = require("lucide-react");
|
|
15
|
-
const wagmi_1 = require("wagmi");
|
|
16
15
|
const CryptoPaymentMethod_1 = require("./CryptoPaymentMethod");
|
|
17
16
|
const OrderDetailsCollapsible_1 = require("./OrderDetailsCollapsible");
|
|
18
17
|
const PaymentMethodSwitch_1 = require("./PaymentMethodSwitch");
|
|
19
18
|
function ConnectWalletPayment({ order, onPayment, txLoading, isSwitchingOrExecuting, phantomWalletAddress, tournament, nft, cryptoPaymentMethod, onPaymentMethodChange, }) {
|
|
20
19
|
const profile = (0, react_1.useProfile)({ address: order.recipientAddress });
|
|
21
20
|
const recipientName = profile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
22
|
-
const {
|
|
21
|
+
const { connectedEOAWallet, connectedSmartWallet } = (0, react_1.useAccountWallet)();
|
|
22
|
+
const connectedEvmAddress = cryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.GLOBAL_WALLET
|
|
23
|
+
? connectedSmartWallet?.getAccount()?.address
|
|
24
|
+
: connectedEOAWallet?.getAccount()?.address;
|
|
23
25
|
const srcToken = order.metadata.srcToken;
|
|
24
26
|
const dstToken = order.metadata.dstToken;
|
|
25
27
|
const expectedDstAmount = order.type === "mint_nft" ||
|
|
@@ -38,5 +40,5 @@ function ConnectWalletPayment({ order, onPayment, txLoading, isSwitchingOrExecut
|
|
|
38
40
|
? "Pay from Global Account"
|
|
39
41
|
: "Pay from Connected Wallet" }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4" })] })) }), (0, jsx_runtime_1.jsxs)("span", { className: "label-style text-as-primary/50 text-xs", children: ["Connected to:", " ", order.srcChain === anyspend_1.RELAY_SOLANA_MAINNET_CHAIN_ID && phantomWalletAddress
|
|
40
42
|
? (0, centerTruncate_1.default)(phantomWalletAddress, 6)
|
|
41
|
-
: (0, centerTruncate_1.default)(
|
|
43
|
+
: (0, centerTruncate_1.default)(connectedEvmAddress || "")] }), (0, jsx_runtime_1.jsx)(PaymentMethodSwitch_1.PaymentMethodSwitch, { currentMethod: cryptoPaymentMethod, onMethodChange: onPaymentMethodChange }), (0, jsx_runtime_1.jsx)("div", { className: "mt-4", children: (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }) })] }) }));
|
|
42
44
|
}
|
|
@@ -7,11 +7,14 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
7
7
|
const react_1 = require("../../../../global-account/react");
|
|
8
8
|
const cn_1 = require("../../../../shared/utils/cn");
|
|
9
9
|
const formatAddress_1 = require("../../../../shared/utils/formatAddress");
|
|
10
|
+
const thirdweb_1 = require("../../../../shared/utils/thirdweb");
|
|
10
11
|
const react_2 = require("@web3icons/react");
|
|
11
12
|
const lucide_react_1 = require("lucide-react");
|
|
12
13
|
const react_3 = require("react");
|
|
13
14
|
const react_dom_1 = require("react-dom");
|
|
14
15
|
const sonner_1 = require("sonner");
|
|
16
|
+
const react_4 = require("thirdweb/react");
|
|
17
|
+
const wallets_1 = require("thirdweb/wallets");
|
|
15
18
|
const wagmi_1 = require("wagmi");
|
|
16
19
|
var CryptoPaymentMethodType;
|
|
17
20
|
(function (CryptoPaymentMethodType) {
|
|
@@ -21,12 +24,58 @@ var CryptoPaymentMethodType;
|
|
|
21
24
|
CryptoPaymentMethodType["TRANSFER_CRYPTO"] = "transfer_crypto";
|
|
22
25
|
})(CryptoPaymentMethodType || (exports.CryptoPaymentMethodType = CryptoPaymentMethodType = {}));
|
|
23
26
|
function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentMethod, isCreatingOrder, onBack, onSelectPaymentMethod, }) {
|
|
24
|
-
const { wallet: globalWallet,
|
|
25
|
-
const { address, isConnected
|
|
27
|
+
const { wallet: globalWallet, connectedEOAWallet: connectedEOAWallet, connectedSmartWallet: connectedSmartWallet, } = (0, react_1.useAccountWallet)();
|
|
28
|
+
const { connector, address, isConnected: wagmiWalletIsConnected } = (0, wagmi_1.useAccount)();
|
|
26
29
|
const { connect, connectors, isPending } = (0, wagmi_1.useConnect)();
|
|
27
30
|
const { disconnect } = (0, wagmi_1.useDisconnect)();
|
|
28
31
|
const { data: walletClient } = (0, wagmi_1.useWalletClient)();
|
|
29
32
|
const [showWalletModal, setShowWalletModal] = (0, react_3.useState)(false);
|
|
33
|
+
const setActiveWallet = (0, react_4.useSetActiveWallet)();
|
|
34
|
+
const { data: eoaWalletInfo } = (0, react_4.useWalletInfo)(connectedEOAWallet?.id);
|
|
35
|
+
const isConnected = !!connectedEOAWallet;
|
|
36
|
+
const globalAddress = connectedSmartWallet?.getAccount()?.address;
|
|
37
|
+
// Helper function to check if two addresses are the same
|
|
38
|
+
const isSameAddress = (addr1, addr2) => {
|
|
39
|
+
if (!addr1 || !addr2)
|
|
40
|
+
return false;
|
|
41
|
+
return addr1.toLowerCase() === addr2.toLowerCase();
|
|
42
|
+
};
|
|
43
|
+
// Check if connectedEOAWallet and wagmi wallet represent the same wallet
|
|
44
|
+
const connectedEOAAddress = connectedEOAWallet?.getAccount()?.address;
|
|
45
|
+
const wagmiAddress = address;
|
|
46
|
+
const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress);
|
|
47
|
+
// Determine which wallet to show (prefer connectedEOAWallet if both exist and are the same)
|
|
48
|
+
const shouldShowConnectedEOA = !!connectedEOAWallet;
|
|
49
|
+
const shouldShowWagmiWallet = wagmiWalletIsConnected && (!isWalletDuplicated || !connectedEOAWallet);
|
|
50
|
+
// Map wagmi connector names to thirdweb wallet IDs
|
|
51
|
+
const getThirdwebWalletId = (connectorName) => {
|
|
52
|
+
const walletMap = {
|
|
53
|
+
MetaMask: "io.metamask",
|
|
54
|
+
"Coinbase Wallet": "com.coinbase.wallet",
|
|
55
|
+
Rainbow: "me.rainbow",
|
|
56
|
+
WalletConnect: "walletConnect",
|
|
57
|
+
Phantom: "app.phantom",
|
|
58
|
+
};
|
|
59
|
+
return walletMap[connectorName] || null;
|
|
60
|
+
};
|
|
61
|
+
// Create thirdweb wallet from wagmi connector
|
|
62
|
+
const createThirdwebWalletFromConnector = async (connectorName) => {
|
|
63
|
+
const walletId = getThirdwebWalletId(connectorName);
|
|
64
|
+
if (!walletId) {
|
|
65
|
+
console.warn(`No thirdweb wallet ID found for connector: ${connectorName}`);
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const thirdwebWallet = (0, wallets_1.createWallet)(walletId);
|
|
70
|
+
// Connect the wallet to sync with the existing wagmi connection
|
|
71
|
+
await thirdwebWallet.connect({ client: thirdweb_1.client });
|
|
72
|
+
return thirdwebWallet;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
console.error(`Failed to create thirdweb wallet for ${connectorName}:`, error);
|
|
76
|
+
return null;
|
|
77
|
+
}
|
|
78
|
+
};
|
|
30
79
|
// Define available wallet connectors
|
|
31
80
|
const availableConnectors = connectors.filter(connector => ["MetaMask", "WalletConnect", "Coinbase Wallet", "Rainbow", "Phantom"].includes(connector.name));
|
|
32
81
|
// Define wallet options with icons and info
|
|
@@ -127,9 +176,30 @@ function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentMethod,
|
|
|
127
176
|
}, 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", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-blue-100", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Wallet, { className: "h-4 w-4 text-blue-600" }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col items-start text-left", children: (0, jsx_runtime_1.jsx)("h4", { className: "text-as-primary font-semibold", children: "Connect wallet" }) })] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: () => {
|
|
128
177
|
setSelectedPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
129
178
|
onSelectPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
130
|
-
}, disabled: isCreatingOrder, className: "crypto-payment-method-transfer 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", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-orange-100", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ZapIcon, { className: "h-4 w-4" }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col items-start text-left", children: (0, jsx_runtime_1.jsx)("h4", { className: "text-as-primary font-semibold", children: "Transfer crypto" }) })] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), (
|
|
179
|
+
}, disabled: isCreatingOrder, className: "crypto-payment-method-transfer 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", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-orange-100", children: (0, jsx_runtime_1.jsx)(lucide_react_1.ZapIcon, { className: "h-4 w-4" }) }), (0, jsx_runtime_1.jsx)("div", { className: "flex flex-col items-start text-left", children: (0, jsx_runtime_1.jsx)("h4", { className: "text-as-primary font-semibold", children: "Transfer crypto" }) })] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), (shouldShowConnectedEOA || shouldShowWagmiWallet || globalAddress) && ((0, jsx_runtime_1.jsxs)("div", { className: "installed-wallets", children: [(0, jsx_runtime_1.jsx)("h3", { className: "text-as-primary/80 mb-3 text-sm font-medium", children: "Connected wallets" }), (0, jsx_runtime_1.jsxs)("div", { className: "space-y-2", children: [shouldShowConnectedEOA && ((0, jsx_runtime_1.jsx)("button", { onClick: () => {
|
|
180
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
181
|
+
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
182
|
+
setActiveWallet(connectedEOAWallet);
|
|
183
|
+
sonner_1.toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
|
|
184
|
+
}, className: (0, cn_1.cn)("crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
185
|
+
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
186
|
+
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80"), children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: "wallet-icon flex h-10 w-10 items-center justify-center rounded-full bg-blue-100", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Wallet, { className: "h-5 w-5 text-blue-600" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-primary font-semibold", children: eoaWalletInfo?.name || connector?.name || "Connected Wallet" }), (0, jsx_runtime_1.jsx)("span", { className: "text-as-primary/60 text-sm", children: (0, formatAddress_1.shortenAddress)(connectedEOAWallet?.getAccount()?.address || "") })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET && ((0, jsx_runtime_1.jsx)("div", { className: "h-2 w-2 rounded-full bg-green-500" })), (0, jsx_runtime_1.jsx)("button", { onClick: e => {
|
|
187
|
+
e.stopPropagation();
|
|
188
|
+
disconnect();
|
|
189
|
+
sonner_1.toast.success("Wallet disconnected");
|
|
190
|
+
if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
191
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
192
|
+
}
|
|
193
|
+
}, className: "text-as-primary/60 hover:text-as-primary/80 rounded-lg p-1.5 transition-colors", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-4 w-4" }) })] })] }) })), shouldShowWagmiWallet && ((0, jsx_runtime_1.jsx)("button", { onClick: async () => {
|
|
131
194
|
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
132
195
|
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
196
|
+
// Create thirdweb wallet from wagmi connector
|
|
197
|
+
if (connector?.name) {
|
|
198
|
+
const thirdwebWallet = await createThirdwebWalletFromConnector(connector.name);
|
|
199
|
+
if (thirdwebWallet) {
|
|
200
|
+
setActiveWallet(thirdwebWallet);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
133
203
|
sonner_1.toast.success(`Selected ${connector?.name || "wallet"}`);
|
|
134
204
|
}, className: (0, cn_1.cn)("crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
135
205
|
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
@@ -139,9 +139,9 @@ exports.OrderDetails = (0, react_4.memo)(function OrderDetails({ mode = "modal",
|
|
|
139
139
|
const colorMode = theme || "light";
|
|
140
140
|
// Read crypto payment method from URL parameters
|
|
141
141
|
const cryptoPaymentMethodFromUrl = searchParams.get("cryptoPaymentMethod");
|
|
142
|
-
const effectiveCryptoPaymentMethod =
|
|
143
|
-
|
|
144
|
-
|
|
142
|
+
const effectiveCryptoPaymentMethod = selectedCryptoPaymentMethod !== CryptoPaymentMethod_1.CryptoPaymentMethodType.NONE
|
|
143
|
+
? selectedCryptoPaymentMethod
|
|
144
|
+
: cryptoPaymentMethod || cryptoPaymentMethodFromUrl || CryptoPaymentMethod_1.CryptoPaymentMethodType.NONE;
|
|
145
145
|
const setB3ModalOpen = (0, react_1.useModalStore)((state) => state.setB3ModalOpen);
|
|
146
146
|
const srcToken = order.metadata.srcToken;
|
|
147
147
|
const dstToken = order.metadata.dstToken;
|
|
@@ -422,7 +422,7 @@ exports.OrderDetails = (0, react_4.memo)(function OrderDetails({ mode = "modal",
|
|
|
422
422
|
}
|
|
423
423
|
};
|
|
424
424
|
if (refundTxs.length > 0) {
|
|
425
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
425
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), (0, jsx_runtime_1.jsx)(Accordion_1.Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: (0, jsx_runtime_1.jsxs)(Accordion_1.AccordionItem, { value: "refund-details", className: "order-details-refund-item", children: [(0, jsx_runtime_1.jsx)(Accordion_1.AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), (0, jsx_runtime_1.jsx)(Accordion_1.AccordionContent, { className: "accordion-content pl-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full flex-col gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: (0, jsx_runtime_1.jsx)(react_3.motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
426
426
|
? depositTxs.map(dTx => ((0, jsx_runtime_1.jsx)(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
427
427
|
? `Received payment`
|
|
428
428
|
: `Received ${(0, number_1.formatTokenAmount)(BigInt(dTx.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTx, isProcessing: false }, dTx.txHash)))
|
|
@@ -431,7 +431,7 @@ exports.OrderDetails = (0, react_4.memo)(function OrderDetails({ mode = "modal",
|
|
|
431
431
|
: null] }) })] }) }), order.errorDetails && ((0, jsx_runtime_1.jsx)("div", { className: "flex justify-center", children: (0, jsx_runtime_1.jsx)("span", { className: "text-as-primary/50 text-center text-sm", style: { maxWidth: "40ch" }, children: (0, anyspend_1.getErrorDisplay)(order.errorDetails) }) })), (0, jsx_runtime_1.jsx)("button", { className: "order-close-button order-details-close-btn bg-as-brand flex w-full items-center justify-center gap-2 rounded-lg p-2 font-semibold text-white", onClick: mode === "page" ? handleBack : handleCloseModal, children: mode === "page" ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Return to Home ", (0, jsx_runtime_1.jsx)(lucide_react_1.Home, { className: "ml-2 h-4 w-4" })] })) : ("Close") })] }));
|
|
432
432
|
}
|
|
433
433
|
if (executeTx) {
|
|
434
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
434
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), (0, jsx_runtime_1.jsx)(Accordion_1.Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: (0, jsx_runtime_1.jsxs)(Accordion_1.AccordionItem, { value: "execute-details", className: "order-details-execute-item", children: [(0, jsx_runtime_1.jsx)(Accordion_1.AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), (0, jsx_runtime_1.jsx)(Accordion_1.AccordionContent, { className: "accordion-content pl-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full flex-col gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: (0, jsx_runtime_1.jsx)(react_3.motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
435
435
|
? depositTxs.map(dTxs => ((0, jsx_runtime_1.jsx)(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
436
436
|
? `Received payment`
|
|
437
437
|
: `Received ${(0, number_1.formatTokenAmount)(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: false }, dTxs.txHash)))
|
|
@@ -456,7 +456,7 @@ exports.OrderDetails = (0, react_4.memo)(function OrderDetails({ mode = "modal",
|
|
|
456
456
|
}), (0, jsx_runtime_1.jsx)(lucide_react_1.ExternalLink, { className: "ml-2 h-4 w-4" })] }) }) }), order.type === "join_tournament" && order.status === "executed" && ((0, jsx_runtime_1.jsxs)(react_1.ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "flex w-full items-center gap-2", disabled: txLoading || isSwitchingOrExecuting, onClick: handleCloseModal, children: [(0, jsx_runtime_1.jsx)("span", { className: "pl-4", children: "Continue to Tournament" }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "h-4 w-4" })] })), order.status === "executed" && ((0, jsx_runtime_1.jsx)("button", { className: "order-close-button order-details-close-btn bg-as-brand flex w-full items-center justify-center gap-2 rounded-lg p-2 font-semibold text-white", onClick: mode === "page" ? handleBack : handleCloseModal, children: mode === "page" ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: ["Return to Home ", (0, jsx_runtime_1.jsx)(lucide_react_1.Home, { className: "ml-2 h-4 w-4" })] })) : ("Close") }))] }));
|
|
457
457
|
}
|
|
458
458
|
if (relayTxs.length > 0 && relayTxs.every(tx => tx.status === "success")) {
|
|
459
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
459
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), (0, jsx_runtime_1.jsx)(Accordion_1.Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: (0, jsx_runtime_1.jsxs)(Accordion_1.AccordionItem, { value: "more-details", className: "order-details-more-item", children: [(0, jsx_runtime_1.jsx)(Accordion_1.AccordionTrigger, { className: "accordion-trigger", children: "More Details" }), (0, jsx_runtime_1.jsx)(Accordion_1.AccordionContent, { className: "accordion-content pl-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full flex-col gap-4", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: (0, jsx_runtime_1.jsx)(react_3.motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
460
460
|
? depositTxs.map(dTxs => ((0, jsx_runtime_1.jsx)(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
461
461
|
? `Received payment`
|
|
462
462
|
: `Received ${(0, number_1.formatTokenAmount)(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: false }, dTxs.txHash)))
|
|
@@ -475,7 +475,7 @@ exports.OrderDetails = (0, react_4.memo)(function OrderDetails({ mode = "modal",
|
|
|
475
475
|
// This boolean indicates that user finish payment, and waiting for the deposit to be confirmed. We get this from query params (waitingForDeposit=true)
|
|
476
476
|
const waitingForDeposit = new URLSearchParams(window.location.search).get("waitingForDeposit") === "true";
|
|
477
477
|
if (depositTxs?.length || waitingForDeposit) {
|
|
478
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
478
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), (0, jsx_runtime_1.jsx)(OrderDetailsCollapsible_1.OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), (0, jsx_runtime_1.jsx)(Accordion_1.Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: (0, jsx_runtime_1.jsxs)(Accordion_1.AccordionItem, { value: "deposit-details", className: "order-details-deposit-item", children: [(0, jsx_runtime_1.jsx)(Accordion_1.AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), (0, jsx_runtime_1.jsx)(Accordion_1.AccordionContent, { className: "accordion-content pl-2", children: (0, jsx_runtime_1.jsxs)("div", { className: "relative flex w-full flex-col gap-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: (0, jsx_runtime_1.jsx)(react_3.motion.div, { className: "from-as-brand/50 absolute left-[2px] top-0 z-10 w-[3px] bg-gradient-to-b from-20% via-purple-500/50 via-80% to-transparent", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1, ease: "easeInOut" } }) }), (depositTxs || []).map((dTxs, index) => ((0, jsx_runtime_1.jsx)(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
479
479
|
? `Received payment`
|
|
480
480
|
: `Received ${(0, number_1.formatTokenAmount)(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: index < (depositTxs || []).length - 1 ? false : !depositEnoughAmount }, dTxs.txHash))), statusDisplay === "failure" ? ((0, jsx_runtime_1.jsx)(TransactionDetails, { title: statusText, chainId: order.srcChain, tx: null, isProcessing: false, delay: 0.5 })) : depositEnoughAmount ? ((0, jsx_runtime_1.jsx)(TransactionDetails, { title: order.type === "swap"
|
|
481
481
|
? "Processing Swap"
|
|
@@ -489,7 +489,7 @@ exports.OrderDetails = (0, react_4.memo)(function OrderDetails({ mode = "modal",
|
|
|
489
489
|
? `Waiting for payment`
|
|
490
490
|
: `Waiting for deposit ${formattedDepositDeficit} ${srcToken.symbol}`, chainId: order.srcChain, tx: null, isProcessing: true, delay: 0.5 }))] }) })] }) }), !depositEnoughAmount && order.status !== "expired" && ((0, jsx_runtime_1.jsx)(InsufficientDepositPayment_1.InsufficientDepositPayment, { order: order, srcToken: srcToken, depositDeficit: depositDeficit, phantomWalletAddress: phantomWalletAddress, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, onPayment: handlePayment }))] }));
|
|
491
491
|
}
|
|
492
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
492
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(OrderStatus_1.OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), statusDisplay === "processing" && ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: order.onrampMetadata ? ((0, jsx_runtime_1.jsx)(PaymentVendorUI_1.default, { order: order, dstTokenSymbol: dstToken.symbol })) : effectiveCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
493
493
|
effectiveCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.GLOBAL_WALLET ? ((0, jsx_runtime_1.jsx)(ConnectWalletPayment_1.default, { order: order, onPayment: handlePayment, onCancel: handleBack, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, phantomWalletAddress: phantomWalletAddress, tournament: tournament, nft: nft, cryptoPaymentMethod: effectiveCryptoPaymentMethod, onPaymentMethodChange: onPaymentMethodChange })) : effectiveCryptoPaymentMethod === CryptoPaymentMethod_1.CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
|
|
494
494
|
// Transfer Crypto Payment Method - Show new card-based UI
|
|
495
495
|
(0, jsx_runtime_1.jsx)(TransferCryptoDetails_1.TransferCryptoDetails, { order: order, recipientName: recipientName, srcToken: srcToken, dstToken: dstToken, tournament: tournament, nft: nft, onBack: handleBack, onPaymentMethodChange: onPaymentMethodChange })) : ((0, jsx_runtime_1.jsxs)("div", { className: "order-details-payment-section relative flex w-full flex-1 flex-col", children: [(0, jsx_runtime_1.jsxs)("div", { className: "order-details-amount-section flex flex-col gap-1", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-as-primary/50 order-details-amount-label", children: "Please send" }), (0, jsx_runtime_1.jsxs)("div", { className: "order-details-amount-container flex w-full flex-wrap items-center gap-6 sm:justify-between sm:gap-0", children: [(0, jsx_runtime_1.jsx)(react_1.CopyToClipboard, { text: roundedUpSrcAmount, onCopy: () => {
|
|
@@ -12,10 +12,11 @@ const invariant_1 = __importDefault(require("invariant"));
|
|
|
12
12
|
const react_1 = require("react");
|
|
13
13
|
const sonner_1 = require("sonner");
|
|
14
14
|
const thirdweb_2 = require("thirdweb");
|
|
15
|
+
const react_2 = require("thirdweb/react");
|
|
16
|
+
const viem_1 = require("viem");
|
|
15
17
|
const wagmi_1 = require("wagmi");
|
|
16
18
|
const components_1 = require("../components");
|
|
17
19
|
const useAccountWallet_1 = require("./useAccountWallet");
|
|
18
|
-
const viem_1 = require("viem");
|
|
19
20
|
const partnerId = String(process.env.PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
20
21
|
process.env.NEXT_PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
21
22
|
process.env.PUBLIC_GLOBAL_ACCOUNTS_PARTNER_ID ||
|
|
@@ -25,37 +26,43 @@ function useUnifiedChainSwitchAndExecute() {
|
|
|
25
26
|
const { data: walletClient } = (0, wagmi_1.useWalletClient)();
|
|
26
27
|
const { switchChainAsync } = (0, wagmi_1.useSwitchChain)();
|
|
27
28
|
const [isSwitchingOrExecuting, setIsSwitchingOrExecuting] = (0, react_1.useState)(false);
|
|
28
|
-
const
|
|
29
|
+
const activeWallet = (0, react_2.useActiveWallet)();
|
|
30
|
+
const { isActiveSmartWallet, isActiveEOAWallet, connectedEOAWallet } = (0, useAccountWallet_1.useAccountWallet)();
|
|
29
31
|
const { account: aaAccount } = (0, components_1.useB3)();
|
|
30
32
|
// Handle EOA wallet chain switch and execute transaction
|
|
31
33
|
const handleEOASwitchChainAndSendTransaction = (0, react_1.useCallback)(async (targetChainId, params) => {
|
|
32
|
-
if (!
|
|
34
|
+
if (!connectedEOAWallet) {
|
|
33
35
|
sonner_1.toast.error("Please connect your wallet");
|
|
34
36
|
return;
|
|
35
37
|
}
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
+
// Get target chain configuration once
|
|
39
|
+
const targetChain = supported_1.supportedChains.find(chain => chain.id === targetChainId);
|
|
40
|
+
if (!targetChain) {
|
|
41
|
+
sonner_1.toast.error(`Chain ${targetChainId} is not supported`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const currentChainId = activeWallet?.getChain()?.id;
|
|
45
|
+
const onCorrectChain = currentChainId === targetChainId;
|
|
38
46
|
// Helper function to execute the transaction
|
|
39
47
|
const executeTransaction = async () => {
|
|
40
|
-
const signer =
|
|
48
|
+
const signer = activeWallet?.getAccount();
|
|
41
49
|
if (!signer) {
|
|
42
50
|
throw new Error("No account connected");
|
|
43
51
|
}
|
|
44
|
-
//
|
|
45
|
-
const
|
|
46
|
-
if (
|
|
47
|
-
|
|
52
|
+
// Coinbase Smart Wallet specific chain switching (different behavior from other wallets)
|
|
53
|
+
const walletChain = connectedEOAWallet.getChain();
|
|
54
|
+
if (walletChain?.id !== targetChainId) {
|
|
55
|
+
activeWallet?.switchChain((0, supported_1.getThirdwebChain)(targetChainId));
|
|
48
56
|
}
|
|
49
57
|
(0, invariant_1.default)((0, viem_1.isAddress)(params.to), "params.to is not a valid address");
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
chain: targetChain,
|
|
58
|
+
const result = await signer.sendTransaction({
|
|
59
|
+
chainId: targetChainId,
|
|
53
60
|
to: params.to,
|
|
54
61
|
data: params.data,
|
|
55
62
|
value: params.value,
|
|
56
63
|
});
|
|
57
|
-
sonner_1.toast.success(`Transaction sent: ${
|
|
58
|
-
return
|
|
64
|
+
sonner_1.toast.success(`Transaction sent: ${result.transactionHash.slice(0, 10)}...`);
|
|
65
|
+
return result.transactionHash;
|
|
59
66
|
};
|
|
60
67
|
try {
|
|
61
68
|
setIsSwitchingOrExecuting(true);
|
|
@@ -63,11 +70,6 @@ function useUnifiedChainSwitchAndExecute() {
|
|
|
63
70
|
return await executeTransaction();
|
|
64
71
|
}
|
|
65
72
|
const switchingToastId = sonner_1.toast.info(`Switching to ${(0, anyspend_1.getChainName)(targetChainId)}…`);
|
|
66
|
-
const targetChain = supported_1.supportedChains.find(chain => chain.id === targetChainId);
|
|
67
|
-
if (!targetChain) {
|
|
68
|
-
sonner_1.toast.error(`Chain ${targetChainId} is not supported`);
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
73
|
const blockExplorerUrl = targetChain.blockExplorers?.default.url;
|
|
72
74
|
(0, invariant_1.default)(blockExplorerUrl, "Block explorer URL is required");
|
|
73
75
|
const nativeCurrency = (0, anyspend_1.getNativeToken)(targetChainId);
|
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { RELAY_SOLANA_MAINNET_CHAIN_ID } from "../../../../anyspend/index.js";
|
|
4
|
-
import { ShinyButton, useProfile } from "../../../../global-account/react/index.js";
|
|
4
|
+
import { ShinyButton, useAccountWallet, useProfile } from "../../../../global-account/react/index.js";
|
|
5
5
|
import centerTruncate from "../../../../shared/utils/centerTruncate.js";
|
|
6
6
|
import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
7
7
|
import { motion } from "framer-motion";
|
|
8
8
|
import { ChevronRight, Loader2 } from "lucide-react";
|
|
9
|
-
import { useAccount } from "wagmi";
|
|
10
9
|
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod.js";
|
|
11
10
|
import { OrderDetailsCollapsible } from "./OrderDetailsCollapsible.js";
|
|
12
11
|
import { PaymentMethodSwitch } from "./PaymentMethodSwitch.js";
|
|
13
12
|
export default function ConnectWalletPayment({ order, onPayment, txLoading, isSwitchingOrExecuting, phantomWalletAddress, tournament, nft, cryptoPaymentMethod, onPaymentMethodChange, }) {
|
|
14
13
|
const profile = useProfile({ address: order.recipientAddress });
|
|
15
14
|
const recipientName = profile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
16
|
-
const {
|
|
15
|
+
const { connectedEOAWallet, connectedSmartWallet } = useAccountWallet();
|
|
16
|
+
const connectedEvmAddress = cryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
|
|
17
|
+
? connectedSmartWallet?.getAccount()?.address
|
|
18
|
+
: connectedEOAWallet?.getAccount()?.address;
|
|
17
19
|
const srcToken = order.metadata.srcToken;
|
|
18
20
|
const dstToken = order.metadata.dstToken;
|
|
19
21
|
const expectedDstAmount = order.type === "mint_nft" ||
|
|
@@ -32,5 +34,5 @@ export default function ConnectWalletPayment({ order, onPayment, txLoading, isSw
|
|
|
32
34
|
? "Pay from Global Account"
|
|
33
35
|
: "Pay from Connected Wallet" }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) }), _jsxs("span", { className: "label-style text-as-primary/50 text-xs", children: ["Connected to:", " ", order.srcChain === RELAY_SOLANA_MAINNET_CHAIN_ID && phantomWalletAddress
|
|
34
36
|
? centerTruncate(phantomWalletAddress, 6)
|
|
35
|
-
: centerTruncate(
|
|
37
|
+
: centerTruncate(connectedEvmAddress || "")] }), _jsx(PaymentMethodSwitch, { currentMethod: cryptoPaymentMethod, onMethodChange: onPaymentMethodChange }), _jsx("div", { className: "mt-4", children: _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }) })] }) }));
|
|
36
38
|
}
|
|
@@ -3,11 +3,14 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useAccountWallet } from "../../../../global-account/react/index.js";
|
|
4
4
|
import { cn } from "../../../../shared/utils/cn.js";
|
|
5
5
|
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
6
|
+
import { client } from "../../../../shared/utils/thirdweb.js";
|
|
6
7
|
import { WalletCoinbase, WalletMetamask, WalletPhantom, WalletRainbow, WalletWalletConnect } from "@web3icons/react";
|
|
7
8
|
import { ChevronLeft, ChevronRightCircle, Wallet, X, ZapIcon } from "lucide-react";
|
|
8
9
|
import { useState } from "react";
|
|
9
10
|
import { createPortal } from "react-dom";
|
|
10
11
|
import { toast } from "sonner";
|
|
12
|
+
import { useSetActiveWallet, useWalletInfo } from "thirdweb/react";
|
|
13
|
+
import { createWallet } from "thirdweb/wallets";
|
|
11
14
|
import { useAccount, useConnect, useDisconnect, useWalletClient } from "wagmi";
|
|
12
15
|
export var CryptoPaymentMethodType;
|
|
13
16
|
(function (CryptoPaymentMethodType) {
|
|
@@ -17,12 +20,58 @@ export var CryptoPaymentMethodType;
|
|
|
17
20
|
CryptoPaymentMethodType["TRANSFER_CRYPTO"] = "transfer_crypto";
|
|
18
21
|
})(CryptoPaymentMethodType || (CryptoPaymentMethodType = {}));
|
|
19
22
|
export function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentMethod, isCreatingOrder, onBack, onSelectPaymentMethod, }) {
|
|
20
|
-
const { wallet: globalWallet,
|
|
21
|
-
const { address, isConnected
|
|
23
|
+
const { wallet: globalWallet, connectedEOAWallet: connectedEOAWallet, connectedSmartWallet: connectedSmartWallet, } = useAccountWallet();
|
|
24
|
+
const { connector, address, isConnected: wagmiWalletIsConnected } = useAccount();
|
|
22
25
|
const { connect, connectors, isPending } = useConnect();
|
|
23
26
|
const { disconnect } = useDisconnect();
|
|
24
27
|
const { data: walletClient } = useWalletClient();
|
|
25
28
|
const [showWalletModal, setShowWalletModal] = useState(false);
|
|
29
|
+
const setActiveWallet = useSetActiveWallet();
|
|
30
|
+
const { data: eoaWalletInfo } = useWalletInfo(connectedEOAWallet?.id);
|
|
31
|
+
const isConnected = !!connectedEOAWallet;
|
|
32
|
+
const globalAddress = connectedSmartWallet?.getAccount()?.address;
|
|
33
|
+
// Helper function to check if two addresses are the same
|
|
34
|
+
const isSameAddress = (addr1, addr2) => {
|
|
35
|
+
if (!addr1 || !addr2)
|
|
36
|
+
return false;
|
|
37
|
+
return addr1.toLowerCase() === addr2.toLowerCase();
|
|
38
|
+
};
|
|
39
|
+
// Check if connectedEOAWallet and wagmi wallet represent the same wallet
|
|
40
|
+
const connectedEOAAddress = connectedEOAWallet?.getAccount()?.address;
|
|
41
|
+
const wagmiAddress = address;
|
|
42
|
+
const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress);
|
|
43
|
+
// Determine which wallet to show (prefer connectedEOAWallet if both exist and are the same)
|
|
44
|
+
const shouldShowConnectedEOA = !!connectedEOAWallet;
|
|
45
|
+
const shouldShowWagmiWallet = wagmiWalletIsConnected && (!isWalletDuplicated || !connectedEOAWallet);
|
|
46
|
+
// Map wagmi connector names to thirdweb wallet IDs
|
|
47
|
+
const getThirdwebWalletId = (connectorName) => {
|
|
48
|
+
const walletMap = {
|
|
49
|
+
MetaMask: "io.metamask",
|
|
50
|
+
"Coinbase Wallet": "com.coinbase.wallet",
|
|
51
|
+
Rainbow: "me.rainbow",
|
|
52
|
+
WalletConnect: "walletConnect",
|
|
53
|
+
Phantom: "app.phantom",
|
|
54
|
+
};
|
|
55
|
+
return walletMap[connectorName] || null;
|
|
56
|
+
};
|
|
57
|
+
// Create thirdweb wallet from wagmi connector
|
|
58
|
+
const createThirdwebWalletFromConnector = async (connectorName) => {
|
|
59
|
+
const walletId = getThirdwebWalletId(connectorName);
|
|
60
|
+
if (!walletId) {
|
|
61
|
+
console.warn(`No thirdweb wallet ID found for connector: ${connectorName}`);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
try {
|
|
65
|
+
const thirdwebWallet = createWallet(walletId);
|
|
66
|
+
// Connect the wallet to sync with the existing wagmi connection
|
|
67
|
+
await thirdwebWallet.connect({ client });
|
|
68
|
+
return thirdwebWallet;
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
console.error(`Failed to create thirdweb wallet for ${connectorName}:`, error);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
};
|
|
26
75
|
// Define available wallet connectors
|
|
27
76
|
const availableConnectors = connectors.filter(connector => ["MetaMask", "WalletConnect", "Coinbase Wallet", "Rainbow", "Phantom"].includes(connector.name));
|
|
28
77
|
// Define wallet options with icons and info
|
|
@@ -123,9 +172,30 @@ export function CryptoPaymentMethod({ selectedPaymentMethod, setSelectedPaymentM
|
|
|
123
172
|
}, 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", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-blue-100", children: _jsx(Wallet, { className: "h-4 w-4 text-blue-600" }) }), _jsx("div", { className: "flex flex-col items-start text-left", children: _jsx("h4", { className: "text-as-primary font-semibold", children: "Connect wallet" }) })] }), _jsx(ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), _jsxs("button", { onClick: () => {
|
|
124
173
|
setSelectedPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
125
174
|
onSelectPaymentMethod(CryptoPaymentMethodType.TRANSFER_CRYPTO);
|
|
126
|
-
}, disabled: isCreatingOrder, className: "crypto-payment-method-transfer 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", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-orange-100", children: _jsx(ZapIcon, { className: "h-4 w-4" }) }), _jsx("div", { className: "flex flex-col items-start text-left", children: _jsx("h4", { className: "text-as-primary font-semibold", children: "Transfer crypto" }) })] }), _jsx(ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), (
|
|
175
|
+
}, disabled: isCreatingOrder, className: "crypto-payment-method-transfer 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", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-8 w-8 items-center justify-center rounded-full bg-orange-100", children: _jsx(ZapIcon, { className: "h-4 w-4" }) }), _jsx("div", { className: "flex flex-col items-start text-left", children: _jsx("h4", { className: "text-as-primary font-semibold", children: "Transfer crypto" }) })] }), _jsx(ChevronRightCircle, { className: "text-as-primary/40 group-hover:text-as-primary/60 h-5 w-5 transition-colors" })] }), (shouldShowConnectedEOA || shouldShowWagmiWallet || globalAddress) && (_jsxs("div", { className: "installed-wallets", children: [_jsx("h3", { className: "text-as-primary/80 mb-3 text-sm font-medium", children: "Connected wallets" }), _jsxs("div", { className: "space-y-2", children: [shouldShowConnectedEOA && (_jsx("button", { onClick: () => {
|
|
176
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
177
|
+
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
178
|
+
setActiveWallet(connectedEOAWallet);
|
|
179
|
+
toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
|
|
180
|
+
}, className: cn("crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
181
|
+
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
182
|
+
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80"), children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "wallet-icon flex h-10 w-10 items-center justify-center rounded-full bg-blue-100", children: _jsx(Wallet, { className: "h-5 w-5 text-blue-600" }) }), _jsxs("div", { className: "flex flex-col", children: [_jsx("span", { className: "text-as-primary font-semibold", children: eoaWalletInfo?.name || connector?.name || "Connected Wallet" }), _jsx("span", { className: "text-as-primary/60 text-sm", children: shortenAddress(connectedEOAWallet?.getAccount()?.address || "") })] })] }), _jsxs("div", { className: "flex items-center gap-2", children: [selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET && (_jsx("div", { className: "h-2 w-2 rounded-full bg-green-500" })), _jsx("button", { onClick: e => {
|
|
183
|
+
e.stopPropagation();
|
|
184
|
+
disconnect();
|
|
185
|
+
toast.success("Wallet disconnected");
|
|
186
|
+
if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
187
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
188
|
+
}
|
|
189
|
+
}, className: "text-as-primary/60 hover:text-as-primary/80 rounded-lg p-1.5 transition-colors", children: _jsx(X, { className: "h-4 w-4" }) })] })] }) })), shouldShowWagmiWallet && (_jsx("button", { onClick: async () => {
|
|
127
190
|
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
128
191
|
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
192
|
+
// Create thirdweb wallet from wagmi connector
|
|
193
|
+
if (connector?.name) {
|
|
194
|
+
const thirdwebWallet = await createThirdwebWalletFromConnector(connector.name);
|
|
195
|
+
if (thirdwebWallet) {
|
|
196
|
+
setActiveWallet(thirdwebWallet);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
129
199
|
toast.success(`Selected ${connector?.name || "wallet"}`);
|
|
130
200
|
}, className: cn("crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md", selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
131
201
|
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
@@ -133,9 +133,9 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
133
133
|
const colorMode = theme || "light";
|
|
134
134
|
// Read crypto payment method from URL parameters
|
|
135
135
|
const cryptoPaymentMethodFromUrl = searchParams.get("cryptoPaymentMethod");
|
|
136
|
-
const effectiveCryptoPaymentMethod =
|
|
137
|
-
|
|
138
|
-
|
|
136
|
+
const effectiveCryptoPaymentMethod = selectedCryptoPaymentMethod !== CryptoPaymentMethodType.NONE
|
|
137
|
+
? selectedCryptoPaymentMethod
|
|
138
|
+
: cryptoPaymentMethod || cryptoPaymentMethodFromUrl || CryptoPaymentMethodType.NONE;
|
|
139
139
|
const setB3ModalOpen = useModalStore((state) => state.setB3ModalOpen);
|
|
140
140
|
const srcToken = order.metadata.srcToken;
|
|
141
141
|
const dstToken = order.metadata.dstToken;
|
|
@@ -416,7 +416,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
416
416
|
}
|
|
417
417
|
};
|
|
418
418
|
if (refundTxs.length > 0) {
|
|
419
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
419
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "refund-details", className: "order-details-refund-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
420
420
|
? depositTxs.map(dTx => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
421
421
|
? `Received payment`
|
|
422
422
|
: `Received ${formatTokenAmount(BigInt(dTx.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTx, isProcessing: false }, dTx.txHash)))
|
|
@@ -425,7 +425,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
425
425
|
: null] }) })] }) }), order.errorDetails && (_jsx("div", { className: "flex justify-center", children: _jsx("span", { className: "text-as-primary/50 text-center text-sm", style: { maxWidth: "40ch" }, children: getErrorDisplay(order.errorDetails) }) })), _jsx("button", { className: "order-close-button order-details-close-btn bg-as-brand flex w-full items-center justify-center gap-2 rounded-lg p-2 font-semibold text-white", onClick: mode === "page" ? handleBack : handleCloseModal, children: mode === "page" ? (_jsxs(_Fragment, { children: ["Return to Home ", _jsx(Home, { className: "ml-2 h-4 w-4" })] })) : ("Close") })] }));
|
|
426
426
|
}
|
|
427
427
|
if (executeTx) {
|
|
428
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
428
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "execute-details", className: "order-details-execute-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
429
429
|
? depositTxs.map(dTxs => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
430
430
|
? `Received payment`
|
|
431
431
|
: `Received ${formatTokenAmount(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: false }, dTxs.txHash)))
|
|
@@ -450,7 +450,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
450
450
|
}), _jsx(ExternalLink, { className: "ml-2 h-4 w-4" })] }) }) }), order.type === "join_tournament" && order.status === "executed" && (_jsxs(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "flex w-full items-center gap-2", disabled: txLoading || isSwitchingOrExecuting, onClick: handleCloseModal, children: [_jsx("span", { className: "pl-4", children: "Continue to Tournament" }), _jsx(ChevronRight, { className: "h-4 w-4" })] })), order.status === "executed" && (_jsx("button", { className: "order-close-button order-details-close-btn bg-as-brand flex w-full items-center justify-center gap-2 rounded-lg p-2 font-semibold text-white", onClick: mode === "page" ? handleBack : handleCloseModal, children: mode === "page" ? (_jsxs(_Fragment, { children: ["Return to Home ", _jsx(Home, { className: "ml-2 h-4 w-4" })] })) : ("Close") }))] }));
|
|
451
451
|
}
|
|
452
452
|
if (relayTxs.length > 0 && relayTxs.every(tx => tx.status === "success")) {
|
|
453
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
453
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "more-details", className: "order-details-more-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "More Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
454
454
|
? depositTxs.map(dTxs => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
455
455
|
? `Received payment`
|
|
456
456
|
: `Received ${formatTokenAmount(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: false }, dTxs.txHash)))
|
|
@@ -469,7 +469,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
469
469
|
// This boolean indicates that user finish payment, and waiting for the deposit to be confirmed. We get this from query params (waitingForDeposit=true)
|
|
470
470
|
const waitingForDeposit = new URLSearchParams(window.location.search).get("waitingForDeposit") === "true";
|
|
471
471
|
if (depositTxs?.length || waitingForDeposit) {
|
|
472
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
472
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "deposit-details", className: "order-details-deposit-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-6", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "from-as-brand/50 absolute left-[2px] top-0 z-10 w-[3px] bg-gradient-to-b from-20% via-purple-500/50 via-80% to-transparent", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1, ease: "easeInOut" } }) }), (depositTxs || []).map((dTxs, index) => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
473
473
|
? `Received payment`
|
|
474
474
|
: `Received ${formatTokenAmount(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: index < (depositTxs || []).length - 1 ? false : !depositEnoughAmount }, dTxs.txHash))), statusDisplay === "failure" ? (_jsx(TransactionDetails, { title: statusText, chainId: order.srcChain, tx: null, isProcessing: false, delay: 0.5 })) : depositEnoughAmount ? (_jsx(TransactionDetails, { title: order.type === "swap"
|
|
475
475
|
? "Processing Swap"
|
|
@@ -483,7 +483,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
483
483
|
? `Waiting for payment`
|
|
484
484
|
: `Waiting for deposit ${formattedDepositDeficit} ${srcToken.symbol}`, chainId: order.srcChain, tx: null, isProcessing: true, delay: 0.5 }))] }) })] }) }), !depositEnoughAmount && order.status !== "expired" && (_jsx(InsufficientDepositPayment, { order: order, srcToken: srcToken, depositDeficit: depositDeficit, phantomWalletAddress: phantomWalletAddress, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, onPayment: handlePayment }))] }));
|
|
485
485
|
}
|
|
486
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod:
|
|
486
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), statusDisplay === "processing" && (_jsx(_Fragment, { children: order.onrampMetadata ? (_jsx(PaymentVendorUI, { order: order, dstTokenSymbol: dstToken.symbol })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET ||
|
|
487
487
|
effectiveCryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET ? (_jsx(ConnectWalletPayment, { order: order, onPayment: handlePayment, onCancel: handleBack, txLoading: txLoading, isSwitchingOrExecuting: isSwitchingOrExecuting, phantomWalletAddress: phantomWalletAddress, tournament: tournament, nft: nft, cryptoPaymentMethod: effectiveCryptoPaymentMethod, onPaymentMethodChange: onPaymentMethodChange })) : effectiveCryptoPaymentMethod === CryptoPaymentMethodType.TRANSFER_CRYPTO ? (
|
|
488
488
|
// Transfer Crypto Payment Method - Show new card-based UI
|
|
489
489
|
_jsx(TransferCryptoDetails, { order: order, recipientName: recipientName, srcToken: srcToken, dstToken: dstToken, tournament: tournament, nft: nft, onBack: handleBack, onPaymentMethodChange: onPaymentMethodChange })) : (_jsxs("div", { className: "order-details-payment-section relative flex w-full flex-1 flex-col", children: [_jsxs("div", { className: "order-details-amount-section flex flex-col gap-1", children: [_jsx("span", { className: "text-as-primary/50 order-details-amount-label", children: "Please send" }), _jsxs("div", { className: "order-details-amount-container flex w-full flex-wrap items-center gap-6 sm:justify-between sm:gap-0", children: [_jsx(CopyToClipboard, { text: roundedUpSrcAmount, onCopy: () => {
|
|
@@ -6,10 +6,11 @@ import invariant from "invariant";
|
|
|
6
6
|
import { useCallback, useState } from "react";
|
|
7
7
|
import { toast } from "sonner";
|
|
8
8
|
import { prepareTransaction, sendTransaction as twSendTransaction } from "thirdweb";
|
|
9
|
+
import { useActiveWallet } from "thirdweb/react";
|
|
10
|
+
import { isAddress } from "viem";
|
|
9
11
|
import { useSwitchChain, useWalletClient } from "wagmi";
|
|
10
12
|
import { useB3 } from "../components/index.js";
|
|
11
13
|
import { useAccountWallet } from "./useAccountWallet.js";
|
|
12
|
-
import { isAddress } from "viem";
|
|
13
14
|
const partnerId = String(process.env.PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
14
15
|
process.env.NEXT_PUBLIC_THIRDWEB_PARTNER_ID ||
|
|
15
16
|
process.env.PUBLIC_GLOBAL_ACCOUNTS_PARTNER_ID ||
|
|
@@ -19,37 +20,43 @@ export function useUnifiedChainSwitchAndExecute() {
|
|
|
19
20
|
const { data: walletClient } = useWalletClient();
|
|
20
21
|
const { switchChainAsync } = useSwitchChain();
|
|
21
22
|
const [isSwitchingOrExecuting, setIsSwitchingOrExecuting] = useState(false);
|
|
22
|
-
const
|
|
23
|
+
const activeWallet = useActiveWallet();
|
|
24
|
+
const { isActiveSmartWallet, isActiveEOAWallet, connectedEOAWallet } = useAccountWallet();
|
|
23
25
|
const { account: aaAccount } = useB3();
|
|
24
26
|
// Handle EOA wallet chain switch and execute transaction
|
|
25
27
|
const handleEOASwitchChainAndSendTransaction = useCallback(async (targetChainId, params) => {
|
|
26
|
-
if (!
|
|
28
|
+
if (!connectedEOAWallet) {
|
|
27
29
|
toast.error("Please connect your wallet");
|
|
28
30
|
return;
|
|
29
31
|
}
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
+
// Get target chain configuration once
|
|
33
|
+
const targetChain = supportedChains.find(chain => chain.id === targetChainId);
|
|
34
|
+
if (!targetChain) {
|
|
35
|
+
toast.error(`Chain ${targetChainId} is not supported`);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
const currentChainId = activeWallet?.getChain()?.id;
|
|
39
|
+
const onCorrectChain = currentChainId === targetChainId;
|
|
32
40
|
// Helper function to execute the transaction
|
|
33
41
|
const executeTransaction = async () => {
|
|
34
|
-
const signer =
|
|
42
|
+
const signer = activeWallet?.getAccount();
|
|
35
43
|
if (!signer) {
|
|
36
44
|
throw new Error("No account connected");
|
|
37
45
|
}
|
|
38
|
-
//
|
|
39
|
-
const
|
|
40
|
-
if (
|
|
41
|
-
|
|
46
|
+
// Coinbase Smart Wallet specific chain switching (different behavior from other wallets)
|
|
47
|
+
const walletChain = connectedEOAWallet.getChain();
|
|
48
|
+
if (walletChain?.id !== targetChainId) {
|
|
49
|
+
activeWallet?.switchChain(getThirdwebChain(targetChainId));
|
|
42
50
|
}
|
|
43
51
|
invariant(isAddress(params.to), "params.to is not a valid address");
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
chain: targetChain,
|
|
52
|
+
const result = await signer.sendTransaction({
|
|
53
|
+
chainId: targetChainId,
|
|
47
54
|
to: params.to,
|
|
48
55
|
data: params.data,
|
|
49
56
|
value: params.value,
|
|
50
57
|
});
|
|
51
|
-
toast.success(`Transaction sent: ${
|
|
52
|
-
return
|
|
58
|
+
toast.success(`Transaction sent: ${result.transactionHash.slice(0, 10)}...`);
|
|
59
|
+
return result.transactionHash;
|
|
53
60
|
};
|
|
54
61
|
try {
|
|
55
62
|
setIsSwitchingOrExecuting(true);
|
|
@@ -57,11 +64,6 @@ export function useUnifiedChainSwitchAndExecute() {
|
|
|
57
64
|
return await executeTransaction();
|
|
58
65
|
}
|
|
59
66
|
const switchingToastId = toast.info(`Switching to ${getChainName(targetChainId)}…`);
|
|
60
|
-
const targetChain = supportedChains.find(chain => chain.id === targetChainId);
|
|
61
|
-
if (!targetChain) {
|
|
62
|
-
toast.error(`Chain ${targetChainId} is not supported`);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
67
|
const blockExplorerUrl = targetChain.blockExplorers?.default.url;
|
|
66
68
|
invariant(blockExplorerUrl, "Block explorer URL is required");
|
|
67
69
|
const nativeCurrency = getNativeToken(targetChainId);
|
package/package.json
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
import { RELAY_SOLANA_MAINNET_CHAIN_ID } from "@b3dotfun/sdk/anyspend";
|
|
4
4
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
5
|
-
import { ShinyButton, useProfile } from "@b3dotfun/sdk/global-account/react";
|
|
5
|
+
import { ShinyButton, useAccountWallet, useProfile } from "@b3dotfun/sdk/global-account/react";
|
|
6
6
|
import centerTruncate from "@b3dotfun/sdk/shared/utils/centerTruncate";
|
|
7
7
|
import { formatTokenAmount } from "@b3dotfun/sdk/shared/utils/number";
|
|
8
8
|
import { motion } from "framer-motion";
|
|
9
9
|
import { ChevronRight, Loader2 } from "lucide-react";
|
|
10
|
-
import { useAccount } from "wagmi";
|
|
11
10
|
import { CryptoPaymentMethodType } from "./CryptoPaymentMethod";
|
|
12
11
|
import { OrderDetailsCollapsible } from "./OrderDetailsCollapsible";
|
|
13
12
|
import { PaymentMethodSwitch } from "./PaymentMethodSwitch";
|
|
@@ -41,7 +40,11 @@ export default function ConnectWalletPayment({
|
|
|
41
40
|
}: ConnectWalletPaymentProps) {
|
|
42
41
|
const profile = useProfile({ address: order.recipientAddress });
|
|
43
42
|
const recipientName = profile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
44
|
-
const {
|
|
43
|
+
const { connectedEOAWallet, connectedSmartWallet } = useAccountWallet();
|
|
44
|
+
const connectedEvmAddress =
|
|
45
|
+
cryptoPaymentMethod === CryptoPaymentMethodType.GLOBAL_WALLET
|
|
46
|
+
? connectedSmartWallet?.getAccount()?.address
|
|
47
|
+
: connectedEOAWallet?.getAccount()?.address;
|
|
45
48
|
|
|
46
49
|
const srcToken = order.metadata.srcToken;
|
|
47
50
|
const dstToken = order.metadata.dstToken;
|
|
@@ -97,7 +100,7 @@ export default function ConnectWalletPayment({
|
|
|
97
100
|
Connected to:{" "}
|
|
98
101
|
{order.srcChain === RELAY_SOLANA_MAINNET_CHAIN_ID && phantomWalletAddress
|
|
99
102
|
? centerTruncate(phantomWalletAddress, 6)
|
|
100
|
-
: centerTruncate(
|
|
103
|
+
: centerTruncate(connectedEvmAddress || "")}
|
|
101
104
|
</span>
|
|
102
105
|
|
|
103
106
|
<PaymentMethodSwitch currentMethod={cryptoPaymentMethod} onMethodChange={onPaymentMethodChange} />
|
|
@@ -3,11 +3,14 @@
|
|
|
3
3
|
import { useAccountWallet } from "@b3dotfun/sdk/global-account/react";
|
|
4
4
|
import { cn } from "@b3dotfun/sdk/shared/utils/cn";
|
|
5
5
|
import { shortenAddress } from "@b3dotfun/sdk/shared/utils/formatAddress";
|
|
6
|
+
import { client } from "@b3dotfun/sdk/shared/utils/thirdweb";
|
|
6
7
|
import { WalletCoinbase, WalletMetamask, WalletPhantom, WalletRainbow, WalletWalletConnect } from "@web3icons/react";
|
|
7
8
|
import { ChevronLeft, ChevronRightCircle, Wallet, X, ZapIcon } from "lucide-react";
|
|
8
9
|
import { useState } from "react";
|
|
9
10
|
import { createPortal } from "react-dom";
|
|
10
11
|
import { toast } from "sonner";
|
|
12
|
+
import { useSetActiveWallet, useWalletInfo } from "thirdweb/react";
|
|
13
|
+
import { WalletId, createWallet } from "thirdweb/wallets";
|
|
11
14
|
import { useAccount, useConnect, useDisconnect, useWalletClient } from "wagmi";
|
|
12
15
|
|
|
13
16
|
export enum CryptoPaymentMethodType {
|
|
@@ -38,13 +41,69 @@ export function CryptoPaymentMethod({
|
|
|
38
41
|
onBack,
|
|
39
42
|
onSelectPaymentMethod,
|
|
40
43
|
}: CryptoPaymentMethodProps) {
|
|
41
|
-
const {
|
|
42
|
-
|
|
44
|
+
const {
|
|
45
|
+
wallet: globalWallet,
|
|
46
|
+
connectedEOAWallet: connectedEOAWallet,
|
|
47
|
+
connectedSmartWallet: connectedSmartWallet,
|
|
48
|
+
} = useAccountWallet();
|
|
49
|
+
const { connector, address, isConnected: wagmiWalletIsConnected } = useAccount();
|
|
43
50
|
const { connect, connectors, isPending } = useConnect();
|
|
44
51
|
const { disconnect } = useDisconnect();
|
|
45
52
|
const { data: walletClient } = useWalletClient();
|
|
46
53
|
const [showWalletModal, setShowWalletModal] = useState(false);
|
|
47
54
|
|
|
55
|
+
const setActiveWallet = useSetActiveWallet();
|
|
56
|
+
const { data: eoaWalletInfo } = useWalletInfo(connectedEOAWallet?.id);
|
|
57
|
+
|
|
58
|
+
const isConnected = !!connectedEOAWallet;
|
|
59
|
+
const globalAddress = connectedSmartWallet?.getAccount()?.address;
|
|
60
|
+
|
|
61
|
+
// Helper function to check if two addresses are the same
|
|
62
|
+
const isSameAddress = (addr1?: string, addr2?: string): boolean => {
|
|
63
|
+
if (!addr1 || !addr2) return false;
|
|
64
|
+
return addr1.toLowerCase() === addr2.toLowerCase();
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// Check if connectedEOAWallet and wagmi wallet represent the same wallet
|
|
68
|
+
const connectedEOAAddress = connectedEOAWallet?.getAccount()?.address;
|
|
69
|
+
const wagmiAddress = address;
|
|
70
|
+
const isWalletDuplicated = isSameAddress(connectedEOAAddress, wagmiAddress);
|
|
71
|
+
|
|
72
|
+
// Determine which wallet to show (prefer connectedEOAWallet if both exist and are the same)
|
|
73
|
+
const shouldShowConnectedEOA = !!connectedEOAWallet;
|
|
74
|
+
const shouldShowWagmiWallet = wagmiWalletIsConnected && (!isWalletDuplicated || !connectedEOAWallet);
|
|
75
|
+
|
|
76
|
+
// Map wagmi connector names to thirdweb wallet IDs
|
|
77
|
+
const getThirdwebWalletId = (connectorName: string): WalletId | null => {
|
|
78
|
+
const walletMap: Record<string, WalletId> = {
|
|
79
|
+
MetaMask: "io.metamask",
|
|
80
|
+
"Coinbase Wallet": "com.coinbase.wallet",
|
|
81
|
+
Rainbow: "me.rainbow",
|
|
82
|
+
WalletConnect: "walletConnect",
|
|
83
|
+
Phantom: "app.phantom",
|
|
84
|
+
};
|
|
85
|
+
return walletMap[connectorName] || null;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
// Create thirdweb wallet from wagmi connector
|
|
89
|
+
const createThirdwebWalletFromConnector = async (connectorName: string) => {
|
|
90
|
+
const walletId = getThirdwebWalletId(connectorName);
|
|
91
|
+
if (!walletId) {
|
|
92
|
+
console.warn(`No thirdweb wallet ID found for connector: ${connectorName}`);
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
try {
|
|
97
|
+
const thirdwebWallet = createWallet(walletId);
|
|
98
|
+
// Connect the wallet to sync with the existing wagmi connection
|
|
99
|
+
await thirdwebWallet.connect({ client });
|
|
100
|
+
return thirdwebWallet;
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error(`Failed to create thirdweb wallet for ${connectorName}:`, error);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
48
107
|
// Define available wallet connectors
|
|
49
108
|
const availableConnectors = connectors.filter(connector =>
|
|
50
109
|
["MetaMask", "WalletConnect", "Coinbase Wallet", "Rainbow", "Phantom"].includes(connector.name),
|
|
@@ -202,16 +261,77 @@ export function CryptoPaymentMethod({
|
|
|
202
261
|
</button>
|
|
203
262
|
|
|
204
263
|
{/* Installed Wallets Section */}
|
|
205
|
-
{(
|
|
264
|
+
{(shouldShowConnectedEOA || shouldShowWagmiWallet || globalAddress) && (
|
|
206
265
|
<div className="installed-wallets">
|
|
207
266
|
<h3 className="text-as-primary/80 mb-3 text-sm font-medium">Connected wallets</h3>
|
|
208
267
|
<div className="space-y-2">
|
|
209
268
|
{/* Current Connected Wallet */}
|
|
210
|
-
|
|
269
|
+
|
|
270
|
+
{shouldShowConnectedEOA && (
|
|
211
271
|
<button
|
|
212
272
|
onClick={() => {
|
|
213
273
|
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
214
274
|
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
275
|
+
setActiveWallet(connectedEOAWallet);
|
|
276
|
+
toast.success(`Selected ${eoaWalletInfo?.name || connector?.name || "wallet"}`);
|
|
277
|
+
}}
|
|
278
|
+
className={cn(
|
|
279
|
+
"crypto-payment-method-connect-wallet w-full rounded-xl border p-4 text-left transition-all hover:shadow-md",
|
|
280
|
+
selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET
|
|
281
|
+
? "connected-wallet border-as-brand bg-as-brand/5"
|
|
282
|
+
: "border-as-border-secondary bg-as-surface-primary hover:border-as-secondary/80",
|
|
283
|
+
)}
|
|
284
|
+
>
|
|
285
|
+
<div className="flex items-center justify-between">
|
|
286
|
+
<div className="flex items-center gap-3">
|
|
287
|
+
<div className="wallet-icon flex h-10 w-10 items-center justify-center rounded-full bg-blue-100">
|
|
288
|
+
<Wallet className="h-5 w-5 text-blue-600" />
|
|
289
|
+
</div>
|
|
290
|
+
<div className="flex flex-col">
|
|
291
|
+
<span className="text-as-primary font-semibold">
|
|
292
|
+
{eoaWalletInfo?.name || connector?.name || "Connected Wallet"}
|
|
293
|
+
</span>
|
|
294
|
+
<span className="text-as-primary/60 text-sm">
|
|
295
|
+
{shortenAddress(connectedEOAWallet?.getAccount()?.address || "")}
|
|
296
|
+
</span>
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
<div className="flex items-center gap-2">
|
|
300
|
+
{selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET && (
|
|
301
|
+
<div className="h-2 w-2 rounded-full bg-green-500"></div>
|
|
302
|
+
)}
|
|
303
|
+
<button
|
|
304
|
+
onClick={e => {
|
|
305
|
+
e.stopPropagation();
|
|
306
|
+
disconnect();
|
|
307
|
+
toast.success("Wallet disconnected");
|
|
308
|
+
if (selectedPaymentMethod === CryptoPaymentMethodType.CONNECT_WALLET) {
|
|
309
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.NONE);
|
|
310
|
+
}
|
|
311
|
+
}}
|
|
312
|
+
className="text-as-primary/60 hover:text-as-primary/80 rounded-lg p-1.5 transition-colors"
|
|
313
|
+
>
|
|
314
|
+
<X className="h-4 w-4" />
|
|
315
|
+
</button>
|
|
316
|
+
</div>
|
|
317
|
+
</div>
|
|
318
|
+
</button>
|
|
319
|
+
)}
|
|
320
|
+
|
|
321
|
+
{shouldShowWagmiWallet && (
|
|
322
|
+
<button
|
|
323
|
+
onClick={async () => {
|
|
324
|
+
setSelectedPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
325
|
+
onSelectPaymentMethod(CryptoPaymentMethodType.CONNECT_WALLET);
|
|
326
|
+
|
|
327
|
+
// Create thirdweb wallet from wagmi connector
|
|
328
|
+
if (connector?.name) {
|
|
329
|
+
const thirdwebWallet = await createThirdwebWalletFromConnector(connector.name);
|
|
330
|
+
if (thirdwebWallet) {
|
|
331
|
+
setActiveWallet(thirdwebWallet);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
215
335
|
toast.success(`Selected ${connector?.name || "wallet"}`);
|
|
216
336
|
}}
|
|
217
337
|
className={cn(
|
|
@@ -223,10 +223,9 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
223
223
|
// Read crypto payment method from URL parameters
|
|
224
224
|
const cryptoPaymentMethodFromUrl = searchParams.get("cryptoPaymentMethod") as CryptoPaymentMethodType | null;
|
|
225
225
|
const effectiveCryptoPaymentMethod =
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
const orderStatusPaymentMethod = selectedCryptoPaymentMethod || effectiveCryptoPaymentMethod;
|
|
226
|
+
selectedCryptoPaymentMethod !== CryptoPaymentMethodType.NONE
|
|
227
|
+
? selectedCryptoPaymentMethod
|
|
228
|
+
: cryptoPaymentMethod || cryptoPaymentMethodFromUrl || CryptoPaymentMethodType.NONE;
|
|
230
229
|
|
|
231
230
|
const setB3ModalOpen = useModalStore((state: any) => state.setB3ModalOpen);
|
|
232
231
|
|
|
@@ -575,7 +574,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
575
574
|
if (refundTxs.length > 0) {
|
|
576
575
|
return (
|
|
577
576
|
<>
|
|
578
|
-
<OrderStatus order={order} selectedCryptoPaymentMethod={
|
|
577
|
+
<OrderStatus order={order} selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod} />
|
|
579
578
|
<OrderDetailsCollapsible
|
|
580
579
|
order={order}
|
|
581
580
|
dstToken={dstToken}
|
|
@@ -653,7 +652,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
653
652
|
if (executeTx) {
|
|
654
653
|
return (
|
|
655
654
|
<>
|
|
656
|
-
<OrderStatus order={order} selectedCryptoPaymentMethod={
|
|
655
|
+
<OrderStatus order={order} selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod} />
|
|
657
656
|
<OrderDetailsCollapsible
|
|
658
657
|
order={order}
|
|
659
658
|
dstToken={dstToken}
|
|
@@ -780,7 +779,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
780
779
|
if (relayTxs.length > 0 && relayTxs.every(tx => tx.status === "success")) {
|
|
781
780
|
return (
|
|
782
781
|
<>
|
|
783
|
-
<OrderStatus order={order} selectedCryptoPaymentMethod={
|
|
782
|
+
<OrderStatus order={order} selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod} />
|
|
784
783
|
<OrderDetailsCollapsible
|
|
785
784
|
order={order}
|
|
786
785
|
dstToken={dstToken}
|
|
@@ -909,7 +908,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
909
908
|
if (depositTxs?.length || waitingForDeposit) {
|
|
910
909
|
return (
|
|
911
910
|
<>
|
|
912
|
-
<OrderStatus order={order} selectedCryptoPaymentMethod={
|
|
911
|
+
<OrderStatus order={order} selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod} />
|
|
913
912
|
<OrderDetailsCollapsible
|
|
914
913
|
order={order}
|
|
915
914
|
dstToken={dstToken}
|
|
@@ -1008,7 +1007,7 @@ export const OrderDetails = memo(function OrderDetails({
|
|
|
1008
1007
|
|
|
1009
1008
|
return (
|
|
1010
1009
|
<>
|
|
1011
|
-
<OrderStatus order={order} selectedCryptoPaymentMethod={
|
|
1010
|
+
<OrderStatus order={order} selectedCryptoPaymentMethod={effectiveCryptoPaymentMethod} />
|
|
1012
1011
|
{statusDisplay === "processing" && (
|
|
1013
1012
|
<>
|
|
1014
1013
|
{order.onrampMetadata ? (
|
|
@@ -6,10 +6,11 @@ import invariant from "invariant";
|
|
|
6
6
|
import { useCallback, useState } from "react";
|
|
7
7
|
import { toast } from "sonner";
|
|
8
8
|
import { prepareTransaction, sendTransaction as twSendTransaction } from "thirdweb";
|
|
9
|
+
import { useActiveWallet } from "thirdweb/react";
|
|
10
|
+
import { isAddress } from "viem";
|
|
9
11
|
import { useSwitchChain, useWalletClient } from "wagmi";
|
|
10
12
|
import { useB3 } from "../components";
|
|
11
13
|
import { useAccountWallet } from "./useAccountWallet";
|
|
12
|
-
import { isAddress } from "viem";
|
|
13
14
|
|
|
14
15
|
export interface UnifiedTransactionParams {
|
|
15
16
|
to: string;
|
|
@@ -29,46 +30,53 @@ export function useUnifiedChainSwitchAndExecute() {
|
|
|
29
30
|
const { data: walletClient } = useWalletClient();
|
|
30
31
|
const { switchChainAsync } = useSwitchChain();
|
|
31
32
|
const [isSwitchingOrExecuting, setIsSwitchingOrExecuting] = useState(false);
|
|
33
|
+
const activeWallet = useActiveWallet();
|
|
32
34
|
|
|
33
|
-
const { isActiveSmartWallet, isActiveEOAWallet } = useAccountWallet();
|
|
35
|
+
const { isActiveSmartWallet, isActiveEOAWallet, connectedEOAWallet } = useAccountWallet();
|
|
34
36
|
const { account: aaAccount } = useB3();
|
|
35
37
|
|
|
36
38
|
// Handle EOA wallet chain switch and execute transaction
|
|
37
39
|
const handleEOASwitchChainAndSendTransaction = useCallback(
|
|
38
40
|
async (targetChainId: number, params: UnifiedTransactionParams): Promise<string | undefined> => {
|
|
39
|
-
if (!
|
|
41
|
+
if (!connectedEOAWallet) {
|
|
40
42
|
toast.error("Please connect your wallet");
|
|
41
43
|
return;
|
|
42
44
|
}
|
|
43
45
|
|
|
44
|
-
|
|
45
|
-
const
|
|
46
|
+
// Get target chain configuration once
|
|
47
|
+
const targetChain = supportedChains.find(chain => chain.id === targetChainId);
|
|
48
|
+
if (!targetChain) {
|
|
49
|
+
toast.error(`Chain ${targetChainId} is not supported`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const currentChainId = activeWallet?.getChain()?.id;
|
|
54
|
+
const onCorrectChain = currentChainId === targetChainId;
|
|
46
55
|
|
|
47
56
|
// Helper function to execute the transaction
|
|
48
57
|
const executeTransaction = async (): Promise<string> => {
|
|
49
|
-
const signer =
|
|
58
|
+
const signer = activeWallet?.getAccount();
|
|
50
59
|
if (!signer) {
|
|
51
60
|
throw new Error("No account connected");
|
|
52
61
|
}
|
|
53
62
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
56
|
-
if (
|
|
57
|
-
|
|
63
|
+
// Coinbase Smart Wallet specific chain switching (different behavior from other wallets)
|
|
64
|
+
const walletChain = connectedEOAWallet.getChain();
|
|
65
|
+
if (walletChain?.id !== targetChainId) {
|
|
66
|
+
activeWallet?.switchChain(getThirdwebChain(targetChainId));
|
|
58
67
|
}
|
|
59
68
|
|
|
60
69
|
invariant(isAddress(params.to), "params.to is not a valid address");
|
|
61
70
|
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
chain: targetChain,
|
|
71
|
+
const result = await signer.sendTransaction({
|
|
72
|
+
chainId: targetChainId,
|
|
65
73
|
to: params.to,
|
|
66
74
|
data: params.data as `0x${string}`,
|
|
67
75
|
value: params.value,
|
|
68
76
|
});
|
|
69
77
|
|
|
70
|
-
toast.success(`Transaction sent: ${
|
|
71
|
-
return
|
|
78
|
+
toast.success(`Transaction sent: ${result.transactionHash.slice(0, 10)}...`);
|
|
79
|
+
return result.transactionHash;
|
|
72
80
|
};
|
|
73
81
|
|
|
74
82
|
try {
|
|
@@ -80,12 +88,6 @@ export function useUnifiedChainSwitchAndExecute() {
|
|
|
80
88
|
|
|
81
89
|
const switchingToastId = toast.info(`Switching to ${getChainName(targetChainId)}…`);
|
|
82
90
|
|
|
83
|
-
const targetChain = supportedChains.find(chain => chain.id === targetChainId);
|
|
84
|
-
if (!targetChain) {
|
|
85
|
-
toast.error(`Chain ${targetChainId} is not supported`);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
91
|
const blockExplorerUrl = targetChain.blockExplorers?.default.url;
|
|
90
92
|
invariant(blockExplorerUrl, "Block explorer URL is required");
|
|
91
93
|
const nativeCurrency = getNativeToken(targetChainId);
|