UNPKG

@reservoir0x/relay-kit-ui

Version:

Relay is the Fastest and Cheapest Way to Bridge and Transact Across Chains.

165 lines 14.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const index_js_1 = require("../primitives/index.js"); const numbers_js_1 = require("../../utils/numbers.js"); const react_fontawesome_1 = require("@fortawesome/react-fontawesome"); const faGasPump_1 = require("@fortawesome/free-solid-svg-icons/faGasPump"); const faChevronDown_1 = require("@fortawesome/free-solid-svg-icons/faChevronDown"); const FetchingQuoteLoader_js_1 = tslib_1.__importDefault(require("../widgets/FetchingQuoteLoader.js")); const SwapRouteSelector_js_1 = tslib_1.__importDefault(require("../widgets/SwapRouteSelector.js")); const Collapsible_js_1 = require("../primitives/Collapsible.js"); const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons"); const PriceImpactTooltip_js_1 = require("./PriceImpactTooltip.js"); const slippage_js_1 = require("../../utils/slippage.js"); const Tooltip_js_1 = tslib_1.__importDefault(require("../primitives/Tooltip.js")); const react_2 = tslib_1.__importDefault(require("react")); const formatSwapRate = (rate) => { return rate >= 1 ? (0, numbers_js_1.formatBN)(rate, 2, 18, false) : (0, numbers_js_1.formatBN)(rate, 4, 18, false); }; const FeeBreakdown = ({ feeBreakdown, isFetchingQuote, quote, toToken, fromToken, toChain, supportsExternalLiquidity, useExternalLiquidity, setUseExternalLiquidity, timeEstimate, canonicalTimeEstimate, isSingleChainLocked, fromChainWalletVMSupported, isAutoSlippage, slippageInputBps, error }) => { const [isOpen, setIsOpen] = (0, react_1.useState)(false); const swapRate = quote?.details?.rate; const originGasFee = feeBreakdown?.breakdown?.find((fee) => fee.id === 'origin-gas'); const originGasFeeFormatted = (0, numbers_js_1.formatDollar)(Math.abs(originGasFee?.usd.value ?? 0)); const [rateMode, setRateMode] = (0, react_1.useState)('input'); const isHighPriceImpact = Number(quote?.details?.totalImpact?.percent) < -3.5; const isSameChain = toToken?.chainId === fromToken?.chainId; const originSlippageTolerance = quote?.details?.slippageTolerance?.origin?.percent; const destinationSlippageTolerance = quote?.details?.slippageTolerance?.destination?.percent; const quoteSlippage = (isSameChain ? destinationSlippageTolerance === '0' ? originSlippageTolerance : destinationSlippageTolerance : destinationSlippageTolerance) ?? '0'; const slippageInputNumber = Number((Number(slippageInputBps ?? '0') / 100).toFixed(2)); const slippage = `${Math.max(Number(quoteSlippage), slippageInputNumber)}`; const slippageRating = (0, slippage_js_1.getSlippageRating)(slippage); const slippageRatingColor = slippage_js_1.ratingToColor[slippageRating]; const minimumAmountFormatted = quote?.details?.currencyOut?.minimumAmount ? (0, numbers_js_1.formatBN)(quote.details.currencyOut.minimumAmount, 6, toToken?.decimals, false) : undefined; const breakdown = [ { title: 'Estimated time', value: ((0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", css: { gap: '1', color: timeEstimate && timeEstimate.time <= 30 ? '{colors.green.9}' : '{colors.amber.9}' }, children: [(0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faClock, width: 16 }), (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle2", children: ["~ ", timeEstimate?.formattedTime] })] })) }, { title: 'Network cost', value: ((0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", css: { gap: '1' }, children: [(0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: faGasPump_1.faGasPump, width: 16, style: { color: '#C1C8CD' } }), (0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", children: originGasFeeFormatted })] })) }, { title: 'Price Impact', value: ((0, jsx_runtime_1.jsx)(PriceImpactTooltip_js_1.PriceImpactTooltip, { feeBreakdown: feeBreakdown, tooltipProps: { side: 'top', align: 'end' }, children: (0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", css: { gap: '1', color: 'gray8' }, children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", css: { color: isHighPriceImpact ? 'red11' : undefined }, children: feeBreakdown?.totalFees?.priceImpactPercentage }), (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faInfoCircle, width: 14, height: 14, style: { display: 'inline-block', marginLeft: 4 } })] }) }) })) }, { title: 'Max Slippage', value: ((0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", css: { gap: '1' }, children: [isAutoSlippage ? ((0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle3", css: { py: '1px', px: '4px', bg: 'gray3', borderRadius: 100 }, children: "Auto" })) : null, (0, jsx_runtime_1.jsx)(Tooltip_js_1.default, { side: "top", align: "end", content: minimumAmountFormatted ? ((0, jsx_runtime_1.jsxs)(index_js_1.Flex, { direction: "row", css: { gap: '2' }, children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", color: "subtle", children: "Min. received" }), (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle2", children: [minimumAmountFormatted, " ", toToken?.symbol] })] })) : null, children: (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle2", css: { color: slippageRatingColor }, children: [slippage, "%"] }) })] })) } ]; if (!isSingleChainLocked && fromChainWalletVMSupported) { breakdown.unshift({ title: 'Route', value: ((0, jsx_runtime_1.jsx)(SwapRouteSelector_js_1.default, { chain: toChain, supportsExternalLiquidity: supportsExternalLiquidity, externalLiquidtySelected: useExternalLiquidity, onExternalLiquidityChange: (selected) => { setUseExternalLiquidity(selected); }, canonicalTimeEstimate: canonicalTimeEstimate?.formattedTime, error: error, trigger: (0, jsx_runtime_1.jsx)(index_js_1.Button, { color: "ghost", size: "none", children: (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { css: { gap: '2', alignItems: 'center' }, children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", children: useExternalLiquidity ? 'Native' : 'Relay' }), supportsExternalLiquidity || useExternalLiquidity ? ((0, jsx_runtime_1.jsx)(index_js_1.Box, { css: { color: 'gray11', width: 14, flexShrink: 0 }, children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faChevronRight, width: 14 }) })) : null] }) }) })) }); } if (!feeBreakdown) { if (isFetchingQuote) { return ((0, jsx_runtime_1.jsx)(index_js_1.Box, { id: 'fee-breakdown-section', css: { borderRadius: 'widget-card-border-radius', backgroundColor: 'widget-background', border: 'widget-card-border', overflow: 'hidden', mb: 'widget-card-section-gutter' }, children: (0, jsx_runtime_1.jsx)(FetchingQuoteLoader_js_1.default, { isLoading: isFetchingQuote, containerCss: { mt: 0, mb: 0, px: '4', py: '3', width: '100%', justifyContent: 'center' } }) })); } else { return null; } } return ((0, jsx_runtime_1.jsxs)(Collapsible_js_1.CollapsibleRoot, { open: isOpen, onOpenChange: setIsOpen, css: { mb: 'widget-card-section-gutter' }, children: [(0, jsx_runtime_1.jsx)(Collapsible_js_1.CollapsibleTrigger, { css: { borderRadius: 'widget-card-border-radius', borderBottomRadius: isOpen ? '0' : 'widget-card-border-radius', backgroundColor: 'widget-background', border: 'widget-card-border', borderBottom: isOpen ? 'none' : 'widget-card-border', overflow: 'hidden', transition: 'border-radius 300ms, border-bottom 0s', transitionDelay: isOpen ? '0s, 0s' : '0s, 300ms' }, id: 'fee-breakdown-section', children: (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { justify: "between", align: "center", css: { flexDirection: 'row', gap: '2', width: '100%', p: '3' }, children: [(0, jsx_runtime_1.jsx)("span", { style: { cursor: 'pointer', flexShrink: 1, overflow: 'hidden', height: 21 }, onClick: (e) => { setRateMode(rateMode === 'input' ? 'output' : 'input'); e.preventDefault(); }, children: (0, jsx_runtime_1.jsx)(ConversionRate, { fromToken: fromToken, toToken: toToken, rate: Number(swapRate), isInputMode: rateMode === 'input' }) }), (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { css: { gap: '2', color: timeEstimate && timeEstimate.time <= 30 ? '{colors.green.9}' : '{colors.amber.9}', flexShrink: 0 }, align: "center", children: [!isOpen && timeEstimate && timeEstimate?.time !== 0 ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faClock, width: 16 }), (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle2", css: { flexShrink: 0 }, children: ["~ ", timeEstimate?.formattedTime] }), (0, jsx_runtime_1.jsx)(index_js_1.Flex, { justify: "center", align: "center", css: { color: 'gray6', height: 4 }, children: "\u2022" })] })) : null, !isOpen && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: faGasPump_1.faGasPump, width: 16, style: { color: '#C1C8CD' } }), (0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", css: { flexShrink: 0 }, children: originGasFeeFormatted })] })), (0, jsx_runtime_1.jsx)(index_js_1.Box, { css: { marginLeft: '2', transition: 'transform 300ms', transform: isOpen ? 'rotate(-180deg)' : 'rotate(0)', color: 'gray9' }, children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: faChevronDown_1.faChevronDown, width: 12 }) })] })] }) }), (0, jsx_runtime_1.jsx)(Collapsible_js_1.CollapsibleContent, { css: { borderRadius: '0 0 12px 12px', border: 'widget-card-border', borderTop: 'none' }, children: (0, jsx_runtime_1.jsx)(index_js_1.Flex, { direction: "column", css: { px: '3', pb: '3', pt: '0', gap: '2', backgroundColor: 'widget-background' }, children: breakdown.map((item) => { const showNativeBridgeWarning = item.title === 'Estimated time' && useExternalLiquidity && timeEstimate?.time && timeEstimate?.time > 86400; return ((0, jsx_runtime_1.jsxs)(react_2.default.Fragment, { children: [(0, jsx_runtime_1.jsxs)(index_js_1.Flex, { justify: "between", align: "center", css: { width: '100%', gap: '4' }, children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", color: showNativeBridgeWarning ? 'warningSecondary' : 'subtle', css: { alignSelf: 'flex-start' }, children: item.title }), item.value] }), showNativeBridgeWarning ? ((0, jsx_runtime_1.jsx)(index_js_1.Flex, { align: "center", css: { gap: '2', py: '2', px: '3', backgroundColor: 'amber2', borderRadius: 12 }, children: (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle3", css: { color: 'amber12' }, children: ["Native bridge routes are expected to take", ' ', timeEstimate.formattedTime, " but could be longer due to unexpected delays"] }) })) : null] }, item.title)); }) }) })] })); }; exports.default = FeeBreakdown; const ConversionRate = ({ fromToken, toToken, rate, isInputMode }) => { const displayRate = isInputMode ? rate : 1 / rate; const fromSymbol = isInputMode ? fromToken?.symbol : toToken?.symbol; const toSymbol = isInputMode ? toToken?.symbol : fromToken?.symbol; return ((0, jsx_runtime_1.jsx)(Tooltip_js_1.default, { content: (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle2", children: ["1 ", fromSymbol, " = ", formatSwapRate(displayRate), " ", toSymbol] }), asChild: true, children: (0, jsx_runtime_1.jsx)("div", { style: { width: '100%', minWidth: 0 }, children: (0, jsx_runtime_1.jsxs)(index_js_1.Text, { style: "subtitle2", ellipsify: true, children: ["1 ", fromSymbol, " = ", formatSwapRate(displayRate), " ", toSymbol] }) }) })); }; //# sourceMappingURL=FeeBreakdown.js.map