@b3dotfun/sdk 0.0.49 → 0.0.50-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/constants/index.d.ts +1 -0
- package/dist/cjs/anyspend/constants/index.js +12 -2
- package/dist/cjs/anyspend/react/components/AnySpend.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/AnySpend.js +18 -5
- package/dist/cjs/anyspend/react/components/AnySpendCustom.js +12 -3
- package/dist/cjs/anyspend/react/components/AnyspendDepositHype.js +11 -4
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/common/CryptoPaySection.js +2 -2
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
- package/dist/cjs/anyspend/react/components/common/CryptoReceiveSection.js +17 -11
- package/dist/cjs/anyspend/react/components/common/FeeBreakDown.d.ts +12 -0
- package/dist/cjs/anyspend/react/components/common/FeeBreakDown.js +19 -0
- package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.d.ts +8 -0
- package/dist/cjs/anyspend/react/components/common/FeeDetailPanel.js +116 -0
- package/dist/cjs/anyspend/react/components/common/OrderDetails.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/common/OrderDetails.js +6 -6
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +1 -0
- package/dist/cjs/anyspend/react/components/common/OrderDetailsCollapsible.js +3 -2
- package/dist/cjs/anyspend/react/components/common/OrderToken.js +1 -1
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmount.js +1 -1
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmountFiat.js +1 -1
- package/dist/cjs/anyspend/react/components/common/OrderTokenAmountNew.js +1 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/cjs/anyspend/react/components/common/PanelOnramp.js +36 -21
- package/dist/cjs/anyspend/react/components/common/PanelOnrampPayment.js +2 -1
- package/dist/cjs/anyspend/react/components/common/PointsDetailPanel.js +1 -2
- package/dist/cjs/anyspend/react/contexts/FeatureFlagsContext.js +1 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.d.ts +3 -1
- package/dist/cjs/anyspend/react/hooks/useAnyspendFlow.js +1 -0
- package/dist/cjs/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +48 -12
- package/dist/cjs/anyspend/types/api.d.ts +133 -178
- package/dist/cjs/anyspend/utils/chain.js +4 -4
- package/dist/cjs/bondkit/bondkitToken.d.ts +3 -1
- package/dist/cjs/bondkit/bondkitToken.js +19 -0
- package/dist/cjs/bondkit/components/TradingView.d.ts +1 -1
- package/dist/cjs/bondkit/components/TradingView.js +14 -3
- package/dist/cjs/bondkit/components/index.d.ts +1 -1
- package/dist/cjs/bondkit/components/index.js +1 -1
- package/dist/cjs/bondkit/components/types.d.ts +1 -0
- package/dist/cjs/bondkit/config.d.ts +1 -0
- package/dist/cjs/bondkit/config.js +1 -0
- package/dist/cjs/bondkit/index.d.ts +1 -1
- package/dist/cjs/bondkit/index.js +2 -6
- package/dist/cjs/bondkit/types.d.ts +15 -0
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.d.ts +1 -1
- package/dist/cjs/global-account/react/components/B3Provider/B3Provider.js +1 -1
- package/dist/cjs/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +2 -2
- package/dist/cjs/global-account/react/components/ui/tooltip.js +1 -1
- package/dist/cjs/global-account/react/hooks/useAuthentication.js +11 -0
- package/dist/cjs/global-account/react/hooks/useFirstEOA.d.ts +7663 -1
- package/dist/cjs/global-account/react/hooks/useFirstEOA.js +21 -1
- package/dist/cjs/shared/generated/chain-networks.json +40 -7
- package/dist/esm/anyspend/constants/index.d.ts +1 -0
- package/dist/esm/anyspend/constants/index.js +11 -1
- package/dist/esm/anyspend/react/components/AnySpend.d.ts +2 -1
- package/dist/esm/anyspend/react/components/AnySpend.js +18 -5
- package/dist/esm/anyspend/react/components/AnySpendCustom.js +14 -5
- package/dist/esm/anyspend/react/components/AnyspendDepositHype.js +11 -4
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.d.ts +3 -1
- package/dist/esm/anyspend/react/components/common/CryptoPaySection.js +4 -4
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
- package/dist/esm/anyspend/react/components/common/CryptoReceiveSection.js +19 -13
- package/dist/esm/anyspend/react/components/common/FeeBreakDown.d.ts +12 -0
- package/dist/esm/anyspend/react/components/common/FeeBreakDown.js +16 -0
- package/dist/esm/anyspend/react/components/common/FeeDetailPanel.d.ts +8 -0
- package/dist/esm/anyspend/react/components/common/FeeDetailPanel.js +113 -0
- package/dist/esm/anyspend/react/components/common/OrderDetails.d.ts +1 -0
- package/dist/esm/anyspend/react/components/common/OrderDetails.js +6 -6
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +1 -0
- package/dist/esm/anyspend/react/components/common/OrderDetailsCollapsible.js +4 -3
- package/dist/esm/anyspend/react/components/common/OrderToken.js +1 -1
- package/dist/esm/anyspend/react/components/common/OrderTokenAmount.js +1 -1
- package/dist/esm/anyspend/react/components/common/OrderTokenAmountFiat.js +1 -1
- package/dist/esm/anyspend/react/components/common/OrderTokenAmountNew.js +1 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/esm/anyspend/react/components/common/PanelOnramp.js +38 -23
- package/dist/esm/anyspend/react/components/common/PanelOnrampPayment.js +2 -1
- package/dist/esm/anyspend/react/components/common/PointsDetailPanel.js +2 -3
- package/dist/esm/anyspend/react/contexts/FeatureFlagsContext.js +1 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.d.ts +3 -1
- package/dist/esm/anyspend/react/hooks/useAnyspendFlow.js +1 -0
- package/dist/esm/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +48 -12
- package/dist/esm/anyspend/types/api.d.ts +133 -178
- package/dist/esm/anyspend/utils/chain.js +4 -4
- package/dist/esm/bondkit/bondkitToken.d.ts +3 -1
- package/dist/esm/bondkit/bondkitToken.js +19 -0
- package/dist/esm/bondkit/components/TradingView.d.ts +1 -1
- package/dist/esm/bondkit/components/TradingView.js +14 -3
- package/dist/esm/bondkit/components/index.d.ts +1 -1
- package/dist/esm/bondkit/components/index.js +1 -1
- package/dist/esm/bondkit/components/types.d.ts +1 -0
- package/dist/esm/bondkit/config.d.ts +1 -0
- package/dist/esm/bondkit/config.js +1 -0
- package/dist/esm/bondkit/index.d.ts +1 -1
- package/dist/esm/bondkit/index.js +1 -1
- package/dist/esm/bondkit/types.d.ts +15 -0
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.d.ts +1 -1
- package/dist/esm/global-account/react/components/B3Provider/B3Provider.js +1 -1
- package/dist/esm/global-account/react/components/B3Provider/RelayKitProviderWrapper.js +2 -2
- package/dist/esm/global-account/react/components/ui/tooltip.js +1 -1
- package/dist/esm/global-account/react/hooks/useAuthentication.js +11 -0
- package/dist/esm/global-account/react/hooks/useFirstEOA.d.ts +7663 -1
- package/dist/esm/global-account/react/hooks/useFirstEOA.js +22 -2
- package/dist/esm/shared/generated/chain-networks.json +40 -7
- package/dist/styles/index.css +1 -1
- package/dist/types/anyspend/constants/index.d.ts +1 -0
- package/dist/types/anyspend/react/components/AnySpend.d.ts +2 -1
- package/dist/types/anyspend/react/components/common/CryptoPaySection.d.ts +3 -1
- package/dist/types/anyspend/react/components/common/CryptoReceiveSection.d.ts +3 -1
- package/dist/types/anyspend/react/components/common/FeeBreakDown.d.ts +12 -0
- package/dist/types/anyspend/react/components/common/FeeDetailPanel.d.ts +8 -0
- package/dist/types/anyspend/react/components/common/OrderDetails.d.ts +1 -0
- package/dist/types/anyspend/react/components/common/OrderDetailsCollapsible.d.ts +1 -0
- package/dist/types/anyspend/react/components/common/PanelOnramp.d.ts +2 -1
- package/dist/types/anyspend/react/hooks/useAnyspendFlow.d.ts +3 -1
- package/dist/types/anyspend/react/hooks/useAnyspendOrderHistory.d.ts +48 -12
- package/dist/types/anyspend/types/api.d.ts +133 -178
- package/dist/types/bondkit/bondkitToken.d.ts +3 -1
- package/dist/types/bondkit/components/TradingView.d.ts +1 -1
- package/dist/types/bondkit/components/index.d.ts +1 -1
- package/dist/types/bondkit/components/types.d.ts +1 -0
- package/dist/types/bondkit/config.d.ts +1 -0
- package/dist/types/bondkit/index.d.ts +1 -1
- package/dist/types/bondkit/types.d.ts +15 -0
- package/dist/types/global-account/react/components/B3Provider/B3Provider.d.ts +1 -1
- package/dist/types/global-account/react/hooks/useFirstEOA.d.ts +7663 -1
- package/package.json +4 -4
- package/src/anyspend/constants/index.ts +12 -1
- package/src/anyspend/react/components/AnySpend.tsx +33 -0
- package/src/anyspend/react/components/AnySpendCustom.tsx +69 -7
- package/src/anyspend/react/components/AnyspendDepositHype.tsx +24 -0
- package/src/anyspend/react/components/common/CryptoPaySection.tsx +14 -2
- package/src/anyspend/react/components/common/CryptoReceiveSection.tsx +31 -11
- package/src/anyspend/react/components/common/FeeBreakDown.tsx +105 -0
- package/src/anyspend/react/components/common/FeeDetailPanel.tsx +334 -0
- package/src/anyspend/react/components/common/OrderDetails.tsx +7 -0
- package/src/anyspend/react/components/common/OrderDetailsCollapsible.tsx +16 -0
- package/src/anyspend/react/components/common/OrderToken.tsx +1 -1
- package/src/anyspend/react/components/common/OrderTokenAmount.tsx +1 -1
- package/src/anyspend/react/components/common/OrderTokenAmountFiat.tsx +1 -1
- package/src/anyspend/react/components/common/OrderTokenAmountNew.tsx +1 -1
- package/src/anyspend/react/components/common/PanelOnramp.tsx +58 -27
- package/src/anyspend/react/components/common/PanelOnrampPayment.tsx +18 -6
- package/src/anyspend/react/components/common/PointsDetailPanel.tsx +1 -13
- package/src/anyspend/react/contexts/FeatureFlagsContext.tsx +2 -2
- package/src/anyspend/react/hooks/useAnyspendFlow.ts +1 -0
- package/src/anyspend/types/api.ts +135 -178
- package/src/anyspend/utils/chain.ts +4 -4
- package/src/bondkit/bondkitToken.ts +24 -0
- package/src/bondkit/components/TradingView.tsx +15 -3
- package/src/bondkit/components/index.ts +1 -1
- package/src/bondkit/components/types.ts +1 -0
- package/src/bondkit/config.ts +2 -0
- package/src/bondkit/index.ts +1 -1
- package/src/bondkit/types.ts +19 -0
- package/src/global-account/react/components/B3Provider/B3Provider.tsx +1 -1
- package/src/global-account/react/components/B3Provider/RelayKitProviderWrapper.tsx +2 -2
- package/src/global-account/react/components/ui/tooltip.tsx +11 -9
- package/src/global-account/react/hooks/useAuthentication.ts +13 -1
- package/src/global-account/react/hooks/useFirstEOA.tsx +20 -2
- package/src/shared/generated/chain-networks.json +40 -7
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { formatUsername } from "../../../../shared/utils/index.js";
|
|
3
3
|
import { cn } from "../../../../shared/utils/cn.js";
|
|
4
4
|
import { shortenAddress } from "../../../../shared/utils/formatAddress.js";
|
|
5
5
|
import { formatDisplayNumber } from "../../../../shared/utils/number.js";
|
|
6
|
-
import { ChevronRight } from "lucide-react";
|
|
6
|
+
import { ChevronRight, Info } from "lucide-react";
|
|
7
7
|
import { motion } from "motion/react";
|
|
8
8
|
import { useFeatureFlags } from "../../contexts/FeatureFlagsContext.js";
|
|
9
9
|
import { OrderTokenAmount } from "./OrderTokenAmount.js";
|
|
10
10
|
import { PointsBadge } from "./PointsBadge.js";
|
|
11
|
-
export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, }) {
|
|
11
|
+
export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false, selectedRecipientAddress, recipientName, onSelectRecipient, dstAmount, dstToken, selectedDstChainId, setSelectedDstChainId, setSelectedDstToken, isSrcInputDirty, onChangeDstAmount, anyspendQuote, dstTokenSymbol, dstTokenLogoURI, onShowPointsDetail, onShowFeeDetail, }) {
|
|
12
12
|
const featureFlags = useFeatureFlags();
|
|
13
|
-
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex w-full items-center justify-between", children: [
|
|
13
|
+
return (_jsxs(motion.div, { initial: { opacity: 0, y: 20, filter: "blur(10px)" }, animate: { opacity: 1, y: 0, filter: "blur(0px)" }, transition: { duration: 0.3, delay: 0.1, ease: "easeInOut" }, className: "receive-section bg-as-surface-secondary border-as-border-secondary relative flex w-full flex-col gap-2 rounded-2xl border p-4 sm:p-6", children: [_jsxs("div", { className: "flex w-full items-center justify-between", children: [_jsxs("div", { className: "text-as-primary/50 flex h-7 items-center gap-1.5 text-sm", children: [isDepositMode ? "Deposit" : "Receive", isSrcInputDirty && anyspendQuote?.data?.fee && onShowFeeDetail && (_jsx("button", { onClick: onShowFeeDetail, className: "text-as-primary/40 hover:text-as-primary/60 transition-colors", children: _jsx(Info, { className: "h-4 w-4" }) }))] }), selectedRecipientAddress ? (_jsx("button", { className: cn("text-as-tertiarry flex h-7 items-center gap-2 rounded-lg"), onClick: onSelectRecipient, children: _jsxs(_Fragment, { children: [_jsx("span", { className: "text-as-tertiarry flex items-center gap-1 text-sm", children: recipientName ? formatUsername(recipientName) : shortenAddress(selectedRecipientAddress || "") }), _jsx(ChevronRight, { className: "h-4 w-4" })] }) })) : (_jsx("button", { className: "text-as-primary/70 flex items-center gap-1 rounded-lg", onClick: onSelectRecipient, children: _jsx("div", { className: "text-sm font-medium", children: "Select recipient" }) }))] }), isBuyMode || isDepositMode ? (
|
|
14
14
|
// Fixed destination token display for buy mode and deposit mode
|
|
15
15
|
_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("div", { className: "text-as-primary text-2xl font-bold", children: dstAmount || "0" }), _jsxs("div", { className: "bg-as-brand/10 border-as-brand/30 flex items-center gap-3 rounded-xl border px-4 py-3", children: [(dstTokenLogoURI || dstToken.metadata?.logoURI) && (_jsx("img", { src: dstTokenLogoURI || dstToken.metadata?.logoURI, alt: dstTokenSymbol || dstToken.symbol, className: "h-8 w-8 rounded-full" })), _jsx("span", { className: "text-as-brand text-lg font-bold", children: dstTokenSymbol || dstToken.symbol })] })] })) : (
|
|
16
16
|
// Token selection for regular swap mode
|
|
@@ -22,32 +22,38 @@ export function CryptoReceiveSection({ isDepositMode = false, isBuyMode = false,
|
|
|
22
22
|
(() => {
|
|
23
23
|
const calculatePriceImpact = (inputUsd, outputUsd) => {
|
|
24
24
|
if (!inputUsd || !outputUsd) {
|
|
25
|
-
return { percentage: "0.00", isNegative: false };
|
|
25
|
+
return { percentage: "0.00", percentageNum: 0, isNegative: false };
|
|
26
26
|
}
|
|
27
27
|
const input = Number(inputUsd);
|
|
28
28
|
const output = Number(outputUsd);
|
|
29
29
|
// Handle edge cases
|
|
30
30
|
if (input === 0 || isNaN(input) || isNaN(output) || input <= output) {
|
|
31
|
-
return { percentage: "0.00", isNegative: false };
|
|
31
|
+
return { percentage: "0.00", percentageNum: 0, isNegative: false };
|
|
32
32
|
}
|
|
33
33
|
const percentageValue = ((output - input) / input) * 100;
|
|
34
34
|
// Handle the -0.00% case
|
|
35
35
|
if (percentageValue > -0.005 && percentageValue < 0) {
|
|
36
|
-
return { percentage: "0.00", isNegative: false };
|
|
36
|
+
return { percentage: "0.00", percentageNum: 0, isNegative: false };
|
|
37
37
|
}
|
|
38
38
|
return {
|
|
39
39
|
percentage: Math.abs(percentageValue).toFixed(2),
|
|
40
|
+
percentageNum: Math.abs(percentageValue),
|
|
40
41
|
isNegative: percentageValue < 0,
|
|
41
42
|
};
|
|
42
43
|
};
|
|
43
|
-
const { percentage, isNegative } = calculatePriceImpact(anyspendQuote.data.currencyIn.amountUsd, anyspendQuote.data.currencyOut.amountUsd);
|
|
44
|
-
//
|
|
45
|
-
const
|
|
46
|
-
//
|
|
47
|
-
|
|
44
|
+
const { percentage, percentageNum, isNegative } = calculatePriceImpact(anyspendQuote.data.currencyIn.amountUsd, anyspendQuote.data.currencyOut.amountUsd);
|
|
45
|
+
// Get the fee percentage if available
|
|
46
|
+
const feePercent = anyspendQuote.data.fee?.finalFeeBps ? anyspendQuote.data.fee.finalFeeBps / 100 : 0;
|
|
47
|
+
// Calculate actual slippage (price impact minus fee)
|
|
48
|
+
const actualSlippage = percentageNum - feePercent;
|
|
49
|
+
// Show warning based on actual slippage, not total impact
|
|
50
|
+
const yellowThreshold = 1; // 1% actual slippage
|
|
51
|
+
const redThreshold = 2; // 2% actual slippage
|
|
52
|
+
// Don't show if actual slippage is less than yellow threshold
|
|
53
|
+
if (actualSlippage < yellowThreshold) {
|
|
48
54
|
return null;
|
|
49
55
|
}
|
|
50
56
|
// Using inline style to ensure color displays
|
|
51
|
-
return (_jsxs("span", { className: "ml-2", style: { color:
|
|
57
|
+
return (_jsxs("span", { className: "ml-2", style: { color: actualSlippage >= redThreshold ? "red" : "#FFD700" }, children: ["(", isNegative ? "-" : "", percentage, "%)"] }));
|
|
52
58
|
})()] }), featureFlags.showPoints && anyspendQuote?.data?.pointsAmount > 0 && (_jsx(PointsBadge, { pointsAmount: anyspendQuote.data.pointsAmount, pointsMultiplier: anyspendQuote.data.pointsMultiplier, onClick: () => onShowPointsDetail?.() }))] })] }));
|
|
53
59
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { components } from "../../../types/api";
|
|
2
|
+
interface FeeBreakDownProps {
|
|
3
|
+
fee: components["schemas"]["Fee"];
|
|
4
|
+
/** Number of decimals for amount display (default: 6 for USDC) */
|
|
5
|
+
decimals?: number;
|
|
6
|
+
/** Show currency symbol for amounts (default: true) */
|
|
7
|
+
showCurrency?: boolean;
|
|
8
|
+
/** Custom className for the container */
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function FeeBreakDown({ fee, decimals, showCurrency, className }: FeeBreakDownProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
export function FeeBreakDown({ fee, decimals = 6, showCurrency = true, className = "" }) {
|
|
3
|
+
const isStripeFee = fee.type === "stripeweb2_fee";
|
|
4
|
+
// Convert basis points to percentage
|
|
5
|
+
const bpsToPercent = (bps) => (bps / 100).toFixed(2);
|
|
6
|
+
// Format amount with optional currency
|
|
7
|
+
const formatAmount = (amount) => {
|
|
8
|
+
const divisor = Math.pow(10, decimals);
|
|
9
|
+
const formatted = (Number(amount) / divisor).toFixed(2);
|
|
10
|
+
return showCurrency ? `$${formatted}` : formatted;
|
|
11
|
+
};
|
|
12
|
+
// Check if discount is active
|
|
13
|
+
const hasWhaleDiscount = fee.anyspendWhaleDiscountBps > 0;
|
|
14
|
+
const hasPartnerDiscount = fee.anyspendPartnerDiscountBps > 0;
|
|
15
|
+
return (_jsxs("div", { className: `min-w-[240px] ${className}`, children: [_jsxs("div", { className: "mb-4", children: [_jsx("h3", { className: "text-as-primary mb-2 text-sm font-semibold", children: "Fee Breakdown" }), _jsx("table", { className: "w-full", children: _jsxs("tbody", { className: "text-as-secondary text-xs", children: [isStripeFee && (_jsxs("tr", { children: [_jsx("td", { className: "py-1", children: "Stripe Fee" }), _jsxs("td", { className: "py-1 text-right", children: [bpsToPercent(fee.stripeFeeBps), "% + $", fee.stripeFeeUsd.toFixed(2)] })] })), _jsxs("tr", { children: [_jsx("td", { className: "py-1", children: "AnySpend Fee" }), _jsxs("td", { className: "py-1 text-right", children: [bpsToPercent(fee.anyspendFeeBps), "%", isStripeFee && fee.anyspendFeeUsd > 0 && ` + $${fee.anyspendFeeUsd.toFixed(2)}`] })] }), hasWhaleDiscount && (_jsxs("tr", { className: "text-green-600", children: [_jsx("td", { className: "py-1", children: "Whale Discount" }), _jsxs("td", { className: "py-1 text-right", children: ["-", bpsToPercent(fee.anyspendWhaleDiscountBps), "%"] })] })), hasPartnerDiscount && (_jsxs("tr", { className: "text-green-600", children: [_jsx("td", { className: "py-1", children: "Partner Discount" }), _jsxs("td", { className: "py-1 text-right", children: ["-", bpsToPercent(fee.anyspendPartnerDiscountBps), "%"] })] })), _jsxs("tr", { className: "border-as-border-secondary border-t", children: [_jsx("td", { className: "text-as-primary py-1.5 pt-2 font-semibold", children: "Total Fee" }), _jsxs("td", { className: "text-as-primary py-1.5 pt-2 text-right font-semibold", children: [bpsToPercent(fee.finalFeeBps), "%", isStripeFee && ` + $${fee.finalFeeUsd.toFixed(2)}`] })] })] }) })] }), isStripeFee && (_jsxs(_Fragment, { children: [_jsx("div", { className: "border-as-border-secondary my-3 border-t" }), _jsxs("div", { children: [_jsx("h3", { className: "text-as-primary mb-2 text-sm font-semibold", children: "Amount Calculation" }), _jsx("table", { className: "w-full", children: _jsxs("tbody", { className: "text-as-secondary text-xs", children: [_jsxs("tr", { children: [_jsx("td", { className: "py-1", children: "Original Amount" }), _jsx("td", { className: "py-1 text-right font-medium", children: formatAmount(fee.originalAmount) })] }), _jsxs("tr", { children: [_jsx("td", { className: "py-1", children: "Total Fee" }), _jsxs("td", { className: "py-1 text-right text-red-600", children: ["-", formatAmount((Number(fee.originalAmount) - Number(fee.finalAmount)).toString())] })] }), _jsxs("tr", { className: "border-as-border-secondary border-t", children: [_jsx("td", { className: "text-as-primary py-1.5 pt-2 font-semibold", children: "You Receive" }), _jsx("td", { className: "text-as-primary py-1.5 pt-2 text-right font-semibold", children: formatAmount(fee.finalAmount) })] })] }) })] })] }))] }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { components } from "../../../types/api";
|
|
2
|
+
interface FeeDetailPanelProps {
|
|
3
|
+
fee: components["schemas"]["Fee"];
|
|
4
|
+
transactionAmountUsd?: number;
|
|
5
|
+
onBack: () => void;
|
|
6
|
+
}
|
|
7
|
+
export declare function FeeDetailPanel({ fee, transactionAmountUsd, onBack }: FeeDetailPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { ShinyButton } from "../../../../global-account/react/index.js";
|
|
3
|
+
import { cn } from "../../../../shared/utils/cn.js";
|
|
4
|
+
import { ChevronDown } from "lucide-react";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
// Fee tier definitions
|
|
7
|
+
const CRYPTO_FEE_TIERS = [
|
|
8
|
+
{ min: 0, max: 10, bps: 120, label: "$0 – $10" },
|
|
9
|
+
{ min: 10, max: 500, bps: 80, label: "$10 – $500" },
|
|
10
|
+
{ min: 500, max: 5000, bps: 60, label: "$500 – $5,000" },
|
|
11
|
+
{ min: 5000, max: 50000, bps: 40, label: "$5,000 – $50,000" },
|
|
12
|
+
{ min: 50000, max: Infinity, bps: 28, label: "$50,000+" },
|
|
13
|
+
];
|
|
14
|
+
const FIAT_FEE_TIERS = [
|
|
15
|
+
{ min: 0.01, max: 25, fee: "$1", label: "$0.01 – $25" },
|
|
16
|
+
{ min: 25.01, max: 250, fee: "2%", label: "$25.01 – $250" },
|
|
17
|
+
{ min: 251, max: Infinity, fee: "3%", label: "$251+" },
|
|
18
|
+
];
|
|
19
|
+
// Whale discount tiers based on $ANY holdings
|
|
20
|
+
const WHALE_DISCOUNT_TIERS = [
|
|
21
|
+
{ minAny: 100000, discountPercent: 50, label: "Tier 1: 100k $ANY" },
|
|
22
|
+
{ minAny: 500000, discountPercent: 75, label: "Tier 2: 500k $ANY" },
|
|
23
|
+
{ minAny: 1000000, discountPercent: 100, label: "Tier 3: 1M+ $ANY" },
|
|
24
|
+
];
|
|
25
|
+
export function FeeDetailPanel({ fee, transactionAmountUsd, onBack }) {
|
|
26
|
+
// Detect if this is a fiat onramp order (Stripe) vs regular crypto swap
|
|
27
|
+
// stripeweb2_fee = Stripe/fiat onramp (uses FIAT_FEE_TIERS)
|
|
28
|
+
// standard_fee = Regular crypto swap (uses CRYPTO_FEE_TIERS)
|
|
29
|
+
const isStripeFee = fee.type === "stripeweb2_fee";
|
|
30
|
+
// Convert basis points to percentage
|
|
31
|
+
const bpsToPercent = (bps) => (bps / 100).toFixed(2);
|
|
32
|
+
// Check if discount is active
|
|
33
|
+
const hasWhaleDiscount = fee.anyspendWhaleDiscountBps > 0;
|
|
34
|
+
const hasPartnerDiscount = fee.anyspendPartnerDiscountBps > 0;
|
|
35
|
+
// Find current tier based on transaction amount
|
|
36
|
+
const getCurrentCryptoTier = (amount) => {
|
|
37
|
+
if (!amount)
|
|
38
|
+
return null;
|
|
39
|
+
return CRYPTO_FEE_TIERS.find(tier => amount >= tier.min && amount < tier.max);
|
|
40
|
+
};
|
|
41
|
+
const getCurrentFiatTier = (amount) => {
|
|
42
|
+
if (!amount)
|
|
43
|
+
return null;
|
|
44
|
+
return FIAT_FEE_TIERS.find(tier => amount >= tier.min && amount < tier.max);
|
|
45
|
+
};
|
|
46
|
+
const currentCryptoTier = getCurrentCryptoTier(transactionAmountUsd);
|
|
47
|
+
const currentFiatTier = getCurrentFiatTier(transactionAmountUsd);
|
|
48
|
+
// The whale discount is a percentage discount on the base fee itself
|
|
49
|
+
// Example: 50% discount on 80 bps fee = 40 bps discount, final fee = 40 bps
|
|
50
|
+
// So: finalFee = baseFee - (baseFee * discountPercent / 100)
|
|
51
|
+
// Which means: discountPercent = ((baseFee - finalFee) / baseFee) * 100
|
|
52
|
+
const baseFee = fee.type === "standard_fee" ? fee.anyspendFeeBps : 0;
|
|
53
|
+
// The whale discount percentage (50%, 75%, or 100%)
|
|
54
|
+
const whaleDiscountPercent = baseFee > 0 && hasWhaleDiscount ? Math.round(((baseFee - fee.finalFeeBps) / baseFee) * 100) : 0;
|
|
55
|
+
// Determine which whale tier based on the discount percentage
|
|
56
|
+
const currentWhaleTier = WHALE_DISCOUNT_TIERS.find(tier => Math.abs(whaleDiscountPercent - tier.discountPercent) <= 5);
|
|
57
|
+
// Calculate partner discount percentage
|
|
58
|
+
const partnerDiscountPercent = baseFee > 0 && hasPartnerDiscount ? Math.round((fee.anyspendPartnerDiscountBps / baseFee) * 100) : 0;
|
|
59
|
+
// State for expanding tier lists
|
|
60
|
+
const [showAllFeeTiers, setShowAllFeeTiers] = useState(false);
|
|
61
|
+
const [showAllDiscountTiers, setShowAllDiscountTiers] = useState(false);
|
|
62
|
+
return (_jsx("div", { className: "mx-auto flex w-[460px] max-w-full flex-col items-center gap-3", children: _jsxs("div", { className: "flex w-full flex-col gap-3", children: [_jsx("div", { className: "text-center", children: _jsx("h3", { className: "text-as-primary text-lg font-bold", children: "Fee Breakdown" }) }), _jsxs("div", { className: "bg-as-surface-secondary border-as-border-secondary rounded-2xl border p-4", children: [_jsx("h4", { className: "text-as-primary mb-3 text-sm font-semibold", children: isStripeFee ? "Fiat Fee Schedule" : "Base Fee Schedule" }), _jsx("div", { className: "space-y-1.5", children: isStripeFee
|
|
63
|
+
? FIAT_FEE_TIERS.map((tier, idx) => {
|
|
64
|
+
const isCurrentTier = currentFiatTier?.label === tier.label;
|
|
65
|
+
const currentTierIndex = FIAT_FEE_TIERS.findIndex(t => t.label === currentFiatTier?.label);
|
|
66
|
+
// Show all tiers if expanded, otherwise show up to current tier
|
|
67
|
+
if (!showAllFeeTiers && currentTierIndex !== -1 && idx > currentTierIndex) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
return (_jsxs("div", { className: cn("flex items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors", isCurrentTier ? "bg-as-brand/10 text-as-brand font-semibold" : "text-as-primary/60"), children: [_jsx("span", { children: tier.label }), _jsxs("span", { children: ["Credit Card Fee + ", tier.fee] })] }, idx));
|
|
71
|
+
})
|
|
72
|
+
: CRYPTO_FEE_TIERS.map((tier, idx) => {
|
|
73
|
+
const isCurrentTier = currentCryptoTier?.label === tier.label;
|
|
74
|
+
const currentTierIndex = CRYPTO_FEE_TIERS.findIndex(t => t.label === currentCryptoTier?.label);
|
|
75
|
+
// Show all tiers if expanded, otherwise show up to current tier
|
|
76
|
+
if (!showAllFeeTiers && currentTierIndex !== -1 && idx > currentTierIndex) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return (_jsxs("div", { className: cn("flex items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors", isCurrentTier ? "bg-as-brand/10 text-as-brand font-semibold" : "text-as-primary/60"), children: [_jsx("span", { children: tier.label }), _jsxs("span", { children: [bpsToPercent(tier.bps), "%"] })] }, idx));
|
|
80
|
+
}) }), (() => {
|
|
81
|
+
const currentTierIndex = isStripeFee
|
|
82
|
+
? FIAT_FEE_TIERS.findIndex(t => t.label === currentFiatTier?.label)
|
|
83
|
+
: CRYPTO_FEE_TIERS.findIndex(t => t.label === currentCryptoTier?.label);
|
|
84
|
+
const totalTiers = isStripeFee ? FIAT_FEE_TIERS.length : CRYPTO_FEE_TIERS.length;
|
|
85
|
+
const hasMoreTiers = currentTierIndex !== -1 && currentTierIndex < totalTiers - 1;
|
|
86
|
+
if (hasMoreTiers) {
|
|
87
|
+
return (_jsxs("button", { onClick: () => setShowAllFeeTiers(!showAllFeeTiers), className: "text-as-primary/60 hover:text-as-primary mt-2 flex w-full items-center justify-center gap-1 text-xs transition-colors", children: [_jsx("span", { children: showAllFeeTiers ? "Show less" : "Show higher tiers" }), _jsx(ChevronDown, { className: cn("h-3.5 w-3.5 transition-transform", showAllFeeTiers && "rotate-180") })] }));
|
|
88
|
+
}
|
|
89
|
+
return null;
|
|
90
|
+
})()] }), !isStripeFee && (_jsxs("div", { className: "bg-as-surface-secondary border-as-border-secondary rounded-2xl border p-4", children: [_jsx("h4", { className: "text-as-primary mb-3 text-sm font-semibold", children: hasWhaleDiscount ? "Whale Discount Tiers" : hasPartnerDiscount ? "Partner Discount" : "Discount Tiers" }), _jsx("div", { className: "space-y-1.5", children: hasPartnerDiscount && !hasWhaleDiscount ? (_jsxs("div", { className: "flex items-center justify-between rounded-lg bg-green-500/10 px-3 py-2.5 text-sm font-semibold text-green-600", children: [_jsx("span", { children: "Partner Discount" }), _jsxs("span", { children: [partnerDiscountPercent, "% discount"] })] })) : (_jsxs(_Fragment, { children: [WHALE_DISCOUNT_TIERS.map((tier, idx) => {
|
|
91
|
+
const isCurrentTier = currentWhaleTier?.label === tier.label;
|
|
92
|
+
const currentTierIndex = WHALE_DISCOUNT_TIERS.findIndex(t => t.label === currentWhaleTier?.label);
|
|
93
|
+
// If no whale discount, show only first tier; otherwise show up to current tier
|
|
94
|
+
if (!showAllDiscountTiers) {
|
|
95
|
+
if (!hasWhaleDiscount && idx > 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
if (hasWhaleDiscount && currentTierIndex !== -1 && idx > currentTierIndex) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return (_jsxs("div", { className: cn("flex items-center justify-between rounded-lg px-3 py-2.5 text-sm transition-colors", isCurrentTier ? "bg-green-500/10 font-semibold text-green-600" : "text-as-primary/60"), children: [_jsx("span", { children: tier.label }), _jsxs("span", { children: [tier.discountPercent, "% discount"] })] }, idx));
|
|
103
|
+
}), (() => {
|
|
104
|
+
const currentTierIndex = WHALE_DISCOUNT_TIERS.findIndex(t => t.label === currentWhaleTier?.label);
|
|
105
|
+
const hasMoreTiers = hasWhaleDiscount
|
|
106
|
+
? currentTierIndex !== -1 && currentTierIndex < WHALE_DISCOUNT_TIERS.length - 1
|
|
107
|
+
: WHALE_DISCOUNT_TIERS.length > 1;
|
|
108
|
+
if (hasMoreTiers) {
|
|
109
|
+
return (_jsxs("button", { onClick: () => setShowAllDiscountTiers(!showAllDiscountTiers), className: "text-as-primary/60 hover:text-as-primary mt-2 flex w-full items-center justify-center gap-1 text-xs transition-colors", children: [_jsx("span", { children: showAllDiscountTiers ? "Show less" : "Show all tiers" }), _jsx(ChevronDown, { className: cn("h-3.5 w-3.5 transition-transform", showAllDiscountTiers && "rotate-180") })] }));
|
|
110
|
+
}
|
|
111
|
+
return null;
|
|
112
|
+
})()] })) })] })), transactionAmountUsd && (_jsx("div", { className: "bg-as-surface-secondary border-as-border-secondary rounded-2xl border p-4", children: _jsxs("div", { className: "space-y-2 text-sm", children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-secondary", children: "Transaction" }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", transactionAmountUsd.toFixed(2)] })] }), isStripeFee && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-as-secondary", children: ["Credit Card Fee (", fee.stripeFeeBps ? `${bpsToPercent(fee.stripeFeeBps)}%` : "0%", " + $", fee.stripeFeeUsd?.toFixed(2) || "0.00", ")"] }), _jsxs("span", { className: "text-as-primary font-medium", children: ["$", ((transactionAmountUsd * (fee.stripeFeeBps || 0)) / 10000 + (fee.stripeFeeUsd || 0)).toFixed(2)] })] }), _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-as-secondary", children: ["AnySpend Fee (", fee.anyspendFeeBps ? `${bpsToPercent(fee.anyspendFeeBps)}%` : "0%", fee.anyspendFeeUsd && fee.anyspendFeeUsd > 0 ? ` + $${fee.anyspendFeeUsd.toFixed(2)}` : "", ")"] }), _jsxs("span", { className: "text-as-primary font-medium", children: ["$", ((transactionAmountUsd * (fee.anyspendFeeBps || 0)) / 10000 + (fee.anyspendFeeUsd || 0)).toFixed(2)] })] }), _jsx("div", { className: "border-as-border-secondary border-t pt-2", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-primary font-semibold", children: "Total Fee" }), _jsxs("span", { className: "text-as-brand font-semibold", children: ["$", ((transactionAmountUsd * (fee.finalFeeBps || 0)) / 10000 + (fee.finalFeeUsd || 0)).toFixed(2)] })] }) })] })), !isStripeFee && currentCryptoTier && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-as-secondary", children: ["Base Fee (", bpsToPercent(currentCryptoTier.bps), "%)"] }), _jsxs("span", { className: "text-as-primary font-medium", children: ["$", ((transactionAmountUsd * currentCryptoTier.bps) / 10000).toFixed(2)] })] }), hasWhaleDiscount && currentWhaleTier && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-green-600", children: ["Discount (", currentWhaleTier.discountPercent, "% off)"] }), _jsxs("span", { className: "font-medium text-green-600", children: ["-$", ((transactionAmountUsd * baseFee * currentWhaleTier.discountPercent) / 100 / 10000).toFixed(2)] })] })), hasPartnerDiscount && (_jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("span", { className: "text-green-600", children: ["Partner Discount (", partnerDiscountPercent, "% off)"] }), _jsxs("span", { className: "font-medium text-green-600", children: ["-$", ((transactionAmountUsd * baseFee * partnerDiscountPercent) / 100 / 10000).toFixed(2)] })] })), _jsx("div", { className: "border-as-border-secondary border-t pt-2", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsx("span", { className: "text-as-primary font-semibold", children: "Total Fee" }), _jsxs("span", { className: "text-as-brand font-semibold", children: ["$", ((transactionAmountUsd * fee.finalFeeBps) / 10000).toFixed(2)] })] }) })] }))] }) })), _jsxs(ShinyButton, { accentColor: "hsl(var(--as-brand))", onClick: onBack, className: cn("as-main-button !bg-as-brand relative w-full"), textClassName: cn("text-white"), children: ["Back to ", isStripeFee ? "Payment" : "Swap"] })] }) }));
|
|
113
|
+
}
|
|
@@ -12,6 +12,7 @@ interface OrderDetailsProps {
|
|
|
12
12
|
onPaymentMethodChange?: (method: CryptoPaymentMethodType) => void;
|
|
13
13
|
onBack?: () => void;
|
|
14
14
|
disableUrlParamManagement?: boolean;
|
|
15
|
+
points?: number | undefined;
|
|
15
16
|
}
|
|
16
17
|
export declare const OrderDetails: import("react").NamedExoticComponent<OrderDetailsProps>;
|
|
17
18
|
export declare const OrderDetailsLoadingView: import("react/jsx-runtime").JSX.Element;
|
|
@@ -125,7 +125,7 @@ function roundTokenAmount(amount) {
|
|
|
125
125
|
const roundedDecimalPart = digits.join("");
|
|
126
126
|
return `${wholePart}.${roundedDecimalPart}`;
|
|
127
127
|
}
|
|
128
|
-
export const OrderDetails = memo(function OrderDetails({ mode = "modal", order, depositTxs, relayTxs, executeTx, refundTxs, cryptoPaymentMethod, selectedCryptoPaymentMethod, onPaymentMethodChange, onBack, disableUrlParamManagement = false, }) {
|
|
128
|
+
export const OrderDetails = memo(function OrderDetails({ mode = "modal", order, depositTxs, relayTxs, executeTx, refundTxs, cryptoPaymentMethod, selectedCryptoPaymentMethod, onPaymentMethodChange, onBack, disableUrlParamManagement = false, points, }) {
|
|
129
129
|
const router = useRouter();
|
|
130
130
|
const searchParams = useSearchParams();
|
|
131
131
|
// Get theme from B3Provider context
|
|
@@ -411,7 +411,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
411
411
|
}
|
|
412
412
|
};
|
|
413
413
|
if (refundTxs.length > 0) {
|
|
414
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "refund-details", className: "order-details-refund-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
414
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount, points: points }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "refund-details", className: "order-details-refund-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
415
415
|
? depositTxs.map(dTx => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
416
416
|
? `Received payment`
|
|
417
417
|
: `Received ${formatTokenAmount(BigInt(dTx.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTx, isProcessing: false }, dTx.txHash)))
|
|
@@ -420,7 +420,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
420
420
|
: null] }) })] }) }), order.errorDetails && (_jsx("div", { className: "flex justify-center", children: _jsx("span", { className: "text-as-primary/50 text-center text-sm", style: { maxWidth: "40ch" }, children: getErrorDisplay(order.errorDetails) }) })), _jsx("button", { className: "order-close-button order-details-close-btn bg-as-brand flex w-full items-center justify-center gap-2 rounded-lg p-2 font-semibold text-white", onClick: mode === "page" ? handleBack : handleCloseModal, children: mode === "page" ? (_jsxs(_Fragment, { children: ["Return to Home ", _jsx(Home, { className: "ml-2 h-4 w-4" })] })) : ("Close") })] }));
|
|
421
421
|
}
|
|
422
422
|
if (executeTx) {
|
|
423
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "execute-details", className: "order-details-execute-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
423
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount, points: points }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "execute-details", className: "order-details-execute-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
424
424
|
? depositTxs.map(dTxs => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
425
425
|
? `Received payment`
|
|
426
426
|
: `Received ${formatTokenAmount(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: false }, dTxs.txHash)))
|
|
@@ -445,7 +445,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
445
445
|
}), _jsx(ExternalLink, { className: "ml-2 h-4 w-4" })] }) }) }), order.type === "join_tournament" && order.status === "executed" && (_jsxs(ShinyButton, { accentColor: "hsl(var(--as-brand))", textColor: "text-white", className: "flex w-full items-center gap-2", disabled: txLoading || isSwitchingOrExecuting, onClick: handleCloseModal, children: [_jsx("span", { className: "pl-4", children: "Continue to Tournament" }), _jsx(ChevronRight, { className: "h-4 w-4" })] })), order.status === "executed" && (_jsx("button", { className: "order-close-button order-details-close-btn bg-as-brand flex w-full items-center justify-center gap-2 rounded-lg p-2 font-semibold text-white", onClick: mode === "page" ? handleBack : handleCloseModal, children: mode === "page" ? (_jsxs(_Fragment, { children: ["Return to Home ", _jsx(Home, { className: "ml-2 h-4 w-4" })] })) : ("Close") }))] }));
|
|
446
446
|
}
|
|
447
447
|
if (relayTxs.length > 0 && relayTxs.every(tx => tx.status === "success")) {
|
|
448
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "more-details", className: "order-details-more-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "More Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
448
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount, points: points }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "more-details", className: "order-details-more-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "More Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-4", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "bg-as-border-primary absolute left-[2px] top-0 z-10 w-[3px]", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1.5, ease: "easeInOut" } }) }), depositTxs
|
|
449
449
|
? depositTxs.map(dTxs => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
450
450
|
? `Received payment`
|
|
451
451
|
: `Received ${formatTokenAmount(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: false }, dTxs.txHash)))
|
|
@@ -464,7 +464,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
464
464
|
// This boolean indicates that user finish payment, and waiting for the deposit to be confirmed. We get this from query params (waitingForDeposit=true)
|
|
465
465
|
const waitingForDeposit = new URLSearchParams(window.location.search).get("waitingForDeposit") === "true";
|
|
466
466
|
if (depositTxs?.length || waitingForDeposit) {
|
|
467
|
-
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "deposit-details", className: "order-details-deposit-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-6", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "from-as-brand/50 absolute left-[2px] top-0 z-10 w-[3px] bg-gradient-to-b from-20% via-purple-500/50 via-80% to-transparent", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1, ease: "easeInOut" } }) }), (depositTxs || []).map((dTxs, index) => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
467
|
+
return (_jsxs(_Fragment, { children: [_jsx(OrderStatus, { order: order, selectedCryptoPaymentMethod: effectiveCryptoPaymentMethod }), _jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount, points: points }), _jsx(Accordion, { type: "single", collapsible: true, className: "order-details-accordion w-full", children: _jsxs(AccordionItem, { value: "deposit-details", className: "order-details-deposit-item", children: [_jsx(AccordionTrigger, { className: "accordion-trigger", children: "Transaction Details" }), _jsx(AccordionContent, { className: "accordion-content pl-2", children: _jsxs("div", { className: "relative flex w-full flex-col gap-6", children: [_jsx("div", { className: "bg-as-surface-secondary absolute bottom-2 left-4 top-2 z-[5] w-2", children: _jsx(motion.div, { className: "from-as-brand/50 absolute left-[2px] top-0 z-10 w-[3px] bg-gradient-to-b from-20% via-purple-500/50 via-80% to-transparent", initial: { height: "0%" }, animate: { height: "100%" }, transition: { duration: 1, ease: "easeInOut" } }) }), (depositTxs || []).map((dTxs, index) => (_jsx(TransactionDetails, { title: order.onrampMetadata?.vendor === "stripe-web2"
|
|
468
468
|
? `Received payment`
|
|
469
469
|
: `Received ${formatTokenAmount(BigInt(dTxs.amount), srcToken.decimals)} ${srcToken.symbol}`, chainId: order.srcChain, tx: dTxs, isProcessing: index < (depositTxs || []).length - 1 ? false : !depositEnoughAmount }, dTxs.txHash))), statusDisplay === "failure" ? (_jsx(TransactionDetails, { title: statusText, chainId: order.srcChain, tx: null, isProcessing: false, delay: 0.5 })) : depositEnoughAmount ? (_jsx(TransactionDetails, { title: order.type === "swap"
|
|
470
470
|
? "Processing Swap"
|
|
@@ -491,7 +491,7 @@ export const OrderDetails = memo(function OrderDetails({ mode = "modal", order,
|
|
|
491
491
|
? centerTruncate(phantomWalletAddress, 6)
|
|
492
492
|
: centerTruncate(account?.address || "", 6)] })] }), _jsxs("div", { className: "flex w-full flex-col items-center gap-2", children: [_jsxs(ShinyButton, { accentColor: colorMode === "dark" ? "#ffffff" : "#000000", className: "flex w-5/6 items-center gap-2 sm:px-0", onClick: () => setShowQRCode(true), children: [_jsx("span", { className: "pl-4 text-lg md:text-sm", children: "Pay from a different wallet" }), _jsx(ChevronRight, { className: "h-4 w-4" })] }), _jsxs("div", { className: "flex items-center gap-2", 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" }), _jsx(WalletWalletConnect, { className: "h-5 w-5", variant: "branded" }), _jsx("span", { className: "label-style text-as-primary/30 text-xs", children: "& more" })] })] })] }) })) : (
|
|
493
493
|
// Default case - existing QR code flow
|
|
494
|
-
_jsx(motion.div, { initial: { opacity: 0, filter: "blur(10px)" }, animate: { opacity: 1, filter: "blur(0px)" }, transition: { duration: 0.5, ease: "easeInOut" }, className: "flex w-full items-center justify-evenly gap-4", children: _jsxs("div", { className: "order-details-qr-container mt-8 flex flex-col items-center rounded-lg bg-white p-6 pb-3", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? srcToken?.symbol || "ETH" : order.srcTokenAddress, order.srcChain, srcToken?.decimals), className: "order-details-qr-code max-w-[200px]" }), _jsxs("div", { className: "order-details-qr-wallets mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "label-style text-as-brand/70 text-sm", 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: "order-details-time-remaining flex w-full items-center justify-center gap-1 text-sm", children: [_jsx("div", { className: "text-as-primary/30 order-details-time-label", children: "Time remaining:" }), _jsx("div", { className: "text-as-primary order-details-time-value", children: depositEnoughAmount ? ("Received") : order.status === "expired" ? ("Expired") : (_jsx(TimeAgo, { date: new Date(order.expiredAt), live: true })) })] }), statusDisplay !== "processing" && (_jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount })), _jsxs("button", { className: "order-details-cancel-btn flex w-full items-center justify-center gap-2", onClick: handleBack, children: [_jsx(RefreshCcw, { className: "ml-2 h-4 w-4" }), " Cancel and start over"] })] }));
|
|
494
|
+
_jsx(motion.div, { initial: { opacity: 0, filter: "blur(10px)" }, animate: { opacity: 1, filter: "blur(0px)" }, transition: { duration: 0.5, ease: "easeInOut" }, className: "flex w-full items-center justify-evenly gap-4", children: _jsxs("div", { className: "order-details-qr-container mt-8 flex flex-col items-center rounded-lg bg-white p-6 pb-3", children: [_jsx(QRCodeSVG, { value: getPaymentUrl(order.globalAddress, BigInt(order.srcAmount), order.srcTokenAddress === RELAY_ETH_ADDRESS ? srcToken?.symbol || "ETH" : order.srcTokenAddress, order.srcChain, srcToken?.decimals), className: "order-details-qr-code max-w-[200px]" }), _jsxs("div", { className: "order-details-qr-wallets mt-3 flex items-center justify-center gap-2 text-sm", children: [_jsx("span", { className: "label-style text-as-brand/70 text-sm", 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: "order-details-time-remaining flex w-full items-center justify-center gap-1 text-sm", children: [_jsx("div", { className: "text-as-primary/30 order-details-time-label", children: "Time remaining:" }), _jsx("div", { className: "text-as-primary order-details-time-value", children: depositEnoughAmount ? ("Received") : order.status === "expired" ? ("Expired") : (_jsx(TimeAgo, { date: new Date(order.expiredAt), live: true })) })] }), statusDisplay !== "processing" && (_jsx(OrderDetailsCollapsible, { order: order, dstToken: dstToken, tournament: tournament, nft: nft, recipientName: recipientName, formattedExpectedDstAmount: formattedExpectedDstAmount, points: points })), _jsxs("button", { className: "order-details-cancel-btn flex w-full items-center justify-center gap-2", onClick: handleBack, children: [_jsx(RefreshCcw, { className: "ml-2 h-4 w-4" }), " Cancel and start over"] })] }));
|
|
495
495
|
});
|
|
496
496
|
function TransactionDetails({ title, chainId, tx, isProcessing, delay, }) {
|
|
497
497
|
return (_jsxs("div", { className: "order-details-transaction-item relative flex w-full flex-1 items-center justify-between gap-4", children: [_jsxs("div", { className: "order-details-transaction-content flex grow items-center gap-4", children: [_jsx(motion.div, { className: "bg-as-surface-secondary relative h-10 w-10 rounded-full", children: isProcessing ? (_jsx(motion.div, { initial: { opacity: 0, scale: 0.3 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeInOut", delay }, className: "border-as-border-secondary absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full border-2 shadow-lg backdrop-blur-sm", children: _jsx(Loader2, { className: "text-as-primary h-4 w-4 animate-spin" }) })) : (_jsx(motion.div, { initial: { opacity: 0, scale: 0.3 }, animate: { opacity: 1, scale: 1 }, transition: { duration: 0.5, ease: "easeOut", delay }, className: "bg-as-success-secondary absolute z-10 m-2 flex h-6 w-6 items-center justify-center rounded-full border border-white/30 shadow-lg backdrop-blur-sm", children: _jsx(CheckIcon, { className: "text-as-content-icon-success h-4 w-4" }) })) }), _jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.3, ease: "easeInOut", delay }, className: "shrink-0 text-base", children: isProcessing ? (_jsx(TextShimmer, { duration: 1, children: title })) : (_jsx("span", { className: "text-as-primary", children: title })) })] }), _jsx("div", { className: "flex flex-col gap-1", children: tx ? (_jsx(motion.div, { initial: { opacity: 0 }, animate: { opacity: 1 }, transition: { duration: 0.3, ease: "easeInOut", delay: (delay || 0) + 0.3 }, className: "flex items-center gap-3", children: _jsx("a", { href: getExplorerTxUrl(chainId, tx.txHash), target: "_blank", children: _jsx("div", { className: "text-as-primary/30 font-mono text-xs", children: centerTruncate(tx?.txHash, 6) }) }) })) : null })] }));
|
|
@@ -13,6 +13,7 @@ interface OrderDetailsCollapsibleProps {
|
|
|
13
13
|
className?: string;
|
|
14
14
|
showTotal?: boolean;
|
|
15
15
|
totalAmount?: string;
|
|
16
|
+
points?: number;
|
|
16
17
|
}
|
|
17
18
|
export declare const OrderDetailsCollapsible: import("react").NamedExoticComponent<OrderDetailsCollapsibleProps>;
|
|
18
19
|
export {};
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { ALL_CHAINS, capitalizeFirstLetter, getChainName } from "../../../../anyspend/index.js";
|
|
4
4
|
import { CopyToClipboard } from "../../../../global-account/react/index.js";
|
|
5
5
|
import { cn } from "../../../../shared/utils/index.js";
|
|
6
6
|
import centerTruncate from "../../../../shared/utils/centerTruncate.js";
|
|
7
|
+
import { formatNumber } from "../../../../shared/utils/formatNumber.js";
|
|
7
8
|
import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
8
9
|
import { ChevronDown, Copy } from "lucide-react";
|
|
9
10
|
import { motion } from "motion/react";
|
|
10
11
|
import { memo, useState } from "react";
|
|
11
12
|
import { toast } from "sonner";
|
|
12
13
|
import { b3 } from "viem/chains";
|
|
13
|
-
export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({ order, dstToken, tournament, nft, recipientName, formattedExpectedDstAmount, className, showTotal = false, totalAmount, }) {
|
|
14
|
+
export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({ order, dstToken, tournament, nft, recipientName, formattedExpectedDstAmount, className, showTotal = false, totalAmount, points, }) {
|
|
14
15
|
const [showOrderDetails, setShowOrderDetails] = useState(true);
|
|
15
16
|
// Calculate expected amount if not provided
|
|
16
17
|
const expectedDstAmount = order.type === "mint_nft" ||
|
|
@@ -33,5 +34,5 @@ export const OrderDetailsCollapsible = memo(function OrderDetailsCollapsible({ o
|
|
|
33
34
|
? order.metadata.action
|
|
34
35
|
? capitalizeFirstLetter(order.metadata.action)
|
|
35
36
|
: "Contract execution"
|
|
36
|
-
: "" }), _jsxs("div", { className: "order-details-expected-value flex items-end gap-2", children: [order.type === "swap" ? (`~${finalFormattedExpectedDstAmount} ${dstToken.symbol}`) : order.type === "mint_nft" ? (_jsxs("div", { className: "order-details-nft-info flex items-center gap-2", children: [_jsx("img", { src: nft?.imageUrl, alt: nft?.name || "NFT", className: "order-details-nft-image h-5 w-5" }), _jsx("div", { className: "order-details-nft-name", children: nft?.name || "NFT" })] })) : order.type === "join_tournament" || order.type === "fund_tournament" ? (_jsxs("div", { className: "order-details-tournament-info flex items-center gap-2", children: [_jsx("img", { src: tournament?.imageUrl, alt: tournament?.name || "Tournament", className: "order-details-tournament-image h-5 w-5" }), _jsx("div", { className: "order-details-tournament-name", children: tournament?.name || "Tournament" })] })) : order.type === "hype_duel" ? (_jsx("div", { className: "order-details-hype-info flex items-center gap-2", children: _jsxs("div", { className: "order-details-hype-amount", children: [formatTokenAmount(BigInt(order.payload.expectedDstAmount), dstToken.decimals), " HYPE"] }) })) : null, _jsxs("div", { className: "order-details-chain-info text-as-primary/50 flex items-center gap-2", children: [_jsxs("span", { className: "order-details-chain-text", children: ["on ", order.dstChain !== b3.id && getChainName(order.dstChain)] }), _jsx("img", { src: ALL_CHAINS[order.dstChain].logoUrl, alt: getChainName(order.dstChain), className: cn("order-details-chain-logo h-3", order.dstChain !== b3.id && "w-3 rounded-full", order.dstChain === b3.id && "h-4") })] })] })] }), _jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-id-total-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-id-total-label text-as-tertiarry", children: showTotal ? "Total (included fee)" : "Order ID" }), _jsx("div", { className: "order-details-id-total-value text-as-primary overflow-hidden text-ellipsis whitespace-nowrap", children: showTotal && totalAmount ? totalAmount : order.id })] })] }) })) : (_jsxs("div", { className: "order-details-collapsed flex w-full items-center", children: [_jsx("div", { className: "order-details-collapsed-divider divider w-full" }), _jsx("button", { className: "order-details-collapsed-button whitespace-nowrap text-sm", onClick: () => setShowOrderDetails(true), children: "Order Details" }), _jsx(ChevronDown, { className: "order-details-collapsed-chevron text-as-primary mx-1 h-4 min-h-4 w-4 min-w-4" }), _jsx("div", { className: "order-details-collapsed-divider divider w-full" })] })) }));
|
|
37
|
+
: "" }), _jsxs("div", { className: "order-details-expected-value flex items-end gap-2", children: [order.type === "swap" ? (`~${finalFormattedExpectedDstAmount} ${dstToken.symbol}`) : order.type === "mint_nft" ? (_jsxs("div", { className: "order-details-nft-info flex items-center gap-2", children: [_jsx("img", { src: nft?.imageUrl, alt: nft?.name || "NFT", className: "order-details-nft-image h-5 w-5" }), _jsx("div", { className: "order-details-nft-name", children: nft?.name || "NFT" })] })) : order.type === "join_tournament" || order.type === "fund_tournament" ? (_jsxs("div", { className: "order-details-tournament-info flex items-center gap-2", children: [_jsx("img", { src: tournament?.imageUrl, alt: tournament?.name || "Tournament", className: "order-details-tournament-image h-5 w-5" }), _jsx("div", { className: "order-details-tournament-name", children: tournament?.name || "Tournament" })] })) : order.type === "hype_duel" ? (_jsx("div", { className: "order-details-hype-info flex items-center gap-2", children: _jsxs("div", { className: "order-details-hype-amount", children: [formatTokenAmount(BigInt(order.payload.expectedDstAmount), dstToken.decimals), " HYPE"] }) })) : null, _jsxs("div", { className: "order-details-chain-info text-as-primary/50 flex items-center gap-2", children: [_jsxs("span", { className: "order-details-chain-text", children: ["on ", order.dstChain !== b3.id && getChainName(order.dstChain)] }), _jsx("img", { src: ALL_CHAINS[order.dstChain].logoUrl, alt: getChainName(order.dstChain), className: cn("order-details-chain-logo h-3", order.dstChain !== b3.id && "w-3 rounded-full", order.dstChain === b3.id && "h-4") })] })] })] }), points !== undefined && points !== null && (_jsxs(_Fragment, { children: [_jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-points-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-points-label text-as-tertiarry", children: "Points" }), _jsxs("div", { className: "order-details-points-value text-as-brand font-semibold", children: ["+", formatNumber(points), " pts"] })] })] })), _jsx("div", { className: "order-details-divider divider w-full" }), _jsxs("div", { className: "order-details-id-total-section flex w-full justify-between gap-4", children: [_jsx("div", { className: "order-details-id-total-label text-as-tertiarry", children: showTotal ? "Total (included fee)" : "Order ID" }), _jsx("div", { className: "order-details-id-total-value text-as-primary overflow-hidden text-ellipsis whitespace-nowrap", children: showTotal && totalAmount ? totalAmount : order.id })] })] }) })) : (_jsxs("div", { className: "order-details-collapsed flex w-full items-center", children: [_jsx("div", { className: "order-details-collapsed-divider divider w-full" }), _jsx("button", { className: "order-details-collapsed-button whitespace-nowrap text-sm", onClick: () => setShowOrderDetails(true), children: "Order Details" }), _jsx(ChevronDown, { className: "order-details-collapsed-chevron text-as-primary mx-1 h-4 min-h-4 w-4 min-w-4" }), _jsx("div", { className: "order-details-collapsed-divider divider w-full" })] })) }));
|
|
37
38
|
});
|
|
@@ -5,7 +5,7 @@ import { Button, useAccountWallet, useTokenBalancesByChain } from "../../../../g
|
|
|
5
5
|
import { cn } from "../../../../shared/utils/index.js";
|
|
6
6
|
import { formatTokenAmount } from "../../../../shared/utils/number.js";
|
|
7
7
|
import { simpleHashChainToChainName } from "../../../../shared/utils/simplehash.js";
|
|
8
|
-
import { TokenSelector } from "@
|
|
8
|
+
import { TokenSelector } from "@relayprotocol/relay-kit-ui";
|
|
9
9
|
import { CheckCircle2, ChevronsUpDown } from "lucide-react";
|
|
10
10
|
import { useMemo } from "react";
|
|
11
11
|
import { ChainTokenIcon } from "./ChainTokenIcon.js";
|
|
@@ -6,7 +6,7 @@ import { NumericFormat } from "react-number-format";
|
|
|
6
6
|
import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID } from "../../../../anyspend/index.js";
|
|
7
7
|
import { Button } from "../../../../global-account/react/index.js";
|
|
8
8
|
import { cn } from "../../../../shared/utils/index.js";
|
|
9
|
-
import { TokenSelector } from "@
|
|
9
|
+
import { TokenSelector } from "@relayprotocol/relay-kit-ui";
|
|
10
10
|
import { ChainTokenIcon } from "./ChainTokenIcon.js";
|
|
11
11
|
export function OrderTokenAmount({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect = false, canEditAmount = true, className, innerClassName, amountClassName, tokenSelectClassName, onTokenSelect, }) {
|
|
12
12
|
// Track previous token to detect changes
|
|
@@ -5,7 +5,7 @@ import { useEffect, useRef } from "react";
|
|
|
5
5
|
import { NumericFormat } from "react-number-format";
|
|
6
6
|
import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID } from "../../../../anyspend/index.js";
|
|
7
7
|
import { cn } from "../../../../shared/utils/index.js";
|
|
8
|
-
import { TokenSelector } from "@
|
|
8
|
+
import { TokenSelector } from "@relayprotocol/relay-kit-ui";
|
|
9
9
|
import { ChainTokenIcon } from "./ChainTokenIcon.js";
|
|
10
10
|
export function OrderTokenAmountFiat({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, className, }) {
|
|
11
11
|
// Track previous token to detect changes
|
|
@@ -6,7 +6,7 @@ import { NumericFormat } from "react-number-format";
|
|
|
6
6
|
import { ALL_CHAINS, RELAY_SOLANA_MAINNET_CHAIN_ID } from "../../../../anyspend/index.js";
|
|
7
7
|
import { Button } from "../../../../global-account/react/index.js";
|
|
8
8
|
import { cn } from "../../../../shared/utils/index.js";
|
|
9
|
-
import { TokenSelector } from "@
|
|
9
|
+
import { TokenSelector } from "@relayprotocol/relay-kit-ui";
|
|
10
10
|
import { ChainTokenIcon } from "./ChainTokenIcon.js";
|
|
11
11
|
export function OrderTokenAmountFiat({ disabled, inputValue, onChangeInput, context, address, chainId, setChainId, token, setToken, hideTokenSelect = false, canEditAmount = true, className, showAsReceiveAmount = false, }) {
|
|
12
12
|
// Track previous token to detect changes
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { components } from "../../../../anyspend/types/api";
|
|
2
2
|
import { GetQuoteResponse } from "../../../../anyspend/types/api_req_res";
|
|
3
3
|
import { FiatPaymentMethod } from "./FiatPaymentMethod";
|
|
4
|
-
export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken, anyspendQuote, onShowPointsDetail, customUsdInputValues, }: {
|
|
4
|
+
export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken, anyspendQuote, onShowPointsDetail, onShowFeeDetail, customUsdInputValues, }: {
|
|
5
5
|
srcAmountOnRamp: string;
|
|
6
6
|
setSrcAmountOnRamp: (amount: string) => void;
|
|
7
7
|
selectedPaymentMethod?: FiatPaymentMethod;
|
|
@@ -18,5 +18,6 @@ export declare function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selec
|
|
|
18
18
|
hideDstToken?: boolean;
|
|
19
19
|
anyspendQuote?: GetQuoteResponse;
|
|
20
20
|
onShowPointsDetail?: () => void;
|
|
21
|
+
onShowFeeDetail?: () => void;
|
|
21
22
|
customUsdInputValues?: string[];
|
|
22
23
|
}): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,44 +1,48 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
-
import { useCoinbaseOnrampOptions
|
|
2
|
+
import { useCoinbaseOnrampOptions } from "../../../../anyspend/react/index.js";
|
|
3
3
|
import { ALL_CHAINS } from "../../../../anyspend/utils/chain.js";
|
|
4
4
|
import { Input, useGetGeo, useProfile } from "../../../../global-account/react/index.js";
|
|
5
5
|
import { cn, formatUsername } from "../../../../shared/utils/index.js";
|
|
6
6
|
import { formatAddress } from "../../../../shared/utils/formatAddress.js";
|
|
7
|
-
import { ChevronRight, Wallet } from "lucide-react";
|
|
7
|
+
import { ChevronRight, Info, Wallet } from "lucide-react";
|
|
8
8
|
import { useRef } from "react";
|
|
9
9
|
import { toast } from "sonner";
|
|
10
10
|
import { useFeatureFlags } from "../../contexts/FeatureFlagsContext.js";
|
|
11
11
|
import { FiatPaymentMethod } from "./FiatPaymentMethod.js";
|
|
12
12
|
import { OrderTokenAmountFiat } from "./OrderTokenAmountFiat.js";
|
|
13
13
|
import { PointsBadge } from "./PointsBadge.js";
|
|
14
|
-
export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken = false, anyspendQuote, onShowPointsDetail, customUsdInputValues = ["5", "10", "20", "25"], }) {
|
|
14
|
+
export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPaymentMethod, setActivePanel, _recipientAddress, destinationToken, destinationChainId, destinationAmount, onDestinationTokenChange, onDestinationChainChange, fiatPaymentMethodIndex, recipientSelectionPanelIndex, dstTokenSymbol, hideDstToken = false, anyspendQuote, onShowPointsDetail, onShowFeeDetail, customUsdInputValues = ["5", "10", "20", "25"], }) {
|
|
15
15
|
const featureFlags = useFeatureFlags();
|
|
16
|
-
//
|
|
17
|
-
const { stripeWeb2Support } = useGeoOnrampOptions(srcAmountOnRamp);
|
|
18
|
-
// Helper function to get fees from API data
|
|
16
|
+
// Helper function to get fees from anyspend quote
|
|
19
17
|
const getFeeFromApi = (paymentMethod) => {
|
|
18
|
+
// Try to get fee from anyspend quote first (most accurate)
|
|
19
|
+
if (anyspendQuote?.data?.fee) {
|
|
20
|
+
const fee = anyspendQuote.data.fee;
|
|
21
|
+
if (fee.type === "stripeweb2_fee") {
|
|
22
|
+
// Calculate total fee in USD from originalAmount - finalAmount
|
|
23
|
+
const originalAmount = Number(fee.originalAmount) / 1e6; // Convert from wei to USD
|
|
24
|
+
const finalAmount = Number(fee.finalAmount) / 1e6;
|
|
25
|
+
return originalAmount - finalAmount;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
// Fallback to payment method defaults
|
|
20
29
|
switch (paymentMethod) {
|
|
21
30
|
case FiatPaymentMethod.COINBASE_PAY:
|
|
22
|
-
// Coinbase
|
|
23
|
-
return 0;
|
|
31
|
+
return 0; // Coinbase has no additional fees
|
|
24
32
|
case FiatPaymentMethod.STRIPE:
|
|
25
|
-
|
|
26
|
-
if (stripeWeb2Support && "formattedFeeUsd" in stripeWeb2Support) {
|
|
27
|
-
return parseFloat(stripeWeb2Support.formattedFeeUsd) || 0;
|
|
28
|
-
}
|
|
29
|
-
return null;
|
|
33
|
+
return null; // No quote available yet
|
|
30
34
|
default:
|
|
31
|
-
return null;
|
|
35
|
+
return null;
|
|
32
36
|
}
|
|
33
37
|
};
|
|
34
38
|
// Helper function to get total amount from API (for Stripe) or calculate it (for others)
|
|
35
39
|
const getTotalAmount = (paymentMethod) => {
|
|
36
40
|
const baseAmount = parseFloat(srcAmountOnRamp) || 5;
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
return parseFloat(stripeWeb2Support.formattedTotalUsd) || baseAmount;
|
|
41
|
+
// Try to get from anyspend quote first (most accurate)
|
|
42
|
+
if (anyspendQuote?.data?.fee?.type === "stripeweb2_fee") {
|
|
43
|
+
return Number(anyspendQuote.data.fee.originalAmount) / 1e6; // Convert from wei to USD
|
|
41
44
|
}
|
|
45
|
+
const fee = getFeeFromApi(paymentMethod);
|
|
42
46
|
// For Coinbase or when fee is available, calculate manually
|
|
43
47
|
if (fee !== null) {
|
|
44
48
|
return baseAmount + fee;
|
|
@@ -75,10 +79,21 @@ export function PanelOnramp({ srcAmountOnRamp, setSrcAmountOnRamp, selectedPayme
|
|
|
75
79
|
.filter(v => !isNaN(Number(v)))
|
|
76
80
|
.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
|
|
77
81
|
? "border-as-border-secondary bg-as-surface-secondary"
|
|
78
|
-
: "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && !hideDstToken && (_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(recipientSelectionPanelIndex), children: [_jsx("span", { className: "text-sm", children: recipientName ? formatUsername(recipientName) : formatAddress(_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", " ", dstTokenSymbol || 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: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-
|
|
79
|
-
const fee = getFeeFromApi(selectedPaymentMethod || FiatPaymentMethod.NONE);
|
|
80
|
-
return fee !== null ? `Total (included $${fee.toFixed(2)} fee)` : "Total";
|
|
81
|
-
})() }), featureFlags.showPoints &&
|
|
82
|
+
: "bg-as-surface-secondary hover:bg-as-surface-secondary"}`, children: ["$", value] }, value))) }), destinationToken && destinationChainId && !hideDstToken && (_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(recipientSelectionPanelIndex), children: [_jsx("span", { className: "text-sm", children: recipientName ? formatUsername(recipientName) : formatAddress(_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", " ", dstTokenSymbol || 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: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-as-tertiarry text-sm", children: "Total" }), anyspendQuote?.data?.fee && onShowFeeDetail && (_jsx("button", { onClick: onShowFeeDetail, className: "text-as-primary/40 hover:text-as-primary/60 transition-colors", children: _jsx(Info, { className: "h-4 w-4" }) })), featureFlags.showPoints &&
|
|
82
83
|
anyspendQuote?.data?.pointsAmount &&
|
|
83
|
-
anyspendQuote?.data?.pointsAmount > 0 && (_jsx(PointsBadge, { pointsAmount: anyspendQuote.data.pointsAmount, pointsMultiplier: anyspendQuote.data.pointsMultiplier, onClick: () => onShowPointsDetail?.() }))] }), _jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)] })
|
|
84
|
+
anyspendQuote?.data?.pointsAmount > 0 && (_jsx(PointsBadge, { pointsAmount: anyspendQuote.data.pointsAmount, pointsMultiplier: anyspendQuote.data.pointsMultiplier, onClick: () => onShowPointsDetail?.() }))] }), _jsxs("div", { className: "flex flex-col items-end gap-0.5", children: [_jsxs("span", { className: "text-as-primary font-semibold", children: ["$", getTotalAmount(selectedPaymentMethod || FiatPaymentMethod.NONE).toFixed(2)] }), (() => {
|
|
85
|
+
// For fiat payments, show the fee from the payment method
|
|
86
|
+
const fiatFee = getFeeFromApi(selectedPaymentMethod || FiatPaymentMethod.NONE);
|
|
87
|
+
if (fiatFee !== null && fiatFee > 0) {
|
|
88
|
+
return _jsxs("span", { className: "text-as-secondary text-xs", children: ["incl. $", fiatFee.toFixed(2), " fee"] });
|
|
89
|
+
}
|
|
90
|
+
// For crypto payments (standard_fee), calculate from the quote
|
|
91
|
+
if (anyspendQuote?.data?.fee?.type === "standard_fee" && anyspendQuote.data.currencyIn?.amountUsd) {
|
|
92
|
+
const cryptoFee = (Number(anyspendQuote.data.currencyIn.amountUsd) * anyspendQuote.data.fee.finalFeeBps) / 10000;
|
|
93
|
+
if (cryptoFee > 0) {
|
|
94
|
+
return _jsxs("span", { className: "text-as-secondary text-xs", children: ["incl. $", cryptoFee.toFixed(2), " fee"] });
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
return null;
|
|
98
|
+
})()] })] }) })] })] }));
|
|
84
99
|
}
|