@b3dotfun/sdk 0.0.83-alpha.5 → 0.0.83-alpha.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/anyspend/react/components/AnySpend.js +16 -8
- package/dist/cjs/anyspend/react/components/common/PaymentStripeWeb2.js +4 -6
- package/dist/cjs/anyspend/react/components/common/PaymentVendorUI.js +41 -2
- package/dist/cjs/anyspend/react/components/webview/WebviewOnrampPayment.js +2 -3
- package/dist/cjs/shared/utils/payment.utils.d.ts +1 -0
- package/dist/cjs/shared/utils/payment.utils.js +9 -0
- package/dist/esm/anyspend/react/components/AnySpend.js +17 -9
- package/dist/esm/anyspend/react/components/common/PaymentStripeWeb2.js +2 -4
- package/dist/esm/anyspend/react/components/common/PaymentVendorUI.js +9 -3
- package/dist/esm/anyspend/react/components/webview/WebviewOnrampPayment.js +3 -4
- package/dist/esm/shared/utils/payment.utils.d.ts +1 -0
- package/dist/esm/shared/utils/payment.utils.js +9 -1
- package/dist/types/shared/utils/payment.utils.d.ts +1 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +25 -9
- package/src/anyspend/react/components/common/PaymentStripeWeb2.tsx +3 -5
- package/src/anyspend/react/components/common/PaymentVendorUI.tsx +26 -2
- package/src/anyspend/react/components/webview/WebviewOnrampPayment.tsx +3 -5
- package/src/shared/utils/payment.utils.ts +10 -1
|
@@ -114,14 +114,17 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
114
114
|
// State for destination chain/token selection
|
|
115
115
|
const [selectedDstChainId, setSelectedDstChainId] = (0, react_4.useState)(initialDstChainId);
|
|
116
116
|
const defaultDstToken = isBuyMode
|
|
117
|
-
?
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
117
|
+
? // Special case: Hyperliquid uses zero address for USDC
|
|
118
|
+
destinationTokenChainId === anyspend_1.HYPERLIQUID_CHAIN_ID && (0, anyspend_1.eqci)(destinationTokenAddress, anyspend_1.ZERO_ADDRESS)
|
|
119
|
+
? (0, anyspend_1.getHyperliquidUSDCToken)()
|
|
120
|
+
: {
|
|
121
|
+
symbol: "",
|
|
122
|
+
chainId: destinationTokenChainId,
|
|
123
|
+
address: destinationTokenAddress,
|
|
124
|
+
name: "",
|
|
125
|
+
decimals: 18,
|
|
126
|
+
metadata: {},
|
|
127
|
+
}
|
|
125
128
|
: (0, anyspend_1.getDefaultToken)(selectedDstChainId);
|
|
126
129
|
const dstTokenFromUrl = (0, react_2.useTokenFromUrl)({
|
|
127
130
|
defaultToken: defaultDstToken,
|
|
@@ -159,6 +162,11 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
159
162
|
// Update destination token with metadata
|
|
160
163
|
(0, react_4.useEffect)(() => {
|
|
161
164
|
if (selectedDstToken && dstTokenMetadata && !appliedDstMetadataRef.current) {
|
|
165
|
+
// Skip metadata enhancement for Hyperliquid USDC - we already have correct metadata from getHyperliquidUSDCToken()
|
|
166
|
+
if (selectedDstToken.chainId === anyspend_1.HYPERLIQUID_CHAIN_ID && (0, anyspend_1.eqci)(selectedDstToken.address, anyspend_1.ZERO_ADDRESS)) {
|
|
167
|
+
appliedDstMetadataRef.current = true;
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
162
170
|
// Mark as applied
|
|
163
171
|
appliedDstMetadataRef.current = true;
|
|
164
172
|
const enhancedToken = {
|
|
@@ -5,19 +5,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.default = PaymentStripeWeb2;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
-
const
|
|
8
|
+
const payment_utils_1 = require("../../../../shared/utils/payment.utils");
|
|
9
9
|
const react_1 = require("../../../../anyspend/react");
|
|
10
10
|
const react_2 = require("../../../../global-account/react");
|
|
11
11
|
const number_1 = require("../../../../shared/utils/number");
|
|
12
|
-
const
|
|
12
|
+
const payment_utils_2 = require("../../../../shared/utils/payment.utils");
|
|
13
13
|
const react_stripe_js_1 = require("@stripe/react-stripe-js");
|
|
14
|
-
const stripe_js_1 = require("@stripe/stripe-js");
|
|
15
14
|
const lucide_react_1 = require("lucide-react");
|
|
16
15
|
const react_3 = require("react");
|
|
17
16
|
const AnySpendFingerprintWrapper_1 = require("../AnySpendFingerprintWrapper");
|
|
18
17
|
const HowItWorks_1 = __importDefault(require("./HowItWorks"));
|
|
19
18
|
const PaymentMethodIcons_1 = __importDefault(require("./PaymentMethodIcons"));
|
|
20
|
-
const stripePromise = (0, stripe_js_1.loadStripe)(constants_1.STRIPE_CONFIG.publishableKey);
|
|
21
19
|
function PaymentStripeWeb2({ order, stripePaymentIntentId, onPaymentSuccess }) {
|
|
22
20
|
const { theme } = (0, react_2.useB3)();
|
|
23
21
|
const fingerprintConfig = (0, AnySpendFingerprintWrapper_1.getFingerprintConfig)();
|
|
@@ -28,7 +26,7 @@ function PaymentStripeWeb2({ order, stripePaymentIntentId, onPaymentSuccess }) {
|
|
|
28
26
|
if (stripeClientSecretError) {
|
|
29
27
|
return (0, jsx_runtime_1.jsx)(StripeErrorState, { error: stripeClientSecretError.message });
|
|
30
28
|
}
|
|
31
|
-
return ((0, jsx_runtime_1.jsx)(AnySpendFingerprintWrapper_1.AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: (0, jsx_runtime_1.jsx)(react_stripe_js_1.Elements, { stripe:
|
|
29
|
+
return ((0, jsx_runtime_1.jsx)(AnySpendFingerprintWrapper_1.AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: (0, jsx_runtime_1.jsx)(react_stripe_js_1.Elements, { stripe: (0, payment_utils_1.getStripePromise)(), options: {
|
|
32
30
|
clientSecret: clientSecret || undefined,
|
|
33
31
|
appearance: { theme: theme === "light" ? "stripe" : "night" },
|
|
34
32
|
}, children: (0, jsx_runtime_1.jsx)(StripePaymentForm, { order: order, clientSecret: clientSecret, onPaymentSuccess: onPaymentSuccess }) }) }));
|
|
@@ -61,7 +59,7 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
|
|
|
61
59
|
try {
|
|
62
60
|
const paymentIntent = await stripe.retrievePaymentIntent(clientSecret);
|
|
63
61
|
const amount = paymentIntent.paymentIntent?.amount
|
|
64
|
-
? (0,
|
|
62
|
+
? (0, payment_utils_2.formatStripeAmount)(paymentIntent.paymentIntent.amount)
|
|
65
63
|
: null;
|
|
66
64
|
setAmount(amount);
|
|
67
65
|
}
|
|
@@ -1,12 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
2
35
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
36
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
37
|
};
|
|
5
38
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
39
|
exports.default = PaymentVendorUI;
|
|
7
40
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
41
|
+
const react_1 = require("react");
|
|
8
42
|
const PaymentOneClick_1 = __importDefault(require("./PaymentOneClick"));
|
|
9
|
-
|
|
43
|
+
// Lazy load Stripe component to prevent loadStripe() from running at module level
|
|
44
|
+
// This prevents EIP-6963 wallet detection events when Stripe is not used
|
|
45
|
+
const PaymentStripeWeb2 = (0, react_1.lazy)(() => Promise.resolve().then(() => __importStar(require("./PaymentStripeWeb2"))));
|
|
46
|
+
function StripeLoadingFallback() {
|
|
47
|
+
return ((0, jsx_runtime_1.jsx)("div", { className: "relative my-8 flex w-full flex-1 flex-col items-center justify-center", children: (0, jsx_runtime_1.jsxs)("div", { className: "bg-as-on-surface-1 flex w-full flex-col items-center justify-center gap-4 rounded-2xl p-8", children: [(0, jsx_runtime_1.jsx)("div", { className: "bg-as-brand/20 flex h-16 w-16 items-center justify-center rounded-full", children: (0, jsx_runtime_1.jsx)("div", { className: "text-as-brand h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent" }) }), (0, jsx_runtime_1.jsxs)("div", { className: "text-as-primary/70 text-center", children: [(0, jsx_runtime_1.jsx)("div", { className: "text-lg font-medium", children: "Loading payment" }), (0, jsx_runtime_1.jsx)("div", { className: "text-as-primary/50 mt-2 text-sm", children: "Initializing secure payment form..." })] })] }) }));
|
|
48
|
+
}
|
|
10
49
|
function PaymentVendorUI({ order, dstTokenSymbol }) {
|
|
11
50
|
const vendor = order.onrampMetadata?.vendor;
|
|
12
51
|
// Handle one-click payment flows (Coinbase, Stripe redirect)
|
|
@@ -15,7 +54,7 @@ function PaymentVendorUI({ order, dstTokenSymbol }) {
|
|
|
15
54
|
}
|
|
16
55
|
// Handle Stripe Web2 payment flow
|
|
17
56
|
if (vendor === "stripe-web2" && order.stripePaymentIntentId) {
|
|
18
|
-
return (0, jsx_runtime_1.jsx)(
|
|
57
|
+
return ((0, jsx_runtime_1.jsx)(react_1.Suspense, { fallback: (0, jsx_runtime_1.jsx)(StripeLoadingFallback, {}), children: (0, jsx_runtime_1.jsx)(PaymentStripeWeb2, { order: order, stripePaymentIntentId: order.stripePaymentIntentId }) }));
|
|
19
58
|
}
|
|
20
59
|
// Return null for unsupported vendors
|
|
21
60
|
return null;
|
|
@@ -6,17 +6,16 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.WebviewOnrampPayment = WebviewOnrampPayment;
|
|
7
7
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
8
|
const anyspend_1 = require("../../../../anyspend");
|
|
9
|
+
const payment_utils_1 = require("../../../../shared/utils/payment.utils");
|
|
9
10
|
const react_1 = require("../../../../anyspend/react");
|
|
10
11
|
const react_2 = require("../../../../global-account/react");
|
|
11
12
|
const centerTruncate_1 = __importDefault(require("../../../../shared/utils/centerTruncate"));
|
|
12
13
|
const react_stripe_js_1 = require("@stripe/react-stripe-js");
|
|
13
|
-
const stripe_js_1 = require("@stripe/stripe-js");
|
|
14
14
|
const lucide_react_1 = require("lucide-react");
|
|
15
15
|
const react_3 = require("motion/react");
|
|
16
16
|
const react_4 = require("react");
|
|
17
17
|
const viem_1 = require("viem");
|
|
18
18
|
const AnySpendFingerprintWrapper_1 = require("../AnySpendFingerprintWrapper");
|
|
19
|
-
const stripePromise = (0, stripe_js_1.loadStripe)(anyspend_1.STRIPE_CONFIG.publishableKey);
|
|
20
19
|
function WebviewOnrampPayment(props) {
|
|
21
20
|
const fingerprintConfig = (0, AnySpendFingerprintWrapper_1.getFingerprintConfig)();
|
|
22
21
|
return ((0, jsx_runtime_1.jsx)(AnySpendFingerprintWrapper_1.AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: (0, jsx_runtime_1.jsx)(WebviewOnrampPaymentInner, { ...props }) }));
|
|
@@ -169,7 +168,7 @@ function WebviewOnrampPaymentInner({ srcAmountOnRamp, recipientAddress, destinat
|
|
|
169
168
|
if (createdOrder && clientSecret) {
|
|
170
169
|
return ((0, jsx_runtime_1.jsxs)("div", { className: "mx-auto flex w-full max-w-[460px] flex-col gap-6", children: [(0, jsx_runtime_1.jsx)("div", { className: "overflow-hidden rounded-xl bg-white", children: (0, jsx_runtime_1.jsxs)("div", { className: "px-6 py-4", children: [(0, jsx_runtime_1.jsx)("h2", { className: "mb-4 text-lg font-semibold", children: "Order summary" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex flex-col divide-y", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "Receiving" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [destinationToken.metadata?.logoURI && ((0, jsx_runtime_1.jsx)("img", { src: destinationToken.metadata.logoURI, alt: destinationToken.symbol, className: "h-5 w-5 rounded-full" })), (0, jsx_runtime_1.jsxs)("span", { className: "font-medium", children: [anyspendQuote?.data?.currencyOut?.amount
|
|
171
170
|
? Number((0, viem_1.formatUnits)(BigInt(anyspendQuote.data.currencyOut.amount), destinationToken.decimals)).toFixed(4)
|
|
172
|
-
: "0", " ", destinationToken.symbol] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "Network" }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: (0, anyspend_1.getChainName)(destinationToken.chainId) })] }), recipientAddress && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "Recipient" }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: (0, centerTruncate_1.default)(recipientAddress) })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "You Pay" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-lg font-semibold", children: ["$", parseFloat(srcAmountOnRamp).toFixed(2)] })] })] })] }) }), (0, jsx_runtime_1.jsx)(react_stripe_js_1.Elements, { stripe:
|
|
171
|
+
: "0", " ", destinationToken.symbol] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "Network" }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: (0, anyspend_1.getChainName)(destinationToken.chainId) })] }), recipientAddress && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "Recipient" }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: (0, centerTruncate_1.default)(recipientAddress) })] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between py-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-gray-600", children: "You Pay" }), (0, jsx_runtime_1.jsxs)("span", { className: "text-lg font-semibold", children: ["$", parseFloat(srcAmountOnRamp).toFixed(2)] })] })] })] }) }), (0, jsx_runtime_1.jsx)(react_stripe_js_1.Elements, { stripe: (0, payment_utils_1.getStripePromise)(), options: {
|
|
173
172
|
clientSecret,
|
|
174
173
|
appearance: {
|
|
175
174
|
theme: "flat",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { components } from "../../anyspend/types/api";
|
|
2
|
+
export declare function getStripePromise(): Promise<import("@stripe/stripe-js").Stripe | null>;
|
|
2
3
|
export declare function getVendorDisplayName(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string;
|
|
3
4
|
export declare function getPaymentMethodDescription(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string;
|
|
4
5
|
export declare function formatStripeAmount(amount: number): string;
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getStripePromise = getStripePromise;
|
|
3
4
|
exports.getVendorDisplayName = getVendorDisplayName;
|
|
4
5
|
exports.getPaymentMethodDescription = getPaymentMethodDescription;
|
|
5
6
|
exports.formatStripeAmount = formatStripeAmount;
|
|
6
7
|
exports.generateReturnUrl = generateReturnUrl;
|
|
7
8
|
const constants_1 = require("../../anyspend/constants");
|
|
9
|
+
const stripe_js_1 = require("@stripe/stripe-js");
|
|
10
|
+
let stripePromise = null;
|
|
11
|
+
function getStripePromise() {
|
|
12
|
+
if (!stripePromise) {
|
|
13
|
+
stripePromise = (0, stripe_js_1.loadStripe)(constants_1.STRIPE_CONFIG.publishableKey);
|
|
14
|
+
}
|
|
15
|
+
return stripePromise;
|
|
16
|
+
}
|
|
8
17
|
function getVendorDisplayName(vendor) {
|
|
9
18
|
switch (vendor) {
|
|
10
19
|
case "coinbase":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { getDefaultToken, HYPERLIQUID_CHAIN_ID, USDC_BASE } from "../../../anyspend/index.js";
|
|
3
|
+
import { eqci, getDefaultToken, getHyperliquidUSDCToken, HYPERLIQUID_CHAIN_ID, USDC_BASE, ZERO_ADDRESS, } from "../../../anyspend/index.js";
|
|
4
4
|
import { useAnyspendCreateOnrampOrder, useAnyspendCreateOrder, useAnyspendOrderAndTransactions, useAnyspendQuote, useGeoOnrampOptions, } from "../../../anyspend/react/index.js";
|
|
5
5
|
import { Button, ShinyButton, StyleRoot, TabsPrimitive, toast, TransitionPanel, useAccountWallet, useB3, useModalStore, useProfile, useRouter, useSearchParamsSSR, useTokenBalanceDirect, useTokenData, useTokenFromUrl, } from "../../../global-account/react/index.js";
|
|
6
6
|
import BottomNavigation from "../../../global-account/react/components/ManageAccount/BottomNavigation.js";
|
|
@@ -107,14 +107,17 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
107
107
|
// State for destination chain/token selection
|
|
108
108
|
const [selectedDstChainId, setSelectedDstChainId] = useState(initialDstChainId);
|
|
109
109
|
const defaultDstToken = isBuyMode
|
|
110
|
-
?
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
110
|
+
? // Special case: Hyperliquid uses zero address for USDC
|
|
111
|
+
destinationTokenChainId === HYPERLIQUID_CHAIN_ID && eqci(destinationTokenAddress, ZERO_ADDRESS)
|
|
112
|
+
? getHyperliquidUSDCToken()
|
|
113
|
+
: {
|
|
114
|
+
symbol: "",
|
|
115
|
+
chainId: destinationTokenChainId,
|
|
116
|
+
address: destinationTokenAddress,
|
|
117
|
+
name: "",
|
|
118
|
+
decimals: 18,
|
|
119
|
+
metadata: {},
|
|
120
|
+
}
|
|
118
121
|
: getDefaultToken(selectedDstChainId);
|
|
119
122
|
const dstTokenFromUrl = useTokenFromUrl({
|
|
120
123
|
defaultToken: defaultDstToken,
|
|
@@ -152,6 +155,11 @@ function AnySpendInner({ destinationTokenAddress, destinationTokenChainId, mode
|
|
|
152
155
|
// Update destination token with metadata
|
|
153
156
|
useEffect(() => {
|
|
154
157
|
if (selectedDstToken && dstTokenMetadata && !appliedDstMetadataRef.current) {
|
|
158
|
+
// Skip metadata enhancement for Hyperliquid USDC - we already have correct metadata from getHyperliquidUSDCToken()
|
|
159
|
+
if (selectedDstToken.chainId === HYPERLIQUID_CHAIN_ID && eqci(selectedDstToken.address, ZERO_ADDRESS)) {
|
|
160
|
+
appliedDstMetadataRef.current = true;
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
155
163
|
// Mark as applied
|
|
156
164
|
appliedDstMetadataRef.current = true;
|
|
157
165
|
const enhancedToken = {
|
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { getStripePromise } from "../../../../shared/utils/payment.utils.js";
|
|
3
3
|
import { OrderDetailsCollapsible, useStripeClientSecret } from "../../../../anyspend/react/index.js";
|
|
4
4
|
import { ShinyButton, useB3, useModalStore, useProfile } from "../../../../global-account/react/index.js";
|
|
5
5
|
import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
6
6
|
import { formatStripeAmount } from "../../../../shared/utils/payment.utils.js";
|
|
7
7
|
import { AddressElement, Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
8
|
-
import { loadStripe } from "@stripe/stripe-js";
|
|
9
8
|
import { X } from "lucide-react";
|
|
10
9
|
import { useEffect, useState } from "react";
|
|
11
10
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper.js";
|
|
12
11
|
import HowItWorks from "./HowItWorks.js";
|
|
13
12
|
import PaymentMethodIcons from "./PaymentMethodIcons.js";
|
|
14
|
-
const stripePromise = loadStripe(STRIPE_CONFIG.publishableKey);
|
|
15
13
|
export default function PaymentStripeWeb2({ order, stripePaymentIntentId, onPaymentSuccess }) {
|
|
16
14
|
const { theme } = useB3();
|
|
17
15
|
const fingerprintConfig = getFingerprintConfig();
|
|
@@ -22,7 +20,7 @@ export default function PaymentStripeWeb2({ order, stripePaymentIntentId, onPaym
|
|
|
22
20
|
if (stripeClientSecretError) {
|
|
23
21
|
return _jsx(StripeErrorState, { error: stripeClientSecretError.message });
|
|
24
22
|
}
|
|
25
|
-
return (_jsx(AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: _jsx(Elements, { stripe:
|
|
23
|
+
return (_jsx(AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: _jsx(Elements, { stripe: getStripePromise(), options: {
|
|
26
24
|
clientSecret: clientSecret || undefined,
|
|
27
25
|
appearance: { theme: theme === "light" ? "stripe" : "night" },
|
|
28
26
|
}, children: _jsx(StripePaymentForm, { order: order, clientSecret: clientSecret, onPaymentSuccess: onPaymentSuccess }) }) }));
|
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { lazy, Suspense } from "react";
|
|
2
3
|
import PaymentOneClick from "./PaymentOneClick.js";
|
|
3
|
-
|
|
4
|
+
// Lazy load Stripe component to prevent loadStripe() from running at module level
|
|
5
|
+
// This prevents EIP-6963 wallet detection events when Stripe is not used
|
|
6
|
+
const PaymentStripeWeb2 = lazy(() => import("./PaymentStripeWeb2"));
|
|
7
|
+
function StripeLoadingFallback() {
|
|
8
|
+
return (_jsx("div", { className: "relative my-8 flex w-full flex-1 flex-col items-center justify-center", children: _jsxs("div", { className: "bg-as-on-surface-1 flex w-full flex-col items-center justify-center gap-4 rounded-2xl p-8", children: [_jsx("div", { className: "bg-as-brand/20 flex h-16 w-16 items-center justify-center rounded-full", children: _jsx("div", { className: "text-as-brand h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent" }) }), _jsxs("div", { className: "text-as-primary/70 text-center", children: [_jsx("div", { className: "text-lg font-medium", children: "Loading payment" }), _jsx("div", { className: "text-as-primary/50 mt-2 text-sm", children: "Initializing secure payment form..." })] })] }) }));
|
|
9
|
+
}
|
|
4
10
|
export default function PaymentVendorUI({ order, dstTokenSymbol }) {
|
|
5
11
|
const vendor = order.onrampMetadata?.vendor;
|
|
6
12
|
// Handle one-click payment flows (Coinbase, Stripe redirect)
|
|
@@ -9,7 +15,7 @@ export default function PaymentVendorUI({ order, dstTokenSymbol }) {
|
|
|
9
15
|
}
|
|
10
16
|
// Handle Stripe Web2 payment flow
|
|
11
17
|
if (vendor === "stripe-web2" && order.stripePaymentIntentId) {
|
|
12
|
-
return _jsx(PaymentStripeWeb2, { order: order, stripePaymentIntentId: order.stripePaymentIntentId });
|
|
18
|
+
return (_jsx(Suspense, { fallback: _jsx(StripeLoadingFallback, {}), children: _jsx(PaymentStripeWeb2, { order: order, stripePaymentIntentId: order.stripePaymentIntentId }) }));
|
|
13
19
|
}
|
|
14
20
|
// Return null for unsupported vendors
|
|
15
21
|
return null;
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { getChainName
|
|
2
|
+
import { getChainName } from "../../../../anyspend/index.js";
|
|
3
|
+
import { getStripePromise } from "../../../../shared/utils/payment.utils.js";
|
|
3
4
|
import { useAnyspendCreateOnrampOrder, useGeoOnrampOptions, useStripeClientSecret } from "../../../../anyspend/react/index.js";
|
|
4
5
|
import { toast } from "../../../../global-account/react/index.js";
|
|
5
6
|
import centerTruncate from "../../../../shared/utils/centerTruncate.js";
|
|
6
7
|
import { AddressElement, Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
7
|
-
import { loadStripe } from "@stripe/stripe-js";
|
|
8
8
|
import { Loader2 } from "lucide-react";
|
|
9
9
|
import { motion } from "motion/react";
|
|
10
10
|
import { useEffect, useRef, useState } from "react";
|
|
11
11
|
import { formatUnits } from "viem";
|
|
12
12
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper.js";
|
|
13
|
-
const stripePromise = loadStripe(STRIPE_CONFIG.publishableKey);
|
|
14
13
|
export function WebviewOnrampPayment(props) {
|
|
15
14
|
const fingerprintConfig = getFingerprintConfig();
|
|
16
15
|
return (_jsx(AnySpendFingerprintWrapper, { fingerprint: fingerprintConfig, children: _jsx(WebviewOnrampPaymentInner, { ...props }) }));
|
|
@@ -163,7 +162,7 @@ function WebviewOnrampPaymentInner({ srcAmountOnRamp, recipientAddress, destinat
|
|
|
163
162
|
if (createdOrder && clientSecret) {
|
|
164
163
|
return (_jsxs("div", { className: "mx-auto flex w-full max-w-[460px] flex-col gap-6", children: [_jsx("div", { className: "overflow-hidden rounded-xl bg-white", children: _jsxs("div", { className: "px-6 py-4", children: [_jsx("h2", { className: "mb-4 text-lg font-semibold", children: "Order summary" }), _jsxs("div", { className: "flex flex-col divide-y", children: [_jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "Receiving" }), _jsxs("div", { className: "flex items-center gap-2", children: [destinationToken.metadata?.logoURI && (_jsx("img", { src: destinationToken.metadata.logoURI, alt: destinationToken.symbol, className: "h-5 w-5 rounded-full" })), _jsxs("span", { className: "font-medium", children: [anyspendQuote?.data?.currencyOut?.amount
|
|
165
164
|
? Number(formatUnits(BigInt(anyspendQuote.data.currencyOut.amount), destinationToken.decimals)).toFixed(4)
|
|
166
|
-
: "0", " ", destinationToken.symbol] })] })] }), _jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "Network" }), _jsx("span", { className: "font-medium", children: getChainName(destinationToken.chainId) })] }), recipientAddress && (_jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "Recipient" }), _jsx("span", { className: "font-medium", children: centerTruncate(recipientAddress) })] })), _jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "You Pay" }), _jsxs("span", { className: "text-lg font-semibold", children: ["$", parseFloat(srcAmountOnRamp).toFixed(2)] })] })] })] }) }), _jsx(Elements, { stripe:
|
|
165
|
+
: "0", " ", destinationToken.symbol] })] })] }), _jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "Network" }), _jsx("span", { className: "font-medium", children: getChainName(destinationToken.chainId) })] }), recipientAddress && (_jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "Recipient" }), _jsx("span", { className: "font-medium", children: centerTruncate(recipientAddress) })] })), _jsxs("div", { className: "flex items-center justify-between py-3", children: [_jsx("span", { className: "text-gray-600", children: "You Pay" }), _jsxs("span", { className: "text-lg font-semibold", children: ["$", parseFloat(srcAmountOnRamp).toFixed(2)] })] })] })] }) }), _jsx(Elements, { stripe: getStripePromise(), options: {
|
|
167
166
|
clientSecret,
|
|
168
167
|
appearance: {
|
|
169
168
|
theme: "flat",
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { components } from "../../anyspend/types/api";
|
|
2
|
+
export declare function getStripePromise(): Promise<import("@stripe/stripe-js").Stripe | null>;
|
|
2
3
|
export declare function getVendorDisplayName(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string;
|
|
3
4
|
export declare function getPaymentMethodDescription(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string;
|
|
4
5
|
export declare function formatStripeAmount(amount: number): string;
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
-
import { VENDOR_DISPLAY_NAMES } from "../../anyspend/constants/index.js";
|
|
1
|
+
import { STRIPE_CONFIG, VENDOR_DISPLAY_NAMES } from "../../anyspend/constants/index.js";
|
|
2
|
+
import { loadStripe } from "@stripe/stripe-js";
|
|
3
|
+
let stripePromise = null;
|
|
4
|
+
export function getStripePromise() {
|
|
5
|
+
if (!stripePromise) {
|
|
6
|
+
stripePromise = loadStripe(STRIPE_CONFIG.publishableKey);
|
|
7
|
+
}
|
|
8
|
+
return stripePromise;
|
|
9
|
+
}
|
|
2
10
|
export function getVendorDisplayName(vendor) {
|
|
3
11
|
switch (vendor) {
|
|
4
12
|
case "coinbase":
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
2
|
+
export declare function getStripePromise(): Promise<import("@stripe/stripe-js").Stripe | null>;
|
|
2
3
|
export declare function getVendorDisplayName(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string;
|
|
3
4
|
export declare function getPaymentMethodDescription(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string;
|
|
4
5
|
export declare function formatStripeAmount(amount: number): string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
eqci,
|
|
5
|
+
getDefaultToken,
|
|
6
|
+
getHyperliquidUSDCToken,
|
|
7
|
+
HYPERLIQUID_CHAIN_ID,
|
|
8
|
+
USDC_BASE,
|
|
9
|
+
ZERO_ADDRESS,
|
|
10
|
+
} from "@b3dotfun/sdk/anyspend";
|
|
4
11
|
import {
|
|
5
12
|
useAnyspendCreateOnrampOrder,
|
|
6
13
|
useAnyspendCreateOrder,
|
|
@@ -224,14 +231,17 @@ function AnySpendInner({
|
|
|
224
231
|
// State for destination chain/token selection
|
|
225
232
|
const [selectedDstChainId, setSelectedDstChainId] = useState<number>(initialDstChainId);
|
|
226
233
|
const defaultDstToken = isBuyMode
|
|
227
|
-
?
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
234
|
+
? // Special case: Hyperliquid uses zero address for USDC
|
|
235
|
+
destinationTokenChainId === HYPERLIQUID_CHAIN_ID && eqci(destinationTokenAddress, ZERO_ADDRESS)
|
|
236
|
+
? getHyperliquidUSDCToken()
|
|
237
|
+
: {
|
|
238
|
+
symbol: "",
|
|
239
|
+
chainId: destinationTokenChainId,
|
|
240
|
+
address: destinationTokenAddress,
|
|
241
|
+
name: "",
|
|
242
|
+
decimals: 18,
|
|
243
|
+
metadata: {},
|
|
244
|
+
}
|
|
235
245
|
: getDefaultToken(selectedDstChainId);
|
|
236
246
|
const dstTokenFromUrl = useTokenFromUrl({
|
|
237
247
|
defaultToken: defaultDstToken,
|
|
@@ -277,6 +287,12 @@ function AnySpendInner({
|
|
|
277
287
|
// Update destination token with metadata
|
|
278
288
|
useEffect(() => {
|
|
279
289
|
if (selectedDstToken && dstTokenMetadata && !appliedDstMetadataRef.current) {
|
|
290
|
+
// Skip metadata enhancement for Hyperliquid USDC - we already have correct metadata from getHyperliquidUSDCToken()
|
|
291
|
+
if (selectedDstToken.chainId === HYPERLIQUID_CHAIN_ID && eqci(selectedDstToken.address, ZERO_ADDRESS)) {
|
|
292
|
+
appliedDstMetadataRef.current = true;
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
|
|
280
296
|
// Mark as applied
|
|
281
297
|
appliedDstMetadataRef.current = true;
|
|
282
298
|
|
|
@@ -1,19 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { getStripePromise } from "@b3dotfun/sdk/shared/utils/payment.utils";
|
|
2
2
|
import { OrderDetailsCollapsible, useStripeClientSecret } from "@b3dotfun/sdk/anyspend/react";
|
|
3
3
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
4
4
|
import { ShinyButton, useB3, useModalStore, useProfile } from "@b3dotfun/sdk/global-account/react";
|
|
5
5
|
import { formatTokenAmount } from "@b3dotfun/sdk/shared/utils/number";
|
|
6
6
|
import { formatStripeAmount } from "@b3dotfun/sdk/shared/utils/payment.utils";
|
|
7
7
|
import { AddressElement, Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
8
|
-
import {
|
|
8
|
+
import { PaymentIntentResult, StripePaymentElementOptions } from "@stripe/stripe-js";
|
|
9
9
|
import { X } from "lucide-react";
|
|
10
10
|
import { useEffect, useState } from "react";
|
|
11
11
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper";
|
|
12
12
|
import HowItWorks from "./HowItWorks";
|
|
13
13
|
import PaymentMethodIcons from "./PaymentMethodIcons";
|
|
14
14
|
|
|
15
|
-
const stripePromise = loadStripe(STRIPE_CONFIG.publishableKey);
|
|
16
|
-
|
|
17
15
|
interface PaymentStripeWeb2Props {
|
|
18
16
|
order: components["schemas"]["Order"];
|
|
19
17
|
stripePaymentIntentId: string;
|
|
@@ -38,7 +36,7 @@ export default function PaymentStripeWeb2({ order, stripePaymentIntentId, onPaym
|
|
|
38
36
|
return (
|
|
39
37
|
<AnySpendFingerprintWrapper fingerprint={fingerprintConfig}>
|
|
40
38
|
<Elements
|
|
41
|
-
stripe={
|
|
39
|
+
stripe={getStripePromise()}
|
|
42
40
|
options={{
|
|
43
41
|
clientSecret: clientSecret || undefined,
|
|
44
42
|
appearance: { theme: theme === "light" ? "stripe" : "night" },
|
|
@@ -1,12 +1,32 @@
|
|
|
1
|
+
import { lazy, Suspense } from "react";
|
|
1
2
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
2
3
|
import PaymentOneClick from "./PaymentOneClick";
|
|
3
|
-
|
|
4
|
+
|
|
5
|
+
// Lazy load Stripe component to prevent loadStripe() from running at module level
|
|
6
|
+
// This prevents EIP-6963 wallet detection events when Stripe is not used
|
|
7
|
+
const PaymentStripeWeb2 = lazy(() => import("./PaymentStripeWeb2"));
|
|
4
8
|
|
|
5
9
|
interface PaymentVendorUIProps {
|
|
6
10
|
order: components["schemas"]["Order"];
|
|
7
11
|
dstTokenSymbol: string;
|
|
8
12
|
}
|
|
9
13
|
|
|
14
|
+
function StripeLoadingFallback() {
|
|
15
|
+
return (
|
|
16
|
+
<div className="relative my-8 flex w-full flex-1 flex-col items-center justify-center">
|
|
17
|
+
<div className="bg-as-on-surface-1 flex w-full flex-col items-center justify-center gap-4 rounded-2xl p-8">
|
|
18
|
+
<div className="bg-as-brand/20 flex h-16 w-16 items-center justify-center rounded-full">
|
|
19
|
+
<div className="text-as-brand h-8 w-8 animate-spin rounded-full border-2 border-current border-t-transparent" />
|
|
20
|
+
</div>
|
|
21
|
+
<div className="text-as-primary/70 text-center">
|
|
22
|
+
<div className="text-lg font-medium">Loading payment</div>
|
|
23
|
+
<div className="text-as-primary/50 mt-2 text-sm">Initializing secure payment form...</div>
|
|
24
|
+
</div>
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
10
30
|
export default function PaymentVendorUI({ order, dstTokenSymbol }: PaymentVendorUIProps) {
|
|
11
31
|
const vendor = order.onrampMetadata?.vendor;
|
|
12
32
|
|
|
@@ -17,7 +37,11 @@ export default function PaymentVendorUI({ order, dstTokenSymbol }: PaymentVendor
|
|
|
17
37
|
|
|
18
38
|
// Handle Stripe Web2 payment flow
|
|
19
39
|
if (vendor === "stripe-web2" && order.stripePaymentIntentId) {
|
|
20
|
-
return
|
|
40
|
+
return (
|
|
41
|
+
<Suspense fallback={<StripeLoadingFallback />}>
|
|
42
|
+
<PaymentStripeWeb2 order={order} stripePaymentIntentId={order.stripePaymentIntentId} />
|
|
43
|
+
</Suspense>
|
|
44
|
+
);
|
|
21
45
|
}
|
|
22
46
|
|
|
23
47
|
// Return null for unsupported vendors
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { getChainName
|
|
1
|
+
import { getChainName } from "@b3dotfun/sdk/anyspend";
|
|
2
|
+
import { getStripePromise } from "@b3dotfun/sdk/shared/utils/payment.utils";
|
|
2
3
|
import { useAnyspendCreateOnrampOrder, useGeoOnrampOptions, useStripeClientSecret } from "@b3dotfun/sdk/anyspend/react";
|
|
3
4
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
4
5
|
import { GetQuoteResponse } from "@b3dotfun/sdk/anyspend/types/api_req_res";
|
|
5
6
|
import { toast } from "@b3dotfun/sdk/global-account/react";
|
|
6
7
|
import centerTruncate from "@b3dotfun/sdk/shared/utils/centerTruncate";
|
|
7
8
|
import { AddressElement, Elements, PaymentElement, useElements, useStripe } from "@stripe/react-stripe-js";
|
|
8
|
-
import { loadStripe } from "@stripe/stripe-js";
|
|
9
9
|
import { Loader2 } from "lucide-react";
|
|
10
10
|
import { motion } from "motion/react";
|
|
11
11
|
import { useEffect, useRef, useState } from "react";
|
|
@@ -13,8 +13,6 @@ import { useEffect, useRef, useState } from "react";
|
|
|
13
13
|
import { formatUnits } from "viem";
|
|
14
14
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper";
|
|
15
15
|
|
|
16
|
-
const stripePromise = loadStripe(STRIPE_CONFIG.publishableKey);
|
|
17
|
-
|
|
18
16
|
interface WebviewOnrampPaymentProps {
|
|
19
17
|
srcAmountOnRamp: string;
|
|
20
18
|
recipientAddress?: string;
|
|
@@ -309,7 +307,7 @@ function WebviewOnrampPaymentInner({
|
|
|
309
307
|
|
|
310
308
|
{/* Stripe Elements */}
|
|
311
309
|
<Elements
|
|
312
|
-
stripe={
|
|
310
|
+
stripe={getStripePromise()}
|
|
313
311
|
options={{
|
|
314
312
|
clientSecret,
|
|
315
313
|
appearance: {
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
-
import { VENDOR_DISPLAY_NAMES } from "@b3dotfun/sdk/anyspend/constants";
|
|
1
|
+
import { STRIPE_CONFIG, VENDOR_DISPLAY_NAMES } from "@b3dotfun/sdk/anyspend/constants";
|
|
2
2
|
import { components } from "@b3dotfun/sdk/anyspend/types/api";
|
|
3
|
+
import { loadStripe } from "@stripe/stripe-js";
|
|
4
|
+
|
|
5
|
+
let stripePromise: ReturnType<typeof loadStripe> | null = null;
|
|
6
|
+
export function getStripePromise() {
|
|
7
|
+
if (!stripePromise) {
|
|
8
|
+
stripePromise = loadStripe(STRIPE_CONFIG.publishableKey);
|
|
9
|
+
}
|
|
10
|
+
return stripePromise;
|
|
11
|
+
}
|
|
3
12
|
|
|
4
13
|
export function getVendorDisplayName(vendor?: components["schemas"]["OnrampMetadata"]["vendor"]): string {
|
|
5
14
|
switch (vendor) {
|