@b3dotfun/sdk 0.1.66-alpha.2 → 0.1.66-alpha.4
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/checkout/CheckoutPaymentPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/checkout/CoinbaseCheckoutPanel.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/checkout/CryptoCheckoutPanel.js +1 -1
- package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/checkout/FiatCheckoutPanel.js +3 -19
- package/dist/cjs/anyspend/react/components/checkout/QRCheckoutPanel.d.ts +1 -1
- package/dist/cjs/anyspend/react/components/checkout/QRCheckoutPanel.js +11 -2
- package/dist/cjs/anyspend/react/hooks/useCreateDepositFirstOrder.d.ts +1 -0
- package/dist/cjs/anyspend/react/hooks/useCreateDepositFirstOrder.js +1 -0
- package/dist/cjs/global-account/react/components/ui/dialog.js +1 -1
- package/dist/esm/anyspend/react/components/checkout/CheckoutPaymentPanel.js +1 -1
- package/dist/esm/anyspend/react/components/checkout/CoinbaseCheckoutPanel.d.ts +1 -0
- package/dist/esm/anyspend/react/components/checkout/CryptoCheckoutPanel.js +1 -1
- package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +2 -1
- package/dist/esm/anyspend/react/components/checkout/FiatCheckoutPanel.js +3 -19
- package/dist/esm/anyspend/react/components/checkout/QRCheckoutPanel.d.ts +1 -1
- package/dist/esm/anyspend/react/components/checkout/QRCheckoutPanel.js +11 -2
- package/dist/esm/anyspend/react/hooks/useCreateDepositFirstOrder.d.ts +1 -0
- package/dist/esm/anyspend/react/hooks/useCreateDepositFirstOrder.js +1 -0
- package/dist/esm/global-account/react/components/ui/dialog.js +1 -1
- package/dist/types/anyspend/react/components/checkout/CoinbaseCheckoutPanel.d.ts +1 -0
- package/dist/types/anyspend/react/components/checkout/FiatCheckoutPanel.d.ts +2 -1
- package/dist/types/anyspend/react/components/checkout/QRCheckoutPanel.d.ts +1 -1
- package/dist/types/anyspend/react/hooks/useCreateDepositFirstOrder.d.ts +1 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/checkout/CheckoutPaymentPanel.tsx +2 -0
- package/src/anyspend/react/components/checkout/CoinbaseCheckoutPanel.tsx +1 -0
- package/src/anyspend/react/components/checkout/CryptoCheckoutPanel.tsx +1 -1
- package/src/anyspend/react/components/checkout/FiatCheckoutPanel.tsx +4 -49
- package/src/anyspend/react/components/checkout/QRCheckoutPanel.tsx +11 -2
- package/src/anyspend/react/hooks/useCreateDepositFirstOrder.ts +2 -0
- package/src/global-account/react/components/ui/dialog.tsx +1 -1
|
@@ -41,5 +41,5 @@ function CheckoutPaymentPanel({ recipientAddress, destinationTokenAddress, desti
|
|
|
41
41
|
}
|
|
42
42
|
const accordionButtonClass = (active) => (0, cn_1.cn)("anyspend-payment-method-btn flex w-full items-center gap-3 px-4 py-4 text-left transition-colors", active ? "bg-white dark:bg-gray-900" : "bg-white hover:bg-gray-50 dark:bg-gray-900 dark:hover:bg-gray-800", classes?.paymentMethodButton);
|
|
43
43
|
const expandedPanelClass = (0, cn_1.cn)("anyspend-payment-method-panel border-t border-gray-100 bg-white px-4 py-4 dark:border-gray-800 dark:bg-gray-900");
|
|
44
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("anyspend-payment-panel flex flex-col gap-5", classes?.paymentPanel), children: [(0, jsx_runtime_1.jsx)("h2", { className: (0, cn_1.cn)("anyspend-payment-title text-lg font-semibold text-gray-900 dark:text-gray-100", classes?.paymentTitle), children: "Payment" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("anyspend-payment-methods divide-y divide-gray-200 overflow-hidden rounded-xl border border-gray-200 dark:divide-gray-700 dark:border-gray-700", classes?.paymentMethodSelector), children: [(0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-crypto", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("crypto"), className: accordionButtonClass(paymentMethod === "crypto"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "crypto", themeColor: themeColor }), (0, jsx_runtime_1.jsx)(lucide_react_1.Wallet, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Crypto wallet" })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "crypto" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(CryptoCheckoutPanel_1.CryptoCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, buttonText: buttonText, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "crypto-panel")) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-qr", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("qr"), className: accordionButtonClass(paymentMethod === "qr"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "qr", themeColor: themeColor }), (0, jsx_runtime_1.jsx)(lucide_react_1.QrCode, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "QR code" })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "qr" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(QRCheckoutPanel_1.QRCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "qr-panel")) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-card", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("card"), className: accordionButtonClass(paymentMethod === "card"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "card", themeColor: themeColor }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Credit or debit card" }), (0, jsx_runtime_1.jsxs)("div", { className: "ml-auto flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(VisaLogo, {}), (0, jsx_runtime_1.jsx)(MastercardLogo, {}), (0, jsx_runtime_1.jsx)(AmexLogo, {})] })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "card" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(FiatCheckoutPanel_1.FiatCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, classes: classes }) }) }, "card-panel")) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-coinbase", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("coinbase"), className: accordionButtonClass(paymentMethod === "coinbase"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "coinbase", themeColor: themeColor }), (0, jsx_runtime_1.jsx)(CoinbaseLogo, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Coinbase Pay" })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "coinbase" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(CoinbaseCheckoutPanel_1.CoinbaseCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, classes: classes }) }) }, "coinbase-panel")) })] })] })] }));
|
|
44
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("anyspend-payment-panel flex flex-col gap-5", classes?.paymentPanel), children: [(0, jsx_runtime_1.jsx)("h2", { className: (0, cn_1.cn)("anyspend-payment-title text-lg font-semibold text-gray-900 dark:text-gray-100", classes?.paymentTitle), children: "Payment" }), (0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("anyspend-payment-methods divide-y divide-gray-200 overflow-hidden rounded-xl border border-gray-200 dark:divide-gray-700 dark:border-gray-700", classes?.paymentMethodSelector), children: [(0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-crypto", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("crypto"), className: accordionButtonClass(paymentMethod === "crypto"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "crypto", themeColor: themeColor }), (0, jsx_runtime_1.jsx)(lucide_react_1.Wallet, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Crypto wallet" })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "crypto" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(CryptoCheckoutPanel_1.CryptoCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, buttonText: buttonText, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "crypto-panel")) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-qr", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("qr"), className: accordionButtonClass(paymentMethod === "qr"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "qr", themeColor: themeColor }), (0, jsx_runtime_1.jsx)(lucide_react_1.QrCode, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "QR code" })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "qr" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(QRCheckoutPanel_1.QRCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "qr-panel")) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-card", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("card"), className: accordionButtonClass(paymentMethod === "card"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "card", themeColor: themeColor }), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Credit or debit card" }), (0, jsx_runtime_1.jsxs)("div", { className: "ml-auto flex items-center gap-1", children: [(0, jsx_runtime_1.jsx)(VisaLogo, {}), (0, jsx_runtime_1.jsx)(MastercardLogo, {}), (0, jsx_runtime_1.jsx)(AmexLogo, {})] })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "card" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(FiatCheckoutPanel_1.FiatCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "card-panel")) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "anyspend-method-coinbase", children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => setPaymentMethod("coinbase"), className: accordionButtonClass(paymentMethod === "coinbase"), children: [(0, jsx_runtime_1.jsx)(RadioCircle, { selected: paymentMethod === "coinbase", themeColor: themeColor }), (0, jsx_runtime_1.jsx)(CoinbaseLogo, {}), (0, jsx_runtime_1.jsx)("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Coinbase Pay" })] }), (0, jsx_runtime_1.jsx)(react_1.AnimatePresence, { initial: false, children: paymentMethod === "coinbase" && ((0, jsx_runtime_1.jsx)(react_1.motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: (0, jsx_runtime_1.jsx)("div", { className: expandedPanelClass, children: (0, jsx_runtime_1.jsx)(CoinbaseCheckoutPanel_1.CoinbaseCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "coinbase-panel")) })] })] })] }));
|
|
45
45
|
}
|
|
@@ -10,6 +10,7 @@ interface CoinbaseCheckoutPanelProps {
|
|
|
10
10
|
orderId?: string;
|
|
11
11
|
}) => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
|
+
callbackMetadata?: Record<string, unknown>;
|
|
13
14
|
classes?: AnySpendCheckoutClasses;
|
|
14
15
|
}
|
|
15
16
|
export declare function CoinbaseCheckoutPanel({ destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, }: CoinbaseCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -170,7 +170,7 @@ function CryptoCheckoutPanel({ recipientAddress, destinationTokenAddress, destin
|
|
|
170
170
|
},
|
|
171
171
|
});
|
|
172
172
|
const isWaitingForExecution = !!orderId && oat?.data?.order.status !== "executed";
|
|
173
|
-
const handlePay = (0, react_5.useCallback)(() => {
|
|
173
|
+
const handlePay = (0, react_5.useCallback)(async () => {
|
|
174
174
|
if (!selectedSrcToken || !walletAddress)
|
|
175
175
|
return;
|
|
176
176
|
depositSentRef.current = false;
|
|
@@ -10,7 +10,8 @@ interface FiatCheckoutPanelProps {
|
|
|
10
10
|
orderId?: string;
|
|
11
11
|
}) => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
|
+
callbackMetadata?: Record<string, unknown>;
|
|
13
14
|
classes?: AnySpendCheckoutClasses;
|
|
14
15
|
}
|
|
15
|
-
export declare function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, classes, }: FiatCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }: FiatCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
16
17
|
export {};
|
|
@@ -4,7 +4,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
4
4
|
exports.FiatCheckoutPanel = FiatCheckoutPanel;
|
|
5
5
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
6
|
const react_1 = require("../../../../anyspend/react");
|
|
7
|
-
const constants_1 = require("../../../../anyspend/constants");
|
|
8
7
|
const cn_1 = require("../../../../shared/utils/cn");
|
|
9
8
|
const number_1 = require("../../../../shared/utils/number");
|
|
10
9
|
const payment_utils_1 = require("../../../../shared/utils/payment.utils");
|
|
@@ -13,7 +12,7 @@ const react_stripe_js_1 = require("@stripe/react-stripe-js");
|
|
|
13
12
|
const lucide_react_1 = require("lucide-react");
|
|
14
13
|
const react_3 = require("motion/react");
|
|
15
14
|
const react_4 = require("react");
|
|
16
|
-
function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, classes, }) {
|
|
15
|
+
function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }) {
|
|
17
16
|
const { data: tokenData } = (0, react_2.useTokenData)(destinationTokenChainId, destinationTokenAddress);
|
|
18
17
|
const { theme, stripePublishableKey } = (0, react_2.useB3Config)();
|
|
19
18
|
const formattedAmount = (0, react_4.useMemo)(() => {
|
|
@@ -21,12 +20,6 @@ function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinat
|
|
|
21
20
|
return (0, number_1.formatTokenAmount)(BigInt(totalAmount), decimals);
|
|
22
21
|
}, [totalAmount, tokenData]);
|
|
23
22
|
const { geoData, stripeOnrampSupport, stripeWeb2Support, isLoading: isLoadingGeo, } = (0, react_1.useGeoOnrampOptions)(formattedAmount);
|
|
24
|
-
// Detect if destination token is the same as the onramp source (USDC on Base)
|
|
25
|
-
// In this case, onramp order creation would fail with "Cannot swap same token on same chain"
|
|
26
|
-
const isSameAsOnrampSource = (0, react_4.useMemo)(() => {
|
|
27
|
-
return (destinationTokenChainId === constants_1.USDC_BASE.chainId &&
|
|
28
|
-
destinationTokenAddress.toLowerCase() === constants_1.USDC_BASE.address.toLowerCase());
|
|
29
|
-
}, [destinationTokenAddress, destinationTokenChainId]);
|
|
30
23
|
// Order state
|
|
31
24
|
const [orderId, setOrderId] = (0, react_4.useState)(null);
|
|
32
25
|
const [stripePaymentIntentId, setStripePaymentIntentId] = (0, react_4.useState)(null);
|
|
@@ -50,11 +43,9 @@ function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinat
|
|
|
50
43
|
},
|
|
51
44
|
});
|
|
52
45
|
// Auto-create onramp order when Stripe Web2 is supported and all data is ready
|
|
53
|
-
// Skip auto-creation when destination is same as source (USDC on Base)
|
|
54
46
|
(0, react_4.useEffect)(() => {
|
|
55
47
|
if (!isLoadingGeo &&
|
|
56
48
|
stripeWeb2Support?.isSupport &&
|
|
57
|
-
!isSameAsOnrampSource &&
|
|
58
49
|
!orderCreatedRef.current &&
|
|
59
50
|
!orderId &&
|
|
60
51
|
!isCreatingOrder &&
|
|
@@ -85,12 +76,12 @@ function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinat
|
|
|
85
76
|
redirectUrl: window.location.origin,
|
|
86
77
|
},
|
|
87
78
|
expectedDstAmount: totalAmount,
|
|
79
|
+
callbackMetadata,
|
|
88
80
|
});
|
|
89
81
|
}
|
|
90
82
|
}, [
|
|
91
83
|
isLoadingGeo,
|
|
92
84
|
stripeWeb2Support,
|
|
93
|
-
isSameAsOnrampSource,
|
|
94
85
|
orderId,
|
|
95
86
|
isCreatingOrder,
|
|
96
87
|
orderError,
|
|
@@ -101,6 +92,7 @@ function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinat
|
|
|
101
92
|
formattedAmount,
|
|
102
93
|
totalAmount,
|
|
103
94
|
geoData,
|
|
95
|
+
callbackMetadata,
|
|
104
96
|
createOrder,
|
|
105
97
|
]);
|
|
106
98
|
// Loading geo/stripe support check
|
|
@@ -120,14 +112,6 @@ function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinat
|
|
|
120
112
|
orderCreatedRef.current = false;
|
|
121
113
|
}, className: "anyspend-fiat-retry text-sm font-medium text-blue-600 hover:text-blue-700 dark:text-blue-400", children: "Try again" })] }));
|
|
122
114
|
}
|
|
123
|
-
// Same-token fallback: USDC on Base uses Stripe redirect instead of embedded
|
|
124
|
-
if (isSameAsOnrampSource && hasStripeRedirect) {
|
|
125
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, cn_1.cn)("anyspend-fiat-redirect flex flex-col gap-3 py-2", classes?.fiatPanel), children: [(0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: "You'll be redirected to Stripe to complete your payment securely." }), (0, jsx_runtime_1.jsxs)("button", { className: (0, cn_1.cn)("anyspend-fiat-redirect-btn flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3.5 text-sm font-semibold text-white transition-all active:scale-[0.98]", "bg-blue-600 hover:bg-blue-700"), style: themeColor ? { backgroundColor: themeColor } : undefined, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Lock, { className: "h-3.5 w-3.5" }), "Pay with Card"] }), (0, jsx_runtime_1.jsxs)("p", { className: "anyspend-fiat-secured flex items-center justify-center gap-1 text-xs text-gray-400", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Lock, { className: "h-3 w-3" }), "Secured by Stripe"] })] }));
|
|
126
|
-
}
|
|
127
|
-
// Same-token without redirect support
|
|
128
|
-
if (isSameAsOnrampSource) {
|
|
129
|
-
return ((0, jsx_runtime_1.jsx)("div", { className: (0, cn_1.cn)("anyspend-fiat-unavailable py-4 text-center", classes?.fiatPanel), children: (0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Card payments are not available for this token configuration." }) }));
|
|
130
|
-
}
|
|
131
115
|
// Creating order / waiting for PaymentIntent
|
|
132
116
|
if (hasStripeWeb2 && (isCreatingOrder || !stripePaymentIntentId)) {
|
|
133
117
|
return ((0, jsx_runtime_1.jsxs)(react_3.motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.2, ease: "easeOut" }, className: (0, cn_1.cn)("anyspend-fiat-initializing flex flex-col items-center gap-3 py-6", classes?.fiatPanel), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Loader2, { className: "h-5 w-5 animate-spin text-gray-400" }), (0, jsx_runtime_1.jsx)(react_2.TextShimmer, { duration: 1.5, className: "text-sm", children: "Initializing secure payment..." })] }));
|
|
@@ -13,5 +13,5 @@ interface QRCheckoutPanelProps {
|
|
|
13
13
|
callbackMetadata?: Record<string, unknown>;
|
|
14
14
|
classes?: AnySpendCheckoutClasses;
|
|
15
15
|
}
|
|
16
|
-
export declare function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata
|
|
16
|
+
export declare function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }: QRCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export {};
|
|
@@ -29,7 +29,7 @@ const DEFAULT_ETH_ON_BASE = {
|
|
|
29
29
|
decimals: 18,
|
|
30
30
|
metadata: { logoURI: "https://assets.relay.link/icons/1/light.png" },
|
|
31
31
|
};
|
|
32
|
-
function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata
|
|
32
|
+
function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }) {
|
|
33
33
|
const [selectedSrcChainId, setSelectedSrcChainId] = (0, react_2.useState)(8453); // Base
|
|
34
34
|
const [selectedSrcToken, setSelectedSrcToken] = (0, react_2.useState)(DEFAULT_ETH_ON_BASE);
|
|
35
35
|
const [showTokenSelector, setShowTokenSelector] = (0, react_2.useState)(false);
|
|
@@ -100,8 +100,17 @@ function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinatio
|
|
|
100
100
|
dstChain: destinationTokenChainId,
|
|
101
101
|
srcToken: selectedSrcToken,
|
|
102
102
|
dstToken,
|
|
103
|
+
callbackMetadata,
|
|
103
104
|
});
|
|
104
|
-
}, [
|
|
105
|
+
}, [
|
|
106
|
+
recipientAddress,
|
|
107
|
+
selectedSrcChainId,
|
|
108
|
+
destinationTokenChainId,
|
|
109
|
+
selectedSrcToken,
|
|
110
|
+
dstToken,
|
|
111
|
+
callbackMetadata,
|
|
112
|
+
createOrder,
|
|
113
|
+
]);
|
|
105
114
|
// Poll order status
|
|
106
115
|
const { orderAndTransactions: oat } = (0, useAnyspendOrderAndTransactions_1.useAnyspendOrderAndTransactions)(orderId);
|
|
107
116
|
// Call onSuccess when order is executed
|
|
@@ -9,6 +9,7 @@ export type CreateDepositFirstOrderParams = {
|
|
|
9
9
|
creatorAddress?: string;
|
|
10
10
|
/** Optional contract config for custom execution after deposit */
|
|
11
11
|
contractConfig?: DepositContractConfig;
|
|
12
|
+
callbackMetadata?: Record<string, unknown>;
|
|
12
13
|
};
|
|
13
14
|
export type UseCreateDepositFirstOrderProps = {
|
|
14
15
|
onSuccess?: (data: any) => void;
|
|
@@ -63,6 +63,7 @@ function useCreateDepositFirstOrder({ onSuccess, onError } = {}) {
|
|
|
63
63
|
creatorAddress: creatorAddress ? (0, utils_1.normalizeAddress)(creatorAddress) : undefined,
|
|
64
64
|
partnerId,
|
|
65
65
|
visitorData,
|
|
66
|
+
callbackMetadata: params.callbackMetadata,
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
catch (error) {
|
|
@@ -53,7 +53,7 @@ exports.DialogOverlay = DialogOverlay;
|
|
|
53
53
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
54
54
|
const DialogContent = React.forwardRef(({ className, children, hideCloseButton = true, closeBtnClassName, ...props }, ref) => {
|
|
55
55
|
const container = typeof window !== "undefined" ? document.getElementById("b3-root") : null;
|
|
56
|
-
return ((0, jsx_runtime_1.jsxs)(DialogPortal, { container: container, children: [(0, jsx_runtime_1.jsx)(DialogOverlay, {}), (0, jsx_runtime_1.jsxs)(DialogPrimitive.Content, { ref: ref, className: (0, utils_1.cn)("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border shadow-lg !outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-500", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", "[perspective:1200px] [transform-style:preserve-3d] sm:rounded-xl", "transition-all ease-out", className), ...props, children: [(0, jsx_runtime_1.jsxs)("div", { className: "modal-inner-content mb-[23px] flex flex-1 flex-col overflow-hidden rounded-xl border border-[#D1D1D6] bg-white shadow-[0_20px_24px_-4px_rgba(10,13,18,0.08),0_8px_8px_-4px_rgba(10,13,18,0.03),0_3px_3px_-1.5px_rgba(10,13,18,0.04)]", children: [children, !hideCloseButton && ((0, jsx_runtime_1.jsxs)(DialogPrimitive.Close, { className: (0, utils_1.cn)("modal-close-button data-[state=open]:bg-b3-react-background data-[state=open]:text-b3-react-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:text-gray-400", closeBtnClassName), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-5 w-5" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "b3-modal-ga-branding absolute bottom-[10px] left-0 right-0 flex items-center justify-center gap-1.5 pt-[10px]", children: [(0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4 w-4" }), (0, jsx_runtime_1.jsx)("span", { className: "font-neue-montreal-semibold text-xs uppercase leading-none tracking-[0.72px] text-[#0B57C2]", children: "Global Account" })] })] })] }));
|
|
56
|
+
return ((0, jsx_runtime_1.jsxs)(DialogPortal, { container: container, children: [(0, jsx_runtime_1.jsx)(DialogOverlay, {}), (0, jsx_runtime_1.jsxs)(DialogPrimitive.Content, { ref: ref, className: (0, utils_1.cn)("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border shadow-lg !outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-500", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", "[perspective:1200px] [transform-style:preserve-3d] sm:rounded-xl", "transition-all ease-out", className), ...props, children: [(0, jsx_runtime_1.jsxs)("div", { className: "modal-inner-content mb-[23px] flex flex-1 flex-col overflow-hidden rounded-xl border border-[#D1D1D6] bg-white shadow-[0_20px_24px_-4px_rgba(10,13,18,0.08),0_8px_8px_-4px_rgba(10,13,18,0.03),0_3px_3px_-1.5px_rgba(10,13,18,0.04)] dark:border-gray-700 dark:bg-gray-900", children: [children, !hideCloseButton && ((0, jsx_runtime_1.jsxs)(DialogPrimitive.Close, { className: (0, utils_1.cn)("modal-close-button data-[state=open]:bg-b3-react-background data-[state=open]:text-b3-react-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:text-gray-400", closeBtnClassName), children: [(0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-5 w-5" }), (0, jsx_runtime_1.jsx)("span", { className: "sr-only", children: "Close" })] }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "b3-modal-ga-branding absolute bottom-[10px] left-0 right-0 flex items-center justify-center gap-1.5 pt-[10px]", children: [(0, jsx_runtime_1.jsx)("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4 w-4" }), (0, jsx_runtime_1.jsx)("span", { className: "font-neue-montreal-semibold text-xs uppercase leading-none tracking-[0.72px] text-[#0B57C2]", children: "Global Account" })] })] })] }));
|
|
57
57
|
});
|
|
58
58
|
exports.DialogContent = DialogContent;
|
|
59
59
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
@@ -38,5 +38,5 @@ export function CheckoutPaymentPanel({ recipientAddress, destinationTokenAddress
|
|
|
38
38
|
}
|
|
39
39
|
const accordionButtonClass = (active) => cn("anyspend-payment-method-btn flex w-full items-center gap-3 px-4 py-4 text-left transition-colors", active ? "bg-white dark:bg-gray-900" : "bg-white hover:bg-gray-50 dark:bg-gray-900 dark:hover:bg-gray-800", classes?.paymentMethodButton);
|
|
40
40
|
const expandedPanelClass = cn("anyspend-payment-method-panel border-t border-gray-100 bg-white px-4 py-4 dark:border-gray-800 dark:bg-gray-900");
|
|
41
|
-
return (_jsxs("div", { className: cn("anyspend-payment-panel flex flex-col gap-5", classes?.paymentPanel), children: [_jsx("h2", { className: cn("anyspend-payment-title text-lg font-semibold text-gray-900 dark:text-gray-100", classes?.paymentTitle), children: "Payment" }), _jsxs("div", { className: cn("anyspend-payment-methods divide-y divide-gray-200 overflow-hidden rounded-xl border border-gray-200 dark:divide-gray-700 dark:border-gray-700", classes?.paymentMethodSelector), children: [_jsxs("div", { className: "anyspend-method-crypto", children: [_jsxs("button", { onClick: () => setPaymentMethod("crypto"), className: accordionButtonClass(paymentMethod === "crypto"), children: [_jsx(RadioCircle, { selected: paymentMethod === "crypto", themeColor: themeColor }), _jsx(Wallet, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Crypto wallet" })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "crypto" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(CryptoCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, buttonText: buttonText, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "crypto-panel")) })] }), _jsxs("div", { className: "anyspend-method-qr", children: [_jsxs("button", { onClick: () => setPaymentMethod("qr"), className: accordionButtonClass(paymentMethod === "qr"), children: [_jsx(RadioCircle, { selected: paymentMethod === "qr", themeColor: themeColor }), _jsx(QrCode, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "QR code" })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "qr" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(QRCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "qr-panel")) })] }), _jsxs("div", { className: "anyspend-method-card", children: [_jsxs("button", { onClick: () => setPaymentMethod("card"), className: accordionButtonClass(paymentMethod === "card"), children: [_jsx(RadioCircle, { selected: paymentMethod === "card", themeColor: themeColor }), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Credit or debit card" }), _jsxs("div", { className: "ml-auto flex items-center gap-1", children: [_jsx(VisaLogo, {}), _jsx(MastercardLogo, {}), _jsx(AmexLogo, {})] })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "card" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(FiatCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, classes: classes }) }) }, "card-panel")) })] }), _jsxs("div", { className: "anyspend-method-coinbase", children: [_jsxs("button", { onClick: () => setPaymentMethod("coinbase"), className: accordionButtonClass(paymentMethod === "coinbase"), children: [_jsx(RadioCircle, { selected: paymentMethod === "coinbase", themeColor: themeColor }), _jsx(CoinbaseLogo, {}), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Coinbase Pay" })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "coinbase" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(CoinbaseCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, classes: classes }) }) }, "coinbase-panel")) })] })] })] }));
|
|
41
|
+
return (_jsxs("div", { className: cn("anyspend-payment-panel flex flex-col gap-5", classes?.paymentPanel), children: [_jsx("h2", { className: cn("anyspend-payment-title text-lg font-semibold text-gray-900 dark:text-gray-100", classes?.paymentTitle), children: "Payment" }), _jsxs("div", { className: cn("anyspend-payment-methods divide-y divide-gray-200 overflow-hidden rounded-xl border border-gray-200 dark:divide-gray-700 dark:border-gray-700", classes?.paymentMethodSelector), children: [_jsxs("div", { className: "anyspend-method-crypto", children: [_jsxs("button", { onClick: () => setPaymentMethod("crypto"), className: accordionButtonClass(paymentMethod === "crypto"), children: [_jsx(RadioCircle, { selected: paymentMethod === "crypto", themeColor: themeColor }), _jsx(Wallet, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Crypto wallet" })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "crypto" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(CryptoCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, buttonText: buttonText, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "crypto-panel")) })] }), _jsxs("div", { className: "anyspend-method-qr", children: [_jsxs("button", { onClick: () => setPaymentMethod("qr"), className: accordionButtonClass(paymentMethod === "qr"), children: [_jsx(RadioCircle, { selected: paymentMethod === "qr", themeColor: themeColor }), _jsx(QrCode, { className: "h-5 w-5 text-gray-700 dark:text-gray-300" }), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "QR code" })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "qr" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(QRCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "qr-panel")) })] }), _jsxs("div", { className: "anyspend-method-card", children: [_jsxs("button", { onClick: () => setPaymentMethod("card"), className: accordionButtonClass(paymentMethod === "card"), children: [_jsx(RadioCircle, { selected: paymentMethod === "card", themeColor: themeColor }), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Credit or debit card" }), _jsxs("div", { className: "ml-auto flex items-center gap-1", children: [_jsx(VisaLogo, {}), _jsx(MastercardLogo, {}), _jsx(AmexLogo, {})] })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "card" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(FiatCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "card-panel")) })] }), _jsxs("div", { className: "anyspend-method-coinbase", children: [_jsxs("button", { onClick: () => setPaymentMethod("coinbase"), className: accordionButtonClass(paymentMethod === "coinbase"), children: [_jsx(RadioCircle, { selected: paymentMethod === "coinbase", themeColor: themeColor }), _jsx(CoinbaseLogo, {}), _jsx("span", { className: "text-sm font-medium text-gray-900 dark:text-gray-100", children: "Coinbase Pay" })] }), _jsx(AnimatePresence, { initial: false, children: paymentMethod === "coinbase" && (_jsx(motion.div, { initial: { height: 0, opacity: 0 }, animate: { height: "auto", opacity: 1 }, exit: { height: 0, opacity: 0 }, transition: { duration: 0.2, ease: "easeOut" }, style: { overflow: "hidden" }, children: _jsx("div", { className: expandedPanelClass, children: _jsx(CoinbaseCheckoutPanel, { recipientAddress: recipientAddress, destinationTokenAddress: destinationTokenAddress, destinationTokenChainId: destinationTokenChainId, totalAmount: totalAmount, themeColor: themeColor, onSuccess: handleSuccess, onError: onError, callbackMetadata: callbackMetadata, classes: classes }) }) }, "coinbase-panel")) })] })] })] }));
|
|
42
42
|
}
|
|
@@ -10,6 +10,7 @@ interface CoinbaseCheckoutPanelProps {
|
|
|
10
10
|
orderId?: string;
|
|
11
11
|
}) => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
|
+
callbackMetadata?: Record<string, unknown>;
|
|
13
14
|
classes?: AnySpendCheckoutClasses;
|
|
14
15
|
}
|
|
15
16
|
export declare function CoinbaseCheckoutPanel({ destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, }: CoinbaseCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -166,7 +166,7 @@ export function CryptoCheckoutPanel({ recipientAddress, destinationTokenAddress,
|
|
|
166
166
|
},
|
|
167
167
|
});
|
|
168
168
|
const isWaitingForExecution = !!orderId && oat?.data?.order.status !== "executed";
|
|
169
|
-
const handlePay = useCallback(() => {
|
|
169
|
+
const handlePay = useCallback(async () => {
|
|
170
170
|
if (!selectedSrcToken || !walletAddress)
|
|
171
171
|
return;
|
|
172
172
|
depositSentRef.current = false;
|
|
@@ -10,7 +10,8 @@ interface FiatCheckoutPanelProps {
|
|
|
10
10
|
orderId?: string;
|
|
11
11
|
}) => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
|
+
callbackMetadata?: Record<string, unknown>;
|
|
13
14
|
classes?: AnySpendCheckoutClasses;
|
|
14
15
|
}
|
|
15
|
-
export declare function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, classes, }: FiatCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }: FiatCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
16
17
|
export {};
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { useAnyspendCreateOnrampOrder, useGeoOnrampOptions, useStripeClientSecret } from "../../../../anyspend/react/index.js";
|
|
4
|
-
import { USDC_BASE } from "../../../../anyspend/constants/index.js";
|
|
5
4
|
import { cn } from "../../../../shared/utils/cn.js";
|
|
6
5
|
import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
7
6
|
import { getStripePromise } from "../../../../shared/utils/payment.utils.js";
|
|
@@ -10,7 +9,7 @@ import { AddressElement, Elements, PaymentElement, useElements, useStripe } from
|
|
|
10
9
|
import { Loader2, Lock } from "lucide-react";
|
|
11
10
|
import { AnimatePresence, motion } from "motion/react";
|
|
12
11
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
13
|
-
export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, classes, }) {
|
|
12
|
+
export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }) {
|
|
14
13
|
const { data: tokenData } = useTokenData(destinationTokenChainId, destinationTokenAddress);
|
|
15
14
|
const { theme, stripePublishableKey } = useB3Config();
|
|
16
15
|
const formattedAmount = useMemo(() => {
|
|
@@ -18,12 +17,6 @@ export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, d
|
|
|
18
17
|
return formatTokenAmount(BigInt(totalAmount), decimals);
|
|
19
18
|
}, [totalAmount, tokenData]);
|
|
20
19
|
const { geoData, stripeOnrampSupport, stripeWeb2Support, isLoading: isLoadingGeo, } = useGeoOnrampOptions(formattedAmount);
|
|
21
|
-
// Detect if destination token is the same as the onramp source (USDC on Base)
|
|
22
|
-
// In this case, onramp order creation would fail with "Cannot swap same token on same chain"
|
|
23
|
-
const isSameAsOnrampSource = useMemo(() => {
|
|
24
|
-
return (destinationTokenChainId === USDC_BASE.chainId &&
|
|
25
|
-
destinationTokenAddress.toLowerCase() === USDC_BASE.address.toLowerCase());
|
|
26
|
-
}, [destinationTokenAddress, destinationTokenChainId]);
|
|
27
20
|
// Order state
|
|
28
21
|
const [orderId, setOrderId] = useState(null);
|
|
29
22
|
const [stripePaymentIntentId, setStripePaymentIntentId] = useState(null);
|
|
@@ -47,11 +40,9 @@ export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, d
|
|
|
47
40
|
},
|
|
48
41
|
});
|
|
49
42
|
// Auto-create onramp order when Stripe Web2 is supported and all data is ready
|
|
50
|
-
// Skip auto-creation when destination is same as source (USDC on Base)
|
|
51
43
|
useEffect(() => {
|
|
52
44
|
if (!isLoadingGeo &&
|
|
53
45
|
stripeWeb2Support?.isSupport &&
|
|
54
|
-
!isSameAsOnrampSource &&
|
|
55
46
|
!orderCreatedRef.current &&
|
|
56
47
|
!orderId &&
|
|
57
48
|
!isCreatingOrder &&
|
|
@@ -82,12 +73,12 @@ export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, d
|
|
|
82
73
|
redirectUrl: window.location.origin,
|
|
83
74
|
},
|
|
84
75
|
expectedDstAmount: totalAmount,
|
|
76
|
+
callbackMetadata,
|
|
85
77
|
});
|
|
86
78
|
}
|
|
87
79
|
}, [
|
|
88
80
|
isLoadingGeo,
|
|
89
81
|
stripeWeb2Support,
|
|
90
|
-
isSameAsOnrampSource,
|
|
91
82
|
orderId,
|
|
92
83
|
isCreatingOrder,
|
|
93
84
|
orderError,
|
|
@@ -98,6 +89,7 @@ export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, d
|
|
|
98
89
|
formattedAmount,
|
|
99
90
|
totalAmount,
|
|
100
91
|
geoData,
|
|
92
|
+
callbackMetadata,
|
|
101
93
|
createOrder,
|
|
102
94
|
]);
|
|
103
95
|
// Loading geo/stripe support check
|
|
@@ -117,14 +109,6 @@ export function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, d
|
|
|
117
109
|
orderCreatedRef.current = false;
|
|
118
110
|
}, className: "anyspend-fiat-retry text-sm font-medium text-blue-600 hover:text-blue-700 dark:text-blue-400", children: "Try again" })] }));
|
|
119
111
|
}
|
|
120
|
-
// Same-token fallback: USDC on Base uses Stripe redirect instead of embedded
|
|
121
|
-
if (isSameAsOnrampSource && hasStripeRedirect) {
|
|
122
|
-
return (_jsxs("div", { className: cn("anyspend-fiat-redirect flex flex-col gap-3 py-2", classes?.fiatPanel), children: [_jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: "You'll be redirected to Stripe to complete your payment securely." }), _jsxs("button", { className: cn("anyspend-fiat-redirect-btn flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3.5 text-sm font-semibold text-white transition-all active:scale-[0.98]", "bg-blue-600 hover:bg-blue-700"), style: themeColor ? { backgroundColor: themeColor } : undefined, children: [_jsx(Lock, { className: "h-3.5 w-3.5" }), "Pay with Card"] }), _jsxs("p", { className: "anyspend-fiat-secured flex items-center justify-center gap-1 text-xs text-gray-400", children: [_jsx(Lock, { className: "h-3 w-3" }), "Secured by Stripe"] })] }));
|
|
123
|
-
}
|
|
124
|
-
// Same-token without redirect support
|
|
125
|
-
if (isSameAsOnrampSource) {
|
|
126
|
-
return (_jsx("div", { className: cn("anyspend-fiat-unavailable py-4 text-center", classes?.fiatPanel), children: _jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: "Card payments are not available for this token configuration." }) }));
|
|
127
|
-
}
|
|
128
112
|
// Creating order / waiting for PaymentIntent
|
|
129
113
|
if (hasStripeWeb2 && (isCreatingOrder || !stripePaymentIntentId)) {
|
|
130
114
|
return (_jsxs(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.2, ease: "easeOut" }, className: cn("anyspend-fiat-initializing flex flex-col items-center gap-3 py-6", classes?.fiatPanel), children: [_jsx(Loader2, { className: "h-5 w-5 animate-spin text-gray-400" }), _jsx(TextShimmer, { duration: 1.5, className: "text-sm", children: "Initializing secure payment..." })] }));
|
|
@@ -13,5 +13,5 @@ interface QRCheckoutPanelProps {
|
|
|
13
13
|
callbackMetadata?: Record<string, unknown>;
|
|
14
14
|
classes?: AnySpendCheckoutClasses;
|
|
15
15
|
}
|
|
16
|
-
export declare function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata
|
|
16
|
+
export declare function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }: QRCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export {};
|
|
@@ -26,7 +26,7 @@ const DEFAULT_ETH_ON_BASE = {
|
|
|
26
26
|
decimals: 18,
|
|
27
27
|
metadata: { logoURI: "https://assets.relay.link/icons/1/light.png" },
|
|
28
28
|
};
|
|
29
|
-
export function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata
|
|
29
|
+
export function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }) {
|
|
30
30
|
const [selectedSrcChainId, setSelectedSrcChainId] = useState(8453); // Base
|
|
31
31
|
const [selectedSrcToken, setSelectedSrcToken] = useState(DEFAULT_ETH_ON_BASE);
|
|
32
32
|
const [showTokenSelector, setShowTokenSelector] = useState(false);
|
|
@@ -97,8 +97,17 @@ export function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, des
|
|
|
97
97
|
dstChain: destinationTokenChainId,
|
|
98
98
|
srcToken: selectedSrcToken,
|
|
99
99
|
dstToken,
|
|
100
|
+
callbackMetadata,
|
|
100
101
|
});
|
|
101
|
-
}, [
|
|
102
|
+
}, [
|
|
103
|
+
recipientAddress,
|
|
104
|
+
selectedSrcChainId,
|
|
105
|
+
destinationTokenChainId,
|
|
106
|
+
selectedSrcToken,
|
|
107
|
+
dstToken,
|
|
108
|
+
callbackMetadata,
|
|
109
|
+
createOrder,
|
|
110
|
+
]);
|
|
102
111
|
// Poll order status
|
|
103
112
|
const { orderAndTransactions: oat } = useAnyspendOrderAndTransactions(orderId);
|
|
104
113
|
// Call onSuccess when order is executed
|
|
@@ -9,6 +9,7 @@ export type CreateDepositFirstOrderParams = {
|
|
|
9
9
|
creatorAddress?: string;
|
|
10
10
|
/** Optional contract config for custom execution after deposit */
|
|
11
11
|
contractConfig?: DepositContractConfig;
|
|
12
|
+
callbackMetadata?: Record<string, unknown>;
|
|
12
13
|
};
|
|
13
14
|
export type UseCreateDepositFirstOrderProps = {
|
|
14
15
|
onSuccess?: (data: any) => void;
|
|
@@ -60,6 +60,7 @@ export function useCreateDepositFirstOrder({ onSuccess, onError } = {}) {
|
|
|
60
60
|
creatorAddress: creatorAddress ? normalizeAddress(creatorAddress) : undefined,
|
|
61
61
|
partnerId,
|
|
62
62
|
visitorData,
|
|
63
|
+
callbackMetadata: params.callbackMetadata,
|
|
63
64
|
});
|
|
64
65
|
}
|
|
65
66
|
catch (error) {
|
|
@@ -12,7 +12,7 @@ const DialogOverlay = React.forwardRef(({ className, ...props }, ref) => (_jsx(D
|
|
|
12
12
|
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
|
|
13
13
|
const DialogContent = React.forwardRef(({ className, children, hideCloseButton = true, closeBtnClassName, ...props }, ref) => {
|
|
14
14
|
const container = typeof window !== "undefined" ? document.getElementById("b3-root") : null;
|
|
15
|
-
return (_jsxs(DialogPortal, { container: container, children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border shadow-lg !outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-500", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", "[perspective:1200px] [transform-style:preserve-3d] sm:rounded-xl", "transition-all ease-out", className), ...props, children: [_jsxs("div", { className: "modal-inner-content mb-[23px] flex flex-1 flex-col overflow-hidden rounded-xl border border-[#D1D1D6] bg-white shadow-[0_20px_24px_-4px_rgba(10,13,18,0.08),0_8px_8px_-4px_rgba(10,13,18,0.03),0_3px_3px_-1.5px_rgba(10,13,18,0.04)]", children: [children, !hideCloseButton && (_jsxs(DialogPrimitive.Close, { className: cn("modal-close-button data-[state=open]:bg-b3-react-background data-[state=open]:text-b3-react-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:text-gray-400", closeBtnClassName), children: [_jsx(X, { className: "h-5 w-5" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] }), _jsxs("div", { className: "b3-modal-ga-branding absolute bottom-[10px] left-0 right-0 flex items-center justify-center gap-1.5 pt-[10px]", children: [_jsx("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4 w-4" }), _jsx("span", { className: "font-neue-montreal-semibold text-xs uppercase leading-none tracking-[0.72px] text-[#0B57C2]", children: "Global Account" })] })] })] }));
|
|
15
|
+
return (_jsxs(DialogPortal, { container: container, children: [_jsx(DialogOverlay, {}), _jsxs(DialogPrimitive.Content, { ref: ref, className: cn("fixed left-1/2 top-1/2 z-50 grid w-full max-w-lg -translate-x-1/2 -translate-y-1/2 border shadow-lg !outline-none", "data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 duration-500", "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95", "data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%]", "[perspective:1200px] [transform-style:preserve-3d] sm:rounded-xl", "transition-all ease-out", className), ...props, children: [_jsxs("div", { className: "modal-inner-content mb-[23px] flex flex-1 flex-col overflow-hidden rounded-xl border border-[#D1D1D6] bg-white shadow-[0_20px_24px_-4px_rgba(10,13,18,0.08),0_8px_8px_-4px_rgba(10,13,18,0.03),0_3px_3px_-1.5px_rgba(10,13,18,0.04)] dark:border-gray-700 dark:bg-gray-900", children: [children, !hideCloseButton && (_jsxs(DialogPrimitive.Close, { className: cn("modal-close-button data-[state=open]:bg-b3-react-background data-[state=open]:text-b3-react-muted-foreground absolute right-2 top-2 rounded-sm opacity-70 transition-opacity hover:opacity-100 focus:outline-none disabled:pointer-events-none dark:data-[state=open]:bg-gray-800 dark:data-[state=open]:text-gray-400", closeBtnClassName), children: [_jsx(X, { className: "h-5 w-5" }), _jsx("span", { className: "sr-only", children: "Close" })] }))] }), _jsxs("div", { className: "b3-modal-ga-branding absolute bottom-[10px] left-0 right-0 flex items-center justify-center gap-1.5 pt-[10px]", children: [_jsx("img", { src: "https://cdn.b3.fun/b3_logo.svg", alt: "B3", className: "h-4 w-4" }), _jsx("span", { className: "font-neue-montreal-semibold text-xs uppercase leading-none tracking-[0.72px] text-[#0B57C2]", children: "Global Account" })] })] })] }));
|
|
16
16
|
});
|
|
17
17
|
DialogContent.displayName = DialogPrimitive.Content.displayName;
|
|
18
18
|
const DialogHeader = ({ className, ...props }) => (_jsx("div", { className: cn("flex flex-col space-y-1.5 text-center sm:text-left", className), ...props }));
|
|
@@ -10,6 +10,7 @@ interface CoinbaseCheckoutPanelProps {
|
|
|
10
10
|
orderId?: string;
|
|
11
11
|
}) => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
|
+
callbackMetadata?: Record<string, unknown>;
|
|
13
14
|
classes?: AnySpendCheckoutClasses;
|
|
14
15
|
}
|
|
15
16
|
export declare function CoinbaseCheckoutPanel({ destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, }: CoinbaseCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -10,7 +10,8 @@ interface FiatCheckoutPanelProps {
|
|
|
10
10
|
orderId?: string;
|
|
11
11
|
}) => void;
|
|
12
12
|
onError?: (error: Error) => void;
|
|
13
|
+
callbackMetadata?: Record<string, unknown>;
|
|
13
14
|
classes?: AnySpendCheckoutClasses;
|
|
14
15
|
}
|
|
15
|
-
export declare function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, classes, }: FiatCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
16
|
+
export declare function FiatCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }: FiatCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
16
17
|
export {};
|
|
@@ -13,5 +13,5 @@ interface QRCheckoutPanelProps {
|
|
|
13
13
|
callbackMetadata?: Record<string, unknown>;
|
|
14
14
|
classes?: AnySpendCheckoutClasses;
|
|
15
15
|
}
|
|
16
|
-
export declare function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata
|
|
16
|
+
export declare function QRCheckoutPanel({ recipientAddress, destinationTokenAddress, destinationTokenChainId, totalAmount, themeColor, onSuccess, onError, callbackMetadata, classes, }: QRCheckoutPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
17
17
|
export {};
|
|
@@ -9,6 +9,7 @@ export type CreateDepositFirstOrderParams = {
|
|
|
9
9
|
creatorAddress?: string;
|
|
10
10
|
/** Optional contract config for custom execution after deposit */
|
|
11
11
|
contractConfig?: DepositContractConfig;
|
|
12
|
+
callbackMetadata?: Record<string, unknown>;
|
|
12
13
|
};
|
|
13
14
|
export type UseCreateDepositFirstOrderProps = {
|
|
14
15
|
onSuccess?: (data: any) => void;
|
package/package.json
CHANGED
|
@@ -270,6 +270,7 @@ export function CheckoutPaymentPanel({
|
|
|
270
270
|
themeColor={themeColor}
|
|
271
271
|
onSuccess={handleSuccess}
|
|
272
272
|
onError={onError}
|
|
273
|
+
callbackMetadata={callbackMetadata}
|
|
273
274
|
classes={classes}
|
|
274
275
|
/>
|
|
275
276
|
</div>
|
|
@@ -307,6 +308,7 @@ export function CheckoutPaymentPanel({
|
|
|
307
308
|
themeColor={themeColor}
|
|
308
309
|
onSuccess={handleSuccess}
|
|
309
310
|
onError={onError}
|
|
311
|
+
callbackMetadata={callbackMetadata}
|
|
310
312
|
classes={classes}
|
|
311
313
|
/>
|
|
312
314
|
</div>
|
|
@@ -17,6 +17,7 @@ interface CoinbaseCheckoutPanelProps {
|
|
|
17
17
|
themeColor?: string;
|
|
18
18
|
onSuccess?: (result: { txHash?: string; orderId?: string }) => void;
|
|
19
19
|
onError?: (error: Error) => void;
|
|
20
|
+
callbackMetadata?: Record<string, unknown>;
|
|
20
21
|
classes?: AnySpendCheckoutClasses;
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -228,7 +228,7 @@ export function CryptoCheckoutPanel({
|
|
|
228
228
|
|
|
229
229
|
const isWaitingForExecution = !!orderId && oat?.data?.order.status !== "executed";
|
|
230
230
|
|
|
231
|
-
const handlePay = useCallback(() => {
|
|
231
|
+
const handlePay = useCallback(async () => {
|
|
232
232
|
if (!selectedSrcToken || !walletAddress) return;
|
|
233
233
|
|
|
234
234
|
depositSentRef.current = false;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useAnyspendCreateOnrampOrder, useGeoOnrampOptions, useStripeClientSecret } from "@b3dotfun/sdk/anyspend/react";
|
|
4
|
-
import { USDC_BASE } from "@b3dotfun/sdk/anyspend/constants";
|
|
5
4
|
import { cn } from "@b3dotfun/sdk/shared/utils/cn";
|
|
6
5
|
import { formatTokenAmount } from "@b3dotfun/sdk/shared/utils/number";
|
|
7
6
|
import { getStripePromise } from "@b3dotfun/sdk/shared/utils/payment.utils";
|
|
@@ -21,6 +20,7 @@ interface FiatCheckoutPanelProps {
|
|
|
21
20
|
themeColor?: string;
|
|
22
21
|
onSuccess?: (result: { txHash?: string; orderId?: string }) => void;
|
|
23
22
|
onError?: (error: Error) => void;
|
|
23
|
+
callbackMetadata?: Record<string, unknown>;
|
|
24
24
|
classes?: AnySpendCheckoutClasses;
|
|
25
25
|
}
|
|
26
26
|
|
|
@@ -32,6 +32,7 @@ export function FiatCheckoutPanel({
|
|
|
32
32
|
themeColor,
|
|
33
33
|
onSuccess,
|
|
34
34
|
onError,
|
|
35
|
+
callbackMetadata,
|
|
35
36
|
classes,
|
|
36
37
|
}: FiatCheckoutPanelProps) {
|
|
37
38
|
const { data: tokenData } = useTokenData(destinationTokenChainId, destinationTokenAddress);
|
|
@@ -49,15 +50,6 @@ export function FiatCheckoutPanel({
|
|
|
49
50
|
isLoading: isLoadingGeo,
|
|
50
51
|
} = useGeoOnrampOptions(formattedAmount);
|
|
51
52
|
|
|
52
|
-
// Detect if destination token is the same as the onramp source (USDC on Base)
|
|
53
|
-
// In this case, onramp order creation would fail with "Cannot swap same token on same chain"
|
|
54
|
-
const isSameAsOnrampSource = useMemo(() => {
|
|
55
|
-
return (
|
|
56
|
-
destinationTokenChainId === USDC_BASE.chainId &&
|
|
57
|
-
destinationTokenAddress.toLowerCase() === USDC_BASE.address.toLowerCase()
|
|
58
|
-
);
|
|
59
|
-
}, [destinationTokenAddress, destinationTokenChainId]);
|
|
60
|
-
|
|
61
53
|
// Order state
|
|
62
54
|
const [orderId, setOrderId] = useState<string | null>(null);
|
|
63
55
|
const [stripePaymentIntentId, setStripePaymentIntentId] = useState<string | null>(null);
|
|
@@ -82,12 +74,10 @@ export function FiatCheckoutPanel({
|
|
|
82
74
|
});
|
|
83
75
|
|
|
84
76
|
// Auto-create onramp order when Stripe Web2 is supported and all data is ready
|
|
85
|
-
// Skip auto-creation when destination is same as source (USDC on Base)
|
|
86
77
|
useEffect(() => {
|
|
87
78
|
if (
|
|
88
79
|
!isLoadingGeo &&
|
|
89
80
|
stripeWeb2Support?.isSupport &&
|
|
90
|
-
!isSameAsOnrampSource &&
|
|
91
81
|
!orderCreatedRef.current &&
|
|
92
82
|
!orderId &&
|
|
93
83
|
!isCreatingOrder &&
|
|
@@ -121,12 +111,12 @@ export function FiatCheckoutPanel({
|
|
|
121
111
|
redirectUrl: window.location.origin,
|
|
122
112
|
},
|
|
123
113
|
expectedDstAmount: totalAmount,
|
|
114
|
+
callbackMetadata,
|
|
124
115
|
});
|
|
125
116
|
}
|
|
126
117
|
}, [
|
|
127
118
|
isLoadingGeo,
|
|
128
119
|
stripeWeb2Support,
|
|
129
|
-
isSameAsOnrampSource,
|
|
130
120
|
orderId,
|
|
131
121
|
isCreatingOrder,
|
|
132
122
|
orderError,
|
|
@@ -137,6 +127,7 @@ export function FiatCheckoutPanel({
|
|
|
137
127
|
formattedAmount,
|
|
138
128
|
totalAmount,
|
|
139
129
|
geoData,
|
|
130
|
+
callbackMetadata,
|
|
140
131
|
createOrder,
|
|
141
132
|
]);
|
|
142
133
|
|
|
@@ -199,42 +190,6 @@ export function FiatCheckoutPanel({
|
|
|
199
190
|
);
|
|
200
191
|
}
|
|
201
192
|
|
|
202
|
-
// Same-token fallback: USDC on Base uses Stripe redirect instead of embedded
|
|
203
|
-
if (isSameAsOnrampSource && hasStripeRedirect) {
|
|
204
|
-
return (
|
|
205
|
-
<div className={cn("anyspend-fiat-redirect flex flex-col gap-3 py-2", classes?.fiatPanel)}>
|
|
206
|
-
<p className="text-sm text-gray-600 dark:text-gray-400">
|
|
207
|
-
You'll be redirected to Stripe to complete your payment securely.
|
|
208
|
-
</p>
|
|
209
|
-
<button
|
|
210
|
-
className={cn(
|
|
211
|
-
"anyspend-fiat-redirect-btn flex w-full items-center justify-center gap-2 rounded-xl px-4 py-3.5 text-sm font-semibold text-white transition-all active:scale-[0.98]",
|
|
212
|
-
"bg-blue-600 hover:bg-blue-700",
|
|
213
|
-
)}
|
|
214
|
-
style={themeColor ? { backgroundColor: themeColor } : undefined}
|
|
215
|
-
>
|
|
216
|
-
<Lock className="h-3.5 w-3.5" />
|
|
217
|
-
Pay with Card
|
|
218
|
-
</button>
|
|
219
|
-
<p className="anyspend-fiat-secured flex items-center justify-center gap-1 text-xs text-gray-400">
|
|
220
|
-
<Lock className="h-3 w-3" />
|
|
221
|
-
Secured by Stripe
|
|
222
|
-
</p>
|
|
223
|
-
</div>
|
|
224
|
-
);
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Same-token without redirect support
|
|
228
|
-
if (isSameAsOnrampSource) {
|
|
229
|
-
return (
|
|
230
|
-
<div className={cn("anyspend-fiat-unavailable py-4 text-center", classes?.fiatPanel)}>
|
|
231
|
-
<p className="text-sm text-gray-500 dark:text-gray-400">
|
|
232
|
-
Card payments are not available for this token configuration.
|
|
233
|
-
</p>
|
|
234
|
-
</div>
|
|
235
|
-
);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
193
|
// Creating order / waiting for PaymentIntent
|
|
239
194
|
if (hasStripeWeb2 && (isCreatingOrder || !stripePaymentIntentId)) {
|
|
240
195
|
return (
|
|
@@ -50,7 +50,7 @@ export function QRCheckoutPanel({
|
|
|
50
50
|
themeColor,
|
|
51
51
|
onSuccess,
|
|
52
52
|
onError,
|
|
53
|
-
callbackMetadata
|
|
53
|
+
callbackMetadata,
|
|
54
54
|
classes,
|
|
55
55
|
}: QRCheckoutPanelProps) {
|
|
56
56
|
const [selectedSrcChainId, setSelectedSrcChainId] = useState(8453); // Base
|
|
@@ -135,8 +135,17 @@ export function QRCheckoutPanel({
|
|
|
135
135
|
dstChain: destinationTokenChainId,
|
|
136
136
|
srcToken: selectedSrcToken,
|
|
137
137
|
dstToken,
|
|
138
|
+
callbackMetadata,
|
|
138
139
|
});
|
|
139
|
-
}, [
|
|
140
|
+
}, [
|
|
141
|
+
recipientAddress,
|
|
142
|
+
selectedSrcChainId,
|
|
143
|
+
destinationTokenChainId,
|
|
144
|
+
selectedSrcToken,
|
|
145
|
+
dstToken,
|
|
146
|
+
callbackMetadata,
|
|
147
|
+
createOrder,
|
|
148
|
+
]);
|
|
140
149
|
|
|
141
150
|
// Poll order status
|
|
142
151
|
const { orderAndTransactions: oat } = useAnyspendOrderAndTransactions(orderId);
|
|
@@ -17,6 +17,7 @@ export type CreateDepositFirstOrderParams = {
|
|
|
17
17
|
creatorAddress?: string;
|
|
18
18
|
/** Optional contract config for custom execution after deposit */
|
|
19
19
|
contractConfig?: DepositContractConfig;
|
|
20
|
+
callbackMetadata?: Record<string, unknown>;
|
|
20
21
|
};
|
|
21
22
|
|
|
22
23
|
export type UseCreateDepositFirstOrderProps = {
|
|
@@ -84,6 +85,7 @@ export function useCreateDepositFirstOrder({ onSuccess, onError }: UseCreateDepo
|
|
|
84
85
|
creatorAddress: creatorAddress ? normalizeAddress(creatorAddress) : undefined,
|
|
85
86
|
partnerId,
|
|
86
87
|
visitorData,
|
|
88
|
+
callbackMetadata: params.callbackMetadata,
|
|
87
89
|
});
|
|
88
90
|
} catch (error: any) {
|
|
89
91
|
if (error?.data) {
|
|
@@ -60,7 +60,7 @@ const DialogContent: React.ForwardRefExoticComponent<DialogContentProps & React.
|
|
|
60
60
|
)}
|
|
61
61
|
{...props}
|
|
62
62
|
>
|
|
63
|
-
<div className="modal-inner-content mb-[23px] flex flex-1 flex-col overflow-hidden rounded-xl border border-[#D1D1D6] bg-white shadow-[0_20px_24px_-4px_rgba(10,13,18,0.08),0_8px_8px_-4px_rgba(10,13,18,0.03),0_3px_3px_-1.5px_rgba(10,13,18,0.04)]">
|
|
63
|
+
<div className="modal-inner-content mb-[23px] flex flex-1 flex-col overflow-hidden rounded-xl border border-[#D1D1D6] bg-white shadow-[0_20px_24px_-4px_rgba(10,13,18,0.08),0_8px_8px_-4px_rgba(10,13,18,0.03),0_3px_3px_-1.5px_rgba(10,13,18,0.04)] dark:border-gray-700 dark:bg-gray-900">
|
|
64
64
|
{children}
|
|
65
65
|
{!hideCloseButton && (
|
|
66
66
|
<DialogPrimitive.Close
|