@b3dotfun/sdk 0.0.16 → 0.0.17-alpha.0
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.d.ts +5 -2
- package/dist/cjs/anyspend/react/components/AnySpend.js +264 -55
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +25 -29
- package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.d.ts +15 -0
- package/dist/cjs/anyspend/react/components/common/ConnectWalletPayment.js +49 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.d.ts +20 -0
- package/dist/cjs/anyspend/react/components/common/CryptoPaymentMethod.js +118 -0
- package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.d.ts +15 -0
- package/dist/cjs/anyspend/react/components/common/FiatPaymentMethod.js +71 -0
- package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +2 -0
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +41 -60
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +18 -0
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +42 -0
- package/dist/cjs/anyspend/react/components/common/OrderStatus.js +28 -5
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmountFiat.d.ts +13 -0
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmountFiat.js +50 -0
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmountNew.d.ts +16 -0
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmountNew.js +63 -0
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +11 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +53 -15
- package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +1 -12
- package/dist/cjs/anyspend/react/components/common/PaymentStripeWeb2.js +4 -12
- package/dist/cjs/anyspend/react/components/common/StepProgress.d.ts +11 -0
- package/dist/cjs/anyspend/react/components/common/StepProgress.js +22 -0
- package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.d.ts +16 -0
- package/dist/cjs/anyspend/react/components/common/TransferCryptoDetails.js +73 -0
- package/dist/cjs/anyspend/react/components/index.d.ts +3 -0
- package/dist/cjs/anyspend/react/components/index.js +7 -1
- package/dist/cjs/anyspend/react/components/webview/WebviewOnrampPayment.js +1 -10
- package/dist/cjs/anyspend/utils/format.d.ts +1 -0
- package/dist/cjs/anyspend/utils/format.js +23 -10
- package/dist/cjs/anyspend/utils/number.d.ts +7 -0
- package/dist/cjs/anyspend/utils/number.js +18 -0
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +5 -2
- package/dist/esm/anyspend/react/components/AnySpend.js +266 -57
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +27 -31
- package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.d.ts +15 -0
- package/dist/esm/anyspend/react/components/common/ConnectWalletPayment.js +46 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.d.ts +20 -0
- package/dist/esm/anyspend/react/components/common/CryptoPaymentMethod.js +114 -0
- package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.d.ts +15 -0
- package/dist/esm/anyspend/react/components/common/FiatPaymentMethod.js +67 -0
- package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +2 -0
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +43 -62
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +18 -0
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +36 -0
- package/dist/esm/anyspend/react/components/common/OrderStatus.js +27 -4
- package/dist/esm/anyspend/react/components/common/OrderTokenAmountFiat.d.ts +13 -0
- package/dist/esm/anyspend/react/components/common/OrderTokenAmountFiat.js +47 -0
- package/dist/esm/anyspend/react/components/common/OrderTokenAmountNew.d.ts +16 -0
- package/dist/esm/anyspend/react/components/common/OrderTokenAmountNew.js +60 -0
- package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +11 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.js +54 -16
- package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +1 -12
- package/dist/esm/anyspend/react/components/common/PaymentStripeWeb2.js +7 -15
- package/dist/esm/anyspend/react/components/common/StepProgress.d.ts +11 -0
- package/dist/esm/anyspend/react/components/common/StepProgress.js +19 -0
- package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.d.ts +16 -0
- package/dist/esm/anyspend/react/components/common/TransferCryptoDetails.js +70 -0
- package/dist/esm/anyspend/react/components/index.d.ts +3 -0
- package/dist/esm/anyspend/react/components/index.js +3 -0
- package/dist/esm/anyspend/react/components/webview/WebviewOnrampPayment.js +1 -10
- package/dist/esm/anyspend/utils/format.d.ts +1 -0
- package/dist/esm/anyspend/utils/format.js +23 -10
- package/dist/esm/anyspend/utils/number.d.ts +7 -0
- package/dist/esm/anyspend/utils/number.js +17 -0
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/react/components/AnySpend.d.ts +5 -2
- package/dist/types/anyspend/react/components/common/ConnectWalletPayment.d.ts +15 -0
- package/dist/types/anyspend/react/components/common/CryptoPaymentMethod.d.ts +20 -0
- package/dist/types/anyspend/react/components/common/FiatPaymentMethod.d.ts +15 -0
- package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +2 -0
- package/dist/types/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +18 -0
- package/dist/types/anyspend/react/components/common/OrderTokenAmountFiat.d.ts +13 -0
- package/dist/types/anyspend/react/components/common/OrderTokenAmountNew.d.ts +16 -0
- package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +11 -1
- package/dist/types/anyspend/react/components/common/StepProgress.d.ts +11 -0
- package/dist/types/anyspend/react/components/common/TransferCryptoDetails.d.ts +16 -0
- package/dist/types/anyspend/react/components/index.d.ts +3 -0
- package/dist/types/anyspend/utils/format.d.ts +1 -0
- package/dist/types/anyspend/utils/number.d.ts +7 -0
- package/package.json +1 -1
- package/src/anyspend/react/components/AnySpend.tsx +535 -177
- package/src/anyspend/react/components/AnySpendCustom.tsx +33 -38
- package/src/anyspend/react/components/common/ConnectWalletPayment.tsx +124 -0
- package/src/anyspend/react/components/common/CryptoPaymentMethod.tsx +227 -0
- package/src/anyspend/react/components/common/FiatPaymentMethod.tsx +173 -0
- package/src/anyspend/react/components/common/OrderDetails.tsx +123 -250
- package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +156 -0
- package/src/anyspend/react/components/common/OrderStatus.tsx +47 -24
- package/src/anyspend/react/components/common/OrderTokenAmountFiat.tsx +147 -0
- package/src/anyspend/react/components/common/OrderTokenAmountNew.tsx +215 -0
- package/src/anyspend/react/components/common/PanelOnramp.tsx +215 -62
- package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +1 -14
- package/src/anyspend/react/components/common/PaymentStripeWeb2.tsx +42 -99
- package/src/anyspend/react/components/common/StepProgress.tsx +104 -0
- package/src/anyspend/react/components/common/TransferCryptoDetails.tsx +261 -0
- package/src/anyspend/react/components/index.ts +3 -0
- package/src/anyspend/react/components/webview/WebviewOnrampPayment.tsx +1 -11
- package/src/anyspend/utils/format.ts +24 -11
- package/src/anyspend/utils/number.ts +18 -0
- package/src/styles/index.css +30 -11
|
@@ -1,14 +1,53 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useCoinbaseOnrampOptions } from "../../../../anyspend/react/index.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useCoinbaseOnrampOptions, useGeoOnrampOptions } from "../../../../anyspend/react/index.js";
|
|
3
|
+
import { ALL_CHAINS } from "../../../../anyspend/utils/chain.js";
|
|
4
|
+
import { Input, useGetGeo, useProfile } from "../../../../global-account/react/index.js";
|
|
5
|
+
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
6
|
+
import { ChevronRight, Wallet } from "lucide-react";
|
|
5
7
|
import { useRef } from "react";
|
|
6
8
|
import { toast } from "sonner";
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
+
import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
|
|
10
|
+
import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat.js";
|
|
11
|
+
export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, }) {
|
|
12
|
+
// Get geo-based onramp options to access fee information
|
|
13
|
+
const { stripeWeb2Support } = useGeoOnrampOptions(true, srcAmountOnRamp);
|
|
14
|
+
// Helper function to get fees from API data
|
|
15
|
+
const getFeeFromApi = (paymentMethod) => {
|
|
16
|
+
switch (paymentMethod) {
|
|
17
|
+
case FiatPaymentMethod.COINBASE_PAY:
|
|
18
|
+
// Coinbase doesn't provide fee info in API, return 0
|
|
19
|
+
return 0;
|
|
20
|
+
case FiatPaymentMethod.STRIPE:
|
|
21
|
+
// Get fee from Stripe API response
|
|
22
|
+
if (stripeWeb2Support && "formattedFeeUsd" in stripeWeb2Support) {
|
|
23
|
+
return parseFloat(stripeWeb2Support.formattedFeeUsd) || 0;
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
default:
|
|
27
|
+
return null; // No fee when no payment method selected
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
// Helper function to get total amount from API (for Stripe) or calculate it (for others)
|
|
31
|
+
const getTotalAmount = (paymentMethod) => {
|
|
32
|
+
const baseAmount = parseFloat(srcAmountOnRamp) || 5;
|
|
33
|
+
const fee = getFeeFromApi(paymentMethod);
|
|
34
|
+
if (paymentMethod === FiatPaymentMethod.STRIPE && stripeWeb2Support && "formattedTotalUsd" in stripeWeb2Support) {
|
|
35
|
+
// Use the total from Stripe API if available
|
|
36
|
+
return parseFloat(stripeWeb2Support.formattedTotalUsd) || baseAmount;
|
|
37
|
+
}
|
|
38
|
+
// For Coinbase or when fee is available, calculate manually
|
|
39
|
+
if (fee !== null) {
|
|
40
|
+
return baseAmount + fee;
|
|
41
|
+
}
|
|
42
|
+
// No fee available, return base amount
|
|
43
|
+
return baseAmount;
|
|
44
|
+
};
|
|
9
45
|
// Get geo data for onramp availability
|
|
10
46
|
const { geoData } = useGetGeo();
|
|
11
47
|
const { coinbaseOnrampOptions } = useCoinbaseOnrampOptions(true, geoData?.country || "US");
|
|
48
|
+
// Get recipient profile for displaying name
|
|
49
|
+
const recipientProfile = useProfile({ address: _recipientAddress });
|
|
50
|
+
const recipientName = recipientProfile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
12
51
|
const amountInputRef = useRef(null);
|
|
13
52
|
const handleAmountChange = (e) => {
|
|
14
53
|
// Only allow numbers and decimal points
|
|
@@ -26,14 +65,13 @@ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, }) {
|
|
|
26
65
|
const handleQuickAmount = (value) => {
|
|
27
66
|
setSrcAmountOnRamp(value);
|
|
28
67
|
};
|
|
29
|
-
return (_jsxs("div", { className: "bg-as-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
: "border-as-stroke hover:border-as-brand hover:bg-as-brand/30"} transition-all duration-200`, children: ["$", value] }, value))) })] }));
|
|
68
|
+
return (_jsxs("div", { className: "bg-as-surface-primary flex w-full flex-col", children: [_jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary relative flex w-full flex-col rounded-2xl border p-4", children: [_jsxs("div", { className: "flex h-7 w-full items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm font-bold", children: "Pay" }), _jsx("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm", onClick: () => setActivePanel(7), children: selectedPaymentMethod === FiatPaymentMethod.COINBASE_PAY ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "C" }) }), "Coinbase Pay"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : selectedPaymentMethod === FiatPaymentMethod.STRIPE ? (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx("div", { className: "flex h-5 w-5 items-center justify-center rounded-full bg-blue-600", children: _jsx("span", { className: "text-xs font-bold text-white", children: "S" }) }), "Stripe"] }), _jsx(ChevronRight, { className: "h-4 w-4" })] })) : (_jsxs(_Fragment, { children: ["Select payment method", _jsx(ChevronRight, { className: "h-4 w-4" })] })) })] }), _jsx("div", { className: "flex items-center justify-center pb-2 pt-8", children: _jsxs("div", { className: "flex gap-1", children: [_jsx("span", { className: "text-as-tertiarry text-2xl font-bold", children: "$" }), _jsx(Input, { ref: amountInputRef, type: "text", value: srcAmountOnRamp, onChange: handleAmountChange, placeholder: "5", className: "text-as-primary placeholder:text-as-primary/50 h-auto min-w-[70px] border-0 bg-transparent p-0 px-3 pt-1 text-4xl font-bold focus-visible:ring-0 focus-visible:ring-offset-0", style: {
|
|
69
|
+
width: `${Math.max(50, srcAmountOnRamp.length * 34)}px`,
|
|
70
|
+
} })] }) }), _jsx("div", { className: "mx-auto mb-6 inline-grid grid-cols-4 gap-2", children: ["5", "10", "25", "100"].map(value => (_jsxs("button", { onClick: () => handleQuickAmount(value), className: `bg-as-surface-secondary border-as-border-secondary hover:border-as-border-secondary h-7 w-14 rounded-lg border text-sm font-medium transition-all duration-200 ${srcAmountOnRamp === value
|
|
71
|
+
? "border-as-border-secondary bg-as-surface-secondary"
|
|
72
|
+
: "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && (_jsx(OrderTokenAmountFiat, { address: _recipientAddress, context: "to", inputValue: destinationAmount || "0", onChangeInput: () => { }, chainId: destinationChainId, setChainId: onDestinationChainChange || (() => { }), token: destinationToken, setToken: onDestinationTokenChange || (() => { }) }))] }), _jsxs("div", { className: "border-as-border-secondary bg-as-surface-secondary mt-4 flex w-full flex-col gap-3 rounded-xl border p-4", children: [_jsxs("div", { className: "flex w-full items-center justify-between gap-2", children: [_jsx("span", { className: "text-as-tertiarry flex items-center text-sm", children: "Recipient" }), _recipientAddress ? (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-full bg-orange-500 text-xs text-white", children: "\uD83E\uDD8A" }), _jsx("span", { className: "text-sm", children: recipientName || shortenAddress(_recipientAddress) }), _jsx(ChevronRight, { size: 16 })] })) : (_jsxs("button", { className: "text-as-tertiarry flex h-7 items-center gap-1 text-sm transition-colors hover:text-blue-700", onClick: () => setActivePanel(5), children: [_jsx(Wallet, { className: "text-as-brand", size: 16 }), "Select recipient", _jsx(ChevronRight, { size: 16 })] }))] }), _jsx("div", { className: "divider w-full" }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: "Expected to receive" }), _jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-as-primary font-semibold", children: [destinationAmount || "0", " ", destinationToken?.symbol || ""] }), _jsxs("span", { className: "text-as-tertiarry text-sm", children: ["on ", destinationChainId ? ALL_CHAINS[destinationChainId]?.name : ""] }), destinationToken && destinationChainId && destinationToken.metadata?.logoURI && (_jsx("img", { src: ALL_CHAINS[destinationChainId]?.logoUrl, alt: "Chain", className: "h-4 w-4 rounded-full" }))] })] }), _jsx("div", { className: "divider w-full" }), _jsx("div", { className: "", children: _jsx("div", { className: "flex items-center justify-between", children: (() => {
|
|
73
|
+
const currentPaymentMethod = selectedPaymentMethod || FiatPaymentMethod.NONE;
|
|
74
|
+
const fee = getFeeFromApi(currentPaymentMethod);
|
|
75
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total" }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(currentPaymentMethod).toFixed(2)] })] }));
|
|
76
|
+
})() }) })] })] }));
|
|
39
77
|
}
|
|
@@ -5,7 +5,6 @@ import centerTruncate from "../../../../shared/utils/centerTruncate.js";
|
|
|
5
5
|
import invariant from "invariant";
|
|
6
6
|
import { ChevronLeft, ChevronRight, Landmark, Loader2 } from "lucide-react";
|
|
7
7
|
import { motion } from "motion/react";
|
|
8
|
-
import { useEffect, useRef, useState } from "react";
|
|
9
8
|
import { toast } from "sonner";
|
|
10
9
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper.js";
|
|
11
10
|
export function PanelOnrampPayment(props) {
|
|
@@ -14,17 +13,7 @@ export function PanelOnrampPayment(props) {
|
|
|
14
13
|
}
|
|
15
14
|
function PanelOnrampPaymentInner(props) {
|
|
16
15
|
const { srcAmountOnRamp, recipientAddress, isMainnet, isBuyMode, destinationTokenChainId, destinationTokenAddress, selectedDstChainId, selectedDstToken, anyspendQuote, globalAddress, onOrderCreated, onBack, orderType, nft, tournament, payload, recipientEnsName, recipientImageUrl, } = props;
|
|
17
|
-
|
|
18
|
-
const [stableAmountForGeo, setStableAmountForGeo] = useState(srcAmountOnRamp);
|
|
19
|
-
const hasInitialized = useRef(false);
|
|
20
|
-
// Only update the stable amount on first render or when explicitly needed
|
|
21
|
-
useEffect(() => {
|
|
22
|
-
if (!hasInitialized.current && srcAmountOnRamp) {
|
|
23
|
-
setStableAmountForGeo(srcAmountOnRamp);
|
|
24
|
-
hasInitialized.current = true;
|
|
25
|
-
}
|
|
26
|
-
}, [srcAmountOnRamp]);
|
|
27
|
-
const { geoData, coinbaseOnrampOptions, coinbaseAvailablePaymentMethods, isStripeOnrampSupported, stripeWeb2Support, isLoading: isLoadingGeoOnramp, } = useGeoOnrampOptions(isMainnet, stableAmountForGeo);
|
|
16
|
+
const { geoData, coinbaseOnrampOptions, coinbaseAvailablePaymentMethods, isStripeOnrampSupported, stripeWeb2Support, isLoading: isLoadingGeoOnramp, } = useGeoOnrampOptions(isMainnet, srcAmountOnRamp);
|
|
28
17
|
const isLoading = isLoadingGeoOnramp;
|
|
29
18
|
const { createOrder, isCreatingOrder } = useAnyspendCreateOnrampOrder({
|
|
30
19
|
onSuccess: data => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { USDC_BASE } from "../../../../anyspend/index.js";
|
|
3
2
|
import { STRIPE_CONFIG } from "../../../../anyspend/constants/index.js";
|
|
4
|
-
import { useStripeClientSecret } from "../../../../anyspend/react/index.js";
|
|
5
|
-
import { ShinyButton, useB3, useModalStore } from "../../../../global-account/react/index.js";
|
|
3
|
+
import { OrderDetailsCollapsible, useStripeClientSecret } from "../../../../anyspend/react/index.js";
|
|
4
|
+
import { ShinyButton, useB3, useModalStore, useProfile } from "../../../../global-account/react/index.js";
|
|
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
8
|
import { loadStripe } from "@stripe/stripe-js";
|
|
9
|
-
import {
|
|
9
|
+
import { X } from "lucide-react";
|
|
10
10
|
import { useEffect, useState } from "react";
|
|
11
11
|
import { AnySpendFingerprintWrapper, getFingerprintConfig } from "../AnySpendFingerprintWrapper.js";
|
|
12
12
|
import HowItWorks from "./HowItWorks.js";
|
|
@@ -125,6 +125,8 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
|
|
|
125
125
|
window.history.replaceState({}, "", url.toString());
|
|
126
126
|
}
|
|
127
127
|
}, [setB3ModalOpen]);
|
|
128
|
+
const profile = useProfile({ address: order.recipientAddress });
|
|
129
|
+
const recipientName = profile.data?.name?.replace(/\.b3\.fun/g, "");
|
|
128
130
|
if (!stripeReady) {
|
|
129
131
|
return _jsx(StripeLoadingState, {});
|
|
130
132
|
}
|
|
@@ -152,12 +154,7 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
|
|
|
152
154
|
description: "After payment confirmation, your order will be processed and completed automatically",
|
|
153
155
|
},
|
|
154
156
|
];
|
|
155
|
-
return (_jsxs("div", { className: "relative
|
|
156
|
-
const originalAmount = Number(order.srcAmount) / 10 ** USDC_BASE.decimals;
|
|
157
|
-
const finalAmount = Number(amount);
|
|
158
|
-
const calculatedFee = finalAmount - originalAmount;
|
|
159
|
-
return (_jsxs("div", { className: "space-y-2", children: [_jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsx("span", { className: "text-as-primary/60", children: "Amount" }), _jsxs("span", { className: "text-as-primary", children: ["$", originalAmount.toFixed(2)] })] }), _jsxs("div", { className: "flex items-center justify-between text-sm", children: [_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "text-as-primary/60", children: "Processing fee" }), _jsx(Tooltip, { content: `Credit card companies charge a processing fee of 5.4% + $0.30 for all transactions.\n\nThis fee covers secure payment processing and fraud protection.`, children: _jsx(Info, { className: "text-as-primary/40 hover:text-as-primary/60 h-3 w-3 transition-colors" }) })] }), _jsxs("span", { className: "text-as-primary", children: ["$", calculatedFee.toFixed(2)] })] }), _jsx("div", { className: "border-as-stroke border-t pt-2", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-primary font-semibold", children: "Total Amount" }), _jsxs("span", { className: "text-as-primary text-2xl font-bold", children: ["$", finalAmount.toFixed(2), " USD"] })] }) })] }));
|
|
160
|
-
})()] }))] }), _jsxs("div", { className: "bg-as-on-surface-1 w-full rounded-2xl p-6", children: [_jsx("div", { className: "text-as-primary mb-4 text-lg font-semibold", children: "Payment Details" }), _jsx(PaymentElement, { onChange: handlePaymentElementChange, options: stripeElementOptions }), showAddressElement && (_jsx(AddressElement, { options: {
|
|
157
|
+
return (_jsxs("div", { className: "relative mt-1 flex w-full flex-1 flex-col items-center justify-center", children: [_jsxs("form", { onSubmit: handleSubmit, className: "w-full space-y-6", children: [_jsx(OrderDetailsCollapsible, { order: order, dstToken: order.metadata.dstToken, tournament: order.type === "join_tournament" || order.type === "fund_tournament" ? order.metadata.tournament : undefined, nft: order.type === "mint_nft" ? order.metadata.nft : undefined, recipientName: recipientName, formattedExpectedDstAmount: formatTokenAmount(BigInt(order.srcAmount), order.metadata.dstToken.decimals), showTotal: true, totalAmount: amount ? `$${Number(amount).toFixed(2)}` : undefined }), _jsxs("div", { className: "w-full", children: [_jsx("div", { className: "text-as-primary mb-4 text-lg font-semibold", children: "Payment Details" }), _jsx(PaymentElement, { onChange: handlePaymentElementChange, options: stripeElementOptions }), showAddressElement && (_jsx(AddressElement, { options: {
|
|
161
158
|
mode: "billing",
|
|
162
159
|
fields: {
|
|
163
160
|
phone: "always",
|
|
@@ -174,8 +171,3 @@ function StripePaymentForm({ order, clientSecret, onPaymentSuccess, }) {
|
|
|
174
171
|
},
|
|
175
172
|
} }))] }), message && (_jsxs("div", { className: "bg-as-red/10 border-as-red/20 flex w-full items-center gap-3 rounded-2xl border p-4", children: [_jsx("div", { className: "bg-as-red flex h-6 w-6 shrink-0 items-center justify-center rounded-full", children: _jsx("svg", { className: "h-4 w-4 text-white", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) }), _jsx("div", { className: "text-as-red text-sm font-medium", children: message })] })), _jsx(ShinyButton, { type: "submit", accentColor: "hsl(var(--as-brand))", disabled: !stripe || !elements || loading, className: "relative w-full py-4 text-lg font-semibold", children: loading ? (_jsxs("div", { className: "flex items-center justify-center gap-3", children: [_jsx("div", { className: "h-5 w-5 animate-spin rounded-full border-2 border-current border-t-transparent" }), _jsx("span", { className: "text-white", children: "Processing Payment..." })] })) : (_jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsx("span", { className: "text-white", children: "Complete Payment" }), amount && _jsxs("span", { className: "text-white/90", children: ["$", Number(amount).toFixed(2)] })] })) })] }), showHowItWorks && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4", children: _jsxs("div", { className: "bg-as-on-surface-1 relative max-h-[80vh] w-full max-w-2xl overflow-y-auto rounded-2xl p-6", children: [_jsxs("div", { className: "mb-6 flex items-center justify-between", children: [_jsx("h2", { className: "text-as-primary text-xl font-semibold", children: "How it works" }), _jsx("button", { onClick: () => setShowHowItWorks(false), className: "text-as-primary/60 hover:text-as-primary transition-colors", children: _jsx(X, { className: "h-6 w-6" }) })] }), _jsxs("div", { className: "space-y-6", children: [_jsx(PaymentMethodIcons, {}), _jsx(HowItWorks, { steps: howItWorksSteps })] })] }) }))] }));
|
|
176
173
|
}
|
|
177
|
-
// Add tooltip component
|
|
178
|
-
function Tooltip({ children, content }) {
|
|
179
|
-
const [isVisible, setIsVisible] = useState(false);
|
|
180
|
-
return (_jsxs("div", { className: "relative inline-block", children: [_jsx("div", { onMouseEnter: () => setIsVisible(true), onMouseLeave: () => setIsVisible(false), className: "cursor-help", children: children }), isVisible && (_jsx("div", { className: "absolute bottom-full left-1/2 z-50 mb-2 w-80 -translate-x-1/2", children: _jsxs("div", { className: "bg-as-on-surface-1 border-as-stroke text-as-primary rounded-lg border p-3 text-sm shadow-lg", children: [_jsx("div", { className: "whitespace-pre-line", children: content }), _jsx("div", { className: "absolute left-1/2 top-full -translate-x-1/2", children: _jsx("div", { className: "border-t-as-on-surface-1 border-l-4 border-r-4 border-t-4 border-transparent" }) })] }) }))] }));
|
|
181
|
-
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface Step {
|
|
2
|
+
id: string | number;
|
|
3
|
+
title: string;
|
|
4
|
+
description?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface StepProgressProps {
|
|
7
|
+
steps: Step[];
|
|
8
|
+
currentStepIndex: number;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function StepProgress({ steps, currentStepIndex, className }: StepProgressProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { motion } from "framer-motion";
|
|
4
|
+
import { CheckIcon } from "lucide-react";
|
|
5
|
+
export function StepProgress({ steps, currentStepIndex, className = "" }) {
|
|
6
|
+
const currentStep = steps[currentStepIndex];
|
|
7
|
+
return (_jsxs("div", { className: `flex w-full flex-col items-center gap-4 ${className}`, children: [_jsx("div", { className: "flex items-center gap-2", children: steps.map((step, index) => (_jsxs(_Fragment, { children: [_jsx("div", { className: "flex items-center", children: _jsx(motion.div, { initial: { scale: 0.8, opacity: 0 }, animate: { scale: 1, opacity: 1 }, transition: { delay: index * 0.2 }, className: `relative flex h-10 w-10 items-center justify-center rounded-full ${index < currentStepIndex
|
|
8
|
+
? "bg-as-success-secondary" // Completed step
|
|
9
|
+
: index === currentStepIndex
|
|
10
|
+
? "border-as-border-secondary border-[3px]" // Current step
|
|
11
|
+
: "border-as-border-secondary border-[3px]" // Future step
|
|
12
|
+
} `, children: index < currentStepIndex ? (
|
|
13
|
+
// Completed step - show check icon
|
|
14
|
+
_jsx(CheckIcon, { className: "text-as-content-icon-success h-6 w-6" })) : index === currentStepIndex ? (
|
|
15
|
+
// Current step - show spinning border and step number
|
|
16
|
+
_jsxs(_Fragment, { children: [_jsx("div", { className: "border-t-as-primary absolute -inset-0.5 animate-spin rounded-full border-[3px] border-transparent" }), _jsx("span", { className: "text-as-primary font-semibold", children: index + 1 })] })) : (
|
|
17
|
+
// Future step - show step number with disabled styling
|
|
18
|
+
_jsx("span", { className: "text-as-content-disabled font-semibold", children: index + 1 })) }) }, step.id), index < steps.length - 1 && (_jsx("div", { className: "flex w-8 items-center justify-center gap-1", children: Array.from({ length: 6 }).map((_, dotIndex) => (_jsx("div", { className: "bg-as-primary/30 h-[2px] w-[2px] rounded-full" }, dotIndex))) }))] }))) }), currentStep && (_jsxs(motion.div, { initial: { opacity: 0, y: 10 }, animate: { opacity: 1, y: 0 }, transition: { delay: 0.3 }, className: "text-center", children: [_jsx("h2", { className: "text-as-primary text-xl font-semibold", children: currentStep.title }), currentStep.description && _jsx("p", { className: "text-as-primary/50 mt-1 text-sm", children: currentStep.description })] }))] }));
|
|
19
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { components } from "../../../../anyspend/types/api";
|
|
2
|
+
type Order = components["schemas"]["Order"];
|
|
3
|
+
type Token = components["schemas"]["Token"];
|
|
4
|
+
type Tournament = components["schemas"]["Tournament"];
|
|
5
|
+
type NFT = components["schemas"]["NFT"];
|
|
6
|
+
interface TransferCryptoDetailsProps {
|
|
7
|
+
order: Order;
|
|
8
|
+
srcToken: Token;
|
|
9
|
+
dstToken: Token;
|
|
10
|
+
tournament?: Tournament;
|
|
11
|
+
nft?: NFT;
|
|
12
|
+
onBack: () => void;
|
|
13
|
+
recipientName?: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const TransferCryptoDetails: import("react").NamedExoticComponent<TransferCryptoDetailsProps>;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ALL_CHAINS, getChainName, getPaymentUrl, RELAY_ETH_ADDRESS } from "../../../../anyspend/index.js";
|
|
4
|
+
import { CopyToClipboard, ShinyButton, TextLoop } from "../../../../global-account/react/index.js";
|
|
5
|
+
import { cn } from "../../../../shared/utils/index.js";
|
|
6
|
+
import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
7
|
+
import { WalletCoinbase, WalletMetamask, WalletPhantom, WalletTrust } from "@web3icons/react";
|
|
8
|
+
import { ChevronLeft, Copy } from "lucide-react";
|
|
9
|
+
import { QRCodeSVG } from "qrcode.react";
|
|
10
|
+
import { memo, useEffect, useMemo, useState } from "react";
|
|
11
|
+
import { toast } from "sonner";
|
|
12
|
+
import { b3 } from "viem/chains";
|
|
13
|
+
import { OrderDetailsCollapsible } from "./OrderDetailsCollapsible.js";
|
|
14
|
+
export const TransferCryptoDetails = memo(function TransferCryptoDetails({ order, srcToken, dstToken, tournament, nft, onBack, recipientName, }) {
|
|
15
|
+
const [timeLeft, setTimeLeft] = useState(0);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const calculateTimeLeft = () => {
|
|
18
|
+
if (!order.expiredAt)
|
|
19
|
+
return 0;
|
|
20
|
+
const now = Date.now();
|
|
21
|
+
const expiredAt = new Date(order.expiredAt).getTime();
|
|
22
|
+
const diff = Math.max(0, Math.floor((expiredAt - now) / 1000));
|
|
23
|
+
return diff;
|
|
24
|
+
};
|
|
25
|
+
// Set initial time
|
|
26
|
+
setTimeLeft(calculateTimeLeft());
|
|
27
|
+
const timer = setInterval(() => {
|
|
28
|
+
setTimeLeft(calculateTimeLeft());
|
|
29
|
+
}, 1000);
|
|
30
|
+
return () => clearInterval(timer);
|
|
31
|
+
}, [order.expiredAt]);
|
|
32
|
+
const formatTime = (seconds) => {
|
|
33
|
+
const minutes = Math.floor(seconds / 60);
|
|
34
|
+
const remainingSeconds = seconds % 60;
|
|
35
|
+
return `${minutes}:${remainingSeconds.toString().padStart(2, "0")}`;
|
|
36
|
+
};
|
|
37
|
+
const totalTime = useMemo(() => {
|
|
38
|
+
if (!order.expiredAt)
|
|
39
|
+
return 15 * 60; // fallback to 15 minutes
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
const expiredAt = new Date(order.expiredAt).getTime();
|
|
42
|
+
const createdAt = order.createdAt ? new Date(order.createdAt).getTime() : now;
|
|
43
|
+
return Math.max(0, Math.floor((expiredAt - createdAt) / 1000));
|
|
44
|
+
}, [order.expiredAt, order.createdAt]);
|
|
45
|
+
const roundedUpSrcAmount = useMemo(() => {
|
|
46
|
+
// Display the full transfer amount without rounding since users need to see the exact value they're transferring.
|
|
47
|
+
// Use 21 significant digits (max allowed by Intl.NumberFormat)
|
|
48
|
+
const formattedSrcAmount = srcToken
|
|
49
|
+
? formatTokenAmount(BigInt(order.srcAmount), srcToken.decimals, 21, false)
|
|
50
|
+
: undefined;
|
|
51
|
+
// Simple function to round up the amount (you may need to implement this based on your utils)
|
|
52
|
+
return formattedSrcAmount;
|
|
53
|
+
}, [order.srcAmount, srcToken]);
|
|
54
|
+
const expectedDstAmount = order.type === "mint_nft" ||
|
|
55
|
+
order.type === "join_tournament" ||
|
|
56
|
+
order.type === "fund_tournament" ||
|
|
57
|
+
order.type === "custom"
|
|
58
|
+
? "0"
|
|
59
|
+
: order.payload.expectedDstAmount.toString();
|
|
60
|
+
const formattedExpectedDstAmount = formatTokenAmount(BigInt(expectedDstAmount), dstToken.decimals);
|
|
61
|
+
const handleCopyAddress = () => {
|
|
62
|
+
navigator.clipboard.writeText(order.globalAddress);
|
|
63
|
+
toast.success("Deposit address copied to clipboard");
|
|
64
|
+
};
|
|
65
|
+
return (_jsxs("div", { className: "flex w-full flex-col gap-6", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("button", { onClick: onBack, className: "text-as-primary/60 hover:text-as-primary flex h-10 w-10 items-center justify-center rounded-full transition-colors", children: _jsx(ChevronLeft, { size: 24, className: "text-as-quaternary" }) }), _jsx("h2", { className: "text-as-primary text-lg font-semibold", children: "Transfer crypto" }), _jsxs("div", { className: "relative flex h-11 w-11 items-center justify-center", children: [_jsxs("svg", { className: "h-11 w-11 -rotate-90", viewBox: "0 0 44 44", children: [_jsx("circle", { cx: "22", cy: "22", r: "18", stroke: "currentColor", strokeWidth: "3", fill: "none", className: "text-gray-200" }), _jsx("circle", { cx: "22", cy: "22", r: "18", stroke: "currentColor", strokeWidth: "3", fill: "none", strokeLinecap: "round", className: "text-blue-500", strokeDasharray: `${2 * Math.PI * 18}`, strokeDashoffset: `${2 * Math.PI * 18 * (1 - timeLeft / totalTime)}`, style: {
|
|
66
|
+
transition: "stroke-dashoffset 1s linear",
|
|
67
|
+
} })] }), _jsx("div", { className: "absolute inset-0 flex items-center justify-center", children: _jsx("span", { className: "text-as-primary text-[10px] font-semibold", children: formatTime(timeLeft) }) })] })] }), _jsxs("div", { className: "flex w-full flex-col gap-4", children: [_jsxs("div", { className: "flex items-center gap-4", children: [_jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Amount" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsx(CopyToClipboard, { text: roundedUpSrcAmount || "", onCopy: () => {
|
|
68
|
+
toast.success("Amount copied to clipboard");
|
|
69
|
+
}, children: _jsxs("div", { className: "flex cursor-pointer items-center justify-between gap-2", children: [_jsxs("strong", { className: "text-as-primary font-semibold", children: [roundedUpSrcAmount, " ", srcToken.symbol] }), _jsx(Copy, { className: "text-as-primary/50 hover:text-as-primary h-4 w-4 transition-all duration-200" })] }) }) })] }), _jsxs("div", { className: "w-full", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Chain" }), _jsx("div", { className: "border-as-border-primary rounded-lg border p-2 shadow-sm", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("img", { src: ALL_CHAINS[order.srcChain].logoUrl, alt: getChainName(order.srcChain), className: cn("h-6 rounded-full", order.srcChain === b3.id && "h-5 rounded-none") }), _jsx("span", { className: "text-as-primary text-sm font-semibold", children: getChainName(order.srcChain) })] }) })] })] }), _jsxs("div", { className: "border-b3-react-border bg-as-surface-secondary grid h-[220px] grid-cols-2 overflow-hidden rounded-xl border", children: [_jsx("div", { className: "border-as-border-primary h-full w-full border-r", children: _jsx("div", { className: "flex justify-center", children: _jsxs("div", { className: "bg-as-surface-secondary flex flex-col items-center rounded-lg p-6", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? "ETH" : order.srcTokenAddress), className: "bg-as-surface-secondary max-h-48 max-w-48" }), _jsxs("div", { className: "mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "text-as-brand/70 text-sm font-medium", children: "SCAN WITH" }), _jsxs(TextLoop, { interval: 3, children: [_jsx(WalletMetamask, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletCoinbase, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletPhantom, { className: "h-5 w-5", variant: "branded" }), _jsx(WalletTrust, { className: "h-5 w-5", variant: "branded" })] })] })] }) }) }), _jsxs("div", { className: "flex h-full w-full flex-col gap-2 p-6", children: [_jsx("span", { className: "text-as-content-secondary text-sm font-medium", children: "Deposit address:" }), _jsxs("div", { className: "flex h-full cursor-pointer flex-col items-stretch justify-between gap-4", onClick: handleCopyAddress, children: [_jsx("div", { className: "text-as-primary break-all font-mono text-sm font-semibold leading-relaxed", children: order.globalAddress }), _jsx("div", { className: "place-self-end", children: _jsx(Copy, { className: "group-hover:text-as-brand text-as-tertiarry h-4 w-4 cursor-pointer transition-all duration-200" }) })] })] })] }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })] }), _jsx("div", { className: "flex flex-col gap-3", children: _jsx(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "w-full py-3", onClick: handleCopyAddress, children: "Copy deposit address" }) })] }));
|
|
70
|
+
});
|
|
@@ -10,11 +10,14 @@ export { AnySpendTournament } from "./AnySpendTournament";
|
|
|
10
10
|
export { AnySpendNFTButton } from "./common/AnySpendNFTButton";
|
|
11
11
|
export { ChainTokenIcon } from "./common/ChainTokenIcon";
|
|
12
12
|
export { OrderDetails } from "./common/OrderDetails";
|
|
13
|
+
export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible";
|
|
13
14
|
export { OrderHistory } from "./common/OrderHistory";
|
|
14
15
|
export { OrderHistoryItem } from "./common/OrderHistoryItem";
|
|
15
16
|
export { OrderStatus } from "./common/OrderStatus";
|
|
16
17
|
export { OrderToken } from "./common/OrderToken";
|
|
17
18
|
export { OrderTokenAmount } from "./common/OrderTokenAmount";
|
|
19
|
+
export { StepProgress } from "./common/StepProgress";
|
|
18
20
|
export { TokenBalance } from "./common/TokenBalance";
|
|
21
|
+
export { TransferCryptoDetails } from "./common/TransferCryptoDetails";
|
|
19
22
|
export { WebviewOnrampOrderStatus } from "./webview/WebviewOnrampOrderStatus";
|
|
20
23
|
export { WebviewOnrampPayment } from "./webview/WebviewOnrampPayment";
|
|
@@ -12,11 +12,14 @@ export { AnySpendNFTButton } from "./common/AnySpendNFTButton.js";
|
|
|
12
12
|
// Common Components
|
|
13
13
|
export { ChainTokenIcon } from "./common/ChainTokenIcon.js";
|
|
14
14
|
export { OrderDetails } from "./common/OrderDetails.js";
|
|
15
|
+
export { OrderDetailsCollapsible } from "./common/OrderDetailsCollapsible.js";
|
|
15
16
|
export { OrderHistory } from "./common/OrderHistory.js";
|
|
16
17
|
export { OrderHistoryItem } from "./common/OrderHistoryItem.js";
|
|
17
18
|
export { OrderStatus } from "./common/OrderStatus.js";
|
|
18
19
|
export { OrderToken } from "./common/OrderToken.js";
|
|
19
20
|
export { OrderTokenAmount } from "./common/OrderTokenAmount.js";
|
|
21
|
+
export { StepProgress } from "./common/StepProgress.js";
|
|
20
22
|
export { TokenBalance } from "./common/TokenBalance.js";
|
|
23
|
+
export { TransferCryptoDetails } from "./common/TransferCryptoDetails.js";
|
|
21
24
|
export { WebviewOnrampOrderStatus } from "./webview/WebviewOnrampOrderStatus.js";
|
|
22
25
|
export { WebviewOnrampPayment } from "./webview/WebviewOnrampPayment.js";
|
|
@@ -85,18 +85,9 @@ function StripePaymentForm({ order, onPaymentSuccess, }) {
|
|
|
85
85
|
} }) })), error && (_jsx("div", { className: "mt-4 rounded-lg border border-red-200 bg-red-50 p-3 text-sm text-red-600", children: error })), _jsx("button", { type: "submit", disabled: !stripe || isProcessing, className: "mt-6 w-full rounded-xl bg-blue-600 px-4 py-3 font-medium text-white hover:bg-blue-700 disabled:cursor-not-allowed disabled:opacity-50", children: isProcessing ? (_jsxs("div", { className: "flex items-center justify-center gap-2", children: [_jsx(Loader2, { className: "h-5 w-5 animate-spin" }), _jsx("span", { children: "Processing..." })] })) : (_jsx("span", { children: "Complete Payment" })) })] }) }) }));
|
|
86
86
|
}
|
|
87
87
|
function WebviewOnrampPaymentInner({ srcAmountOnRamp, recipientAddress, destinationToken, anyspendQuote, onPaymentSuccess, userId, partnerId, }) {
|
|
88
|
-
const [stableAmountForGeo, setStableAmountForGeo] = useState(srcAmountOnRamp);
|
|
89
|
-
const hasInitialized = useRef(false);
|
|
90
88
|
const [createdOrder, setCreatedOrder] = useState(null);
|
|
91
89
|
const orderCreationAttempted = useRef(false);
|
|
92
|
-
|
|
93
|
-
useEffect(() => {
|
|
94
|
-
if (!hasInitialized.current && srcAmountOnRamp) {
|
|
95
|
-
setStableAmountForGeo(srcAmountOnRamp);
|
|
96
|
-
hasInitialized.current = true;
|
|
97
|
-
}
|
|
98
|
-
}, [srcAmountOnRamp]);
|
|
99
|
-
const { geoData, stripeWeb2Support, isLoading: isLoadingGeoOnramp } = useGeoOnrampOptions(true, stableAmountForGeo);
|
|
90
|
+
const { geoData, stripeWeb2Support, isLoading: isLoadingGeoOnramp } = useGeoOnrampOptions(true, srcAmountOnRamp);
|
|
100
91
|
const { createOrder, isCreatingOrder } = useAnyspendCreateOnrampOrder({
|
|
101
92
|
onSuccess: data => {
|
|
102
93
|
setCreatedOrder(data.data);
|
|
@@ -2,5 +2,6 @@ import { components } from "../../anyspend/types/api";
|
|
|
2
2
|
export declare const getStatusDisplay: (order: components["schemas"]["Order"]) => {
|
|
3
3
|
text: string;
|
|
4
4
|
status: "processing" | "success" | "failure";
|
|
5
|
+
description?: string;
|
|
5
6
|
};
|
|
6
7
|
export declare const getErrorDisplay: (errorDetails: string) => string;
|
|
@@ -9,31 +9,44 @@ export const getStatusDisplay = (order) => {
|
|
|
9
9
|
return {
|
|
10
10
|
text: "Awaiting Payment",
|
|
11
11
|
status: "processing",
|
|
12
|
+
description: "Complete your payment securely with Stripe to move forward",
|
|
12
13
|
};
|
|
13
14
|
case "expired":
|
|
14
|
-
return {
|
|
15
|
+
return {
|
|
16
|
+
text: "Order Expired",
|
|
17
|
+
status: "failure",
|
|
18
|
+
description: "This order is no longer valid because the order expired.",
|
|
19
|
+
};
|
|
15
20
|
case "sending_token_from_vault":
|
|
16
21
|
return { text: "Sending Token", status: "processing" };
|
|
17
22
|
case "relay":
|
|
18
|
-
return {
|
|
23
|
+
return {
|
|
24
|
+
text: "Executing Order",
|
|
25
|
+
status: "processing",
|
|
26
|
+
description: "It will take approximately one minute to complete.",
|
|
27
|
+
};
|
|
19
28
|
case "executed": {
|
|
20
|
-
const text = order.type === "swap"
|
|
21
|
-
? "Swap Complete"
|
|
29
|
+
const { text, description } = order.type === "swap"
|
|
30
|
+
? { text: "Swap Complete", description: "Your swap has been completed successfully." }
|
|
22
31
|
: order.type === "mint_nft"
|
|
23
|
-
? "NFT Minted"
|
|
32
|
+
? { text: "NFT Minted", description: "Your NFT has been minted" }
|
|
24
33
|
: order.type === "join_tournament"
|
|
25
|
-
? "Tournament Joined"
|
|
34
|
+
? { text: "Tournament Joined", description: "You have joined the tournament" }
|
|
26
35
|
: order.type === "fund_tournament"
|
|
27
|
-
? "Tournament Funded"
|
|
28
|
-
: "Order Complete";
|
|
29
|
-
return { text, status: "success" };
|
|
36
|
+
? { text: "Tournament Funded", description: "You have funded the tournament" }
|
|
37
|
+
: { text: "Order Complete", description: "Your order has been completed" };
|
|
38
|
+
return { text, status: "success", description };
|
|
30
39
|
}
|
|
31
40
|
case "refunding":
|
|
32
41
|
return { text: "Order Refunding", status: "processing" };
|
|
33
42
|
case "refunded":
|
|
34
43
|
return { text: "Order Refunded", status: "failure" };
|
|
35
44
|
case "failure":
|
|
36
|
-
return {
|
|
45
|
+
return {
|
|
46
|
+
text: "Order Failure",
|
|
47
|
+
status: "failure",
|
|
48
|
+
description: "This order has failed. Please try again or contact support.",
|
|
49
|
+
};
|
|
37
50
|
default:
|
|
38
51
|
throw new Error("Invalid order status");
|
|
39
52
|
}
|
|
@@ -11,3 +11,10 @@ export declare function escapeRegExp(string: string): string;
|
|
|
11
11
|
* For example, roundUpUSDCBaseAmountToNearest("2663988") = "2670000"
|
|
12
12
|
*/
|
|
13
13
|
export declare function roundUpUSDCBaseAmountToNearest(value: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Round up a USD amount to the nearest multiple of 0.01 USD
|
|
16
|
+
* @param value - The USD amount to round up
|
|
17
|
+
* @returns The rounded USD amount
|
|
18
|
+
* For example, roundUpUsdAmountToNearest("2.663988") = "2.67"
|
|
19
|
+
*/
|
|
20
|
+
export declare function roundUpUsdAmountToNearest(value: string): string;
|
|
@@ -77,3 +77,20 @@ export function roundUpUSDCBaseAmountToNearest(value) {
|
|
|
77
77
|
const res = srcAmountBig.plus(divisor.minus(remainder)).toString();
|
|
78
78
|
return res;
|
|
79
79
|
}
|
|
80
|
+
/**
|
|
81
|
+
* Round up a USD amount to the nearest multiple of 0.01 USD
|
|
82
|
+
* @param value - The USD amount to round up
|
|
83
|
+
* @returns The rounded USD amount
|
|
84
|
+
* For example, roundUpUsdAmountToNearest("2.663988") = "2.67"
|
|
85
|
+
*/
|
|
86
|
+
export function roundUpUsdAmountToNearest(value) {
|
|
87
|
+
const divisor = new Big(0.01); // Round to nearest 0.01 USD
|
|
88
|
+
const srcAmountBig = new Big(value);
|
|
89
|
+
const remainder = srcAmountBig.mod(divisor);
|
|
90
|
+
// If remainder is already 0 (exactly divisible by 0.01), return the original amount
|
|
91
|
+
if (remainder.eq(0)) {
|
|
92
|
+
return value;
|
|
93
|
+
}
|
|
94
|
+
const res = srcAmountBig.plus(divisor.minus(remainder)).toString();
|
|
95
|
+
return res;
|
|
96
|
+
}
|