@reservoir0x/relay-kit-ui
Version:
Relay is the Fastest and Cheapest Way to Bridge and Transact Across Chains.
643 lines (642 loc) • 76.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const jsx_runtime_1 = require("react/jsx-runtime");
const index_js_1 = require("../../primitives/index.js");
const react_1 = require("react");
const index_js_2 = require("../../../hooks/index.js");
const viem_1 = require("viem");
const wagmi_1 = require("wagmi");
const numbers_js_1 = require("../../../utils/numbers.js");
const AmountInput_js_1 = tslib_1.__importDefault(require("../../common/AmountInput.js"));
const react_fontawesome_1 = require("@fortawesome/react-fontawesome");
const index_js_3 = require("../../../icons/index.js");
const nativeMaxAmount_js_1 = require("../../../utils/nativeMaxAmount.js");
const WidgetErrorWell_js_1 = require("../WidgetErrorWell.js");
const BalanceDisplay_js_1 = require("../../common/BalanceDisplay.js");
const events_js_1 = require("../../../constants/events.js");
const SwapWidgetRenderer_js_1 = tslib_1.__importDefault(require("../SwapWidgetRenderer.js"));
const WidgetContainer_js_1 = tslib_1.__importDefault(require("../WidgetContainer.js"));
const SwapButton_js_1 = tslib_1.__importDefault(require("../SwapButton.js"));
const TokenSelectorContainer_js_1 = tslib_1.__importDefault(require("../TokenSelectorContainer.js"));
const FeeBreakdown_js_1 = tslib_1.__importDefault(require("../FeeBreakdown.js"));
const free_solid_svg_icons_1 = require("@fortawesome/free-solid-svg-icons");
const TokenTrigger_js_1 = require("../../common/TokenSelector/triggers/TokenTrigger.js");
const MultiWalletDropdown_js_1 = require("../../common/MultiWalletDropdown.js");
const address_js_1 = require("../../../utils/address.js");
const relay_sdk_1 = require("@reservoir0x/relay-sdk");
const SwapRouteSelector_js_1 = tslib_1.__importDefault(require("../SwapRouteSelector.js"));
const RelayKitProvider_js_1 = require("../../../providers/RelayKitProvider.js");
const tokens_js_1 = require("../../../utils/tokens.js");
const tokenSelector_js_1 = require("../../../utils/tokenSelector.js");
const TokenSelector_js_1 = tslib_1.__importDefault(require("../../common/TokenSelector/TokenSelector.js"));
const UnverifiedTokenModal_js_1 = require("../../common/UnverifiedTokenModal.js");
const localStorage_js_1 = require("../../../utils/localStorage.js");
const GasTopUpSection_js_1 = tslib_1.__importDefault(require("./GasTopUpSection.js"));
const quote_js_1 = require("../../../utils/quote.js");
const SwapWidget = ({ fromToken, setFromToken, toToken, setToToken, defaultToAddress, defaultAmount, defaultTradeType, slippageTolerance, lockToToken = false, lockFromToken = false, lockChainId, singleChainMode = false, wallet, multiWalletSupportEnabled = false, linkedWallets, supportedWalletVMs, disableInputAutoFocus = false, popularChainIds, disablePasteWalletAddressOption, onSetPrimaryWallet, onLinkNewWallet, onFromTokenChange, onToTokenChange, onConnectWallet, onAnalyticEvent: _onAnalyticEvent, onSwapSuccess, onSwapValidating, onSwapError }) => {
const onAnalyticEvent = (0, react_1.useCallback)((eventName, data) => {
try {
_onAnalyticEvent?.(eventName, data);
}
catch (e) {
console.error('Error in onAnalyticEvent', eventName, data, e);
}
}, [_onAnalyticEvent]);
const relayClient = (0, index_js_2.useRelayClient)();
const providerOptionsContext = (0, react_1.useContext)(RelayKitProvider_js_1.ProviderOptionsContext);
const connectorKeyOverrides = providerOptionsContext.vmConnectorKeyOverrides;
const [transactionModalOpen, setTransactionModalOpen] = (0, react_1.useState)(false);
const [depositAddressModalOpen, setDepositAddressModalOpen] = (0, react_1.useState)(false);
const [addressModalOpen, setAddressModalOpen] = (0, react_1.useState)(false);
const [pendingSuccessFlush, setPendingSuccessFlush] = (0, react_1.useState)(false);
const [unverifiedTokens, setUnverifiedTokens] = (0, react_1.useState)([]);
const [isUsdInputMode, setIsUsdInputMode] = (0, react_1.useState)(false);
const [usdInputValue, setUsdInputValue] = (0, react_1.useState)('');
const [usdOutputValue, setUsdOutputValue] = (0, react_1.useState)('');
const [tokenInputCache, setTokenInputCache] = (0, react_1.useState)('');
const hasLockedToken = lockFromToken || lockToToken;
const isSingleChainLocked = singleChainMode && lockChainId !== undefined;
(0, react_1.useEffect)(() => {
if (fromToken && 'verified' in fromToken && !fromToken.verified) {
const isAlreadyAccepted = (0, localStorage_js_1.alreadyAcceptedToken)(fromToken);
if (!isAlreadyAccepted) {
unverifiedTokens.push({ token: fromToken, context: 'from' });
setFromToken?.(undefined);
}
}
if (toToken && 'verified' in toToken && !toToken.verified) {
const isAlreadyAccepted = (0, localStorage_js_1.alreadyAcceptedToken)(toToken);
if (!isAlreadyAccepted) {
unverifiedTokens.push({ token: toToken, context: 'to' });
setToToken?.(undefined);
}
}
}, [fromToken, toToken]);
return ((0, jsx_runtime_1.jsx)(SwapWidgetRenderer_js_1.default, { context: "Swap", transactionModalOpen: transactionModalOpen, setTransactionModalOpen: setTransactionModalOpen, depositAddressModalOpen: depositAddressModalOpen, defaultAmount: defaultAmount, defaultToAddress: defaultToAddress, defaultTradeType: defaultTradeType, toToken: toToken, setToToken: setToToken, fromToken: fromToken, setFromToken: setFromToken, slippageTolerance: slippageTolerance, wallet: wallet, linkedWallets: linkedWallets, multiWalletSupportEnabled: multiWalletSupportEnabled, onSwapError: onSwapError, onAnalyticEvent: onAnalyticEvent, supportedWalletVMs: supportedWalletVMs, children: ({ quote, steps, swap, setSteps, feeBreakdown, fromToken, setFromToken, toToken, setToToken, error, toDisplayName, address, recipient, customToAddress, setCustomToAddress, tradeType, setTradeType, isSameCurrencySameRecipientSwap, debouncedInputAmountValue, debouncedAmountInputControls, setAmountInputValue, amountInputValue, amountOutputValue, debouncedOutputAmountValue, debouncedAmountOutputControls, setAmountOutputValue, toBalance, toBalancePending, isLoadingToBalance, isFetchingQuote, isLoadingFromBalance, fromBalance, fromBalancePending, highRelayerServiceFee, relayerFeeProportion, hasInsufficientBalance, isInsufficientLiquidityError, isCapacityExceededError, isCouldNotExecuteError, ctaCopy, isFromNative, timeEstimate, isSvmSwap, isBvmSwap, isValidFromAddress, isValidToAddress, supportsExternalLiquidity, useExternalLiquidity, slippageTolerance, canonicalTimeEstimate, fromChainWalletVMSupported, toChainWalletVMSupported, isRecipientLinked, swapError, recipientWalletSupportsChain, gasTopUpEnabled, setGasTopUpEnabled, gasTopUpRequired, gasTopUpAmount, gasTopUpAmountUsd, linkedWallet, quoteParameters, setSwapError, setUseExternalLiquidity, invalidateBalanceQueries, invalidateQuoteQuery, quoteInProgress, setQuoteInProgress, abortController, fromTokenPriceData, toTokenPriceData, isLoadingFromTokenPrice, isLoadingToTokenPrice }) => {
const inputAmountUsd = (0, react_1.useMemo)(() => {
return (0, quote_js_1.calculateUsdValue)(fromTokenPriceData?.price, amountInputValue);
}, [fromTokenPriceData, amountInputValue]);
const outputAmountUsd = (0, react_1.useMemo)(() => {
return (0, quote_js_1.calculateUsdValue)(toTokenPriceData?.price, amountOutputValue);
}, [toTokenPriceData, amountOutputValue]);
const handleMaxAmountClicked = async (amount, percent, bufferAmount) => {
if (fromToken) {
const formattedAmount = (0, viem_1.formatUnits)(amount, fromToken?.decimals);
setAmountInputValue(formattedAmount);
setTradeType('EXACT_INPUT');
debouncedAmountOutputControls.cancel();
debouncedAmountInputControls.flush();
onAnalyticEvent?.(events_js_1.EventNames.MAX_AMOUNT_CLICKED, {
percent: percent,
bufferAmount: bufferAmount ? bufferAmount.toString() : '0',
chainType: fromChain?.vmType
});
if (isUsdInputMode && conversionRate) {
const numericTokenAmount = Number(formattedAmount);
if (!isNaN(numericTokenAmount)) {
const usdEquivalent = numericTokenAmount * conversionRate;
setUsdInputValue(usdEquivalent.toFixed(2));
}
}
}
};
const handleSetFromToken = (token) => {
if (!token) {
setFromToken(undefined);
onFromTokenChange?.(undefined);
return;
}
let _token = token;
const newFromChain = relayClient?.chains.find((chain) => token?.chainId == chain.id);
if (newFromChain?.vmType &&
!supportedWalletVMs.includes(newFromChain?.vmType)) {
setTradeType('EXACT_INPUT');
const _toToken = (0, tokens_js_1.findBridgableToken)(toChain, toToken);
if (_toToken && _toToken?.address != toToken?.address) {
handleSetToToken(_toToken);
}
const _fromToken = (0, tokens_js_1.findBridgableToken)(newFromChain, _token);
if (_fromToken && _fromToken.address != _token?.address) {
_token = _fromToken;
}
}
setFromToken(_token);
onFromTokenChange?.(_token);
};
const handleSetToToken = (token) => {
if (!token) {
setToToken(undefined);
onToTokenChange?.(undefined);
return;
}
let _token = token;
if (!fromChainWalletVMSupported) {
const newToChain = relayClient?.chains.find((chain) => token?.chainId == chain.id);
if (newToChain) {
const _toToken = (0, tokens_js_1.findBridgableToken)(newToChain, _token);
if (_toToken && _toToken.address != _token?.address) {
_token = _toToken;
}
}
}
setToToken(_token);
onToTokenChange?.(_token);
};
const fromChain = relayClient?.chains?.find((chain) => chain.id === fromToken?.chainId);
const toChain = relayClient?.chains?.find((chain) => chain.id === toToken?.chainId);
const publicClient = (0, wagmi_1.usePublicClient)({ chainId: fromChain?.id });
(0, react_1.useEffect)(() => {
if (multiWalletSupportEnabled &&
fromChain &&
address &&
linkedWallets &&
!isValidFromAddress) {
const supportedAddress = (0, address_js_1.findSupportedWallet)(fromChain, address, linkedWallets, connectorKeyOverrides);
if (supportedAddress) {
onSetPrimaryWallet?.(supportedAddress);
}
}
if (multiWalletSupportEnabled &&
toChain &&
recipient &&
linkedWallets &&
!isValidToAddress) {
const supportedAddress = (0, address_js_1.findSupportedWallet)(toChain, recipient, linkedWallets, connectorKeyOverrides);
if (supportedAddress) {
setCustomToAddress(supportedAddress);
}
else {
setCustomToAddress(undefined);
}
}
}, [
multiWalletSupportEnabled,
fromChain?.id,
toChain?.id,
address,
linkedWallets,
onSetPrimaryWallet,
isValidFromAddress,
isValidToAddress,
connectorKeyOverrides
]);
(0, react_1.useEffect)(() => {
if (disablePasteWalletAddressOption && customToAddress) {
setCustomToAddress(undefined);
}
}, [disablePasteWalletAddressOption]);
const promptSwitchRoute = (isCapacityExceededError || isCouldNotExecuteError) &&
supportsExternalLiquidity &&
!isSingleChainLocked;
const isAutoSlippage = slippageTolerance === undefined;
const isHighPriceImpact = Number(quote?.details?.totalImpact?.percent) < -3.5;
const totalImpactUsd = quote?.details?.totalImpact?.usd;
const showHighPriceImpactWarning = Boolean(isHighPriceImpact && totalImpactUsd && Number(totalImpactUsd) <= -10);
const conversionRate = (0, react_1.useMemo)(() => {
if (isUsdInputMode) {
if (fromTokenPriceData?.price && fromTokenPriceData.price > 0) {
return fromTokenPriceData.price;
}
else {
return null;
}
}
else {
if (amountInputValue &&
Number(amountInputValue) > 0 &&
quote?.details?.currencyIn?.amountUsd) {
const tokenVal = Number(amountInputValue);
const usdVal = Number(quote.details.currencyIn.amountUsd);
if (tokenVal > 0 && usdVal > 0) {
const rate = usdVal / tokenVal;
return rate;
}
else {
return null;
}
}
else {
return null;
}
}
}, [
isUsdInputMode,
fromTokenPriceData?.price,
quote?.details?.currencyIn?.amountUsd,
amountInputValue
]);
const toggleInputMode = () => {
if (!isUsdInputMode) {
let newUsdInputValue = '';
let newUsdOutputValue = '';
if (quote?.details?.currencyIn?.amountUsd &&
Number(quote.details.currencyIn.amountUsd) > 0) {
newUsdInputValue = String(Number(quote.details.currencyIn.amountUsd));
}
else if (inputAmountUsd && inputAmountUsd > 0) {
newUsdInputValue = inputAmountUsd.toFixed(2);
}
else if (amountInputValue &&
Number(amountInputValue) > 0 &&
conversionRate &&
conversionRate > 0) {
newUsdInputValue = (Number(amountInputValue) * conversionRate).toFixed(2);
}
if (quote?.details?.currencyOut?.amountUsd &&
Number(quote.details.currencyOut.amountUsd) > 0) {
newUsdOutputValue = String(Number(quote.details.currencyOut.amountUsd));
}
else if (outputAmountUsd && outputAmountUsd > 0) {
newUsdOutputValue = outputAmountUsd.toFixed(2);
}
else if (amountOutputValue &&
Number(amountOutputValue) > 0 &&
toTokenPriceData?.price &&
toTokenPriceData.price > 0) {
newUsdOutputValue = (Number(amountOutputValue) * toTokenPriceData.price).toFixed(2);
}
setTokenInputCache(amountInputValue);
setUsdInputValue(newUsdInputValue);
setUsdOutputValue(newUsdOutputValue);
setIsUsdInputMode(true);
if (tradeType !== 'EXPECTED_OUTPUT' || !newUsdOutputValue) {
setTradeType('EXACT_INPUT');
}
}
else {
if (!usdInputValue && tokenInputCache) {
setAmountInputValue(tokenInputCache);
}
setUsdInputValue('');
setUsdOutputValue('');
setIsUsdInputMode(false);
}
};
(0, react_1.useEffect)(() => {
if (isUsdInputMode) {
if (conversionRate && conversionRate > 0 && usdInputValue) {
const usdValue = Number(usdInputValue);
if (!isNaN(usdValue) && usdValue > 0) {
const tokenEquivalent = (usdValue / conversionRate).toFixed(fromToken?.decimals ?? 8);
setAmountInputValue(tokenEquivalent);
}
}
else if (usdInputValue === '' || Number(usdInputValue) === 0) {
setAmountInputValue('');
}
}
}, [
isUsdInputMode,
usdInputValue,
conversionRate,
setAmountInputValue,
fromToken?.decimals
]);
(0, react_1.useEffect)(() => {
if (isUsdInputMode && tradeType === 'EXPECTED_OUTPUT') {
if (toTokenPriceData?.price &&
toTokenPriceData.price > 0 &&
usdOutputValue) {
const usdValue = Number(usdOutputValue);
if (!isNaN(usdValue) && usdValue > 0) {
const tokenEquivalent = (usdValue / toTokenPriceData.price).toFixed(toToken?.decimals ?? 8);
setAmountOutputValue(tokenEquivalent);
}
}
else if (usdOutputValue === '' || Number(usdOutputValue) === 0) {
setAmountOutputValue('');
}
}
}, [
isUsdInputMode,
tradeType,
usdOutputValue,
toTokenPriceData?.price,
setAmountOutputValue,
toToken?.decimals
]);
(0, react_1.useEffect)(() => {
if (isUsdInputMode) {
if (tradeType === 'EXPECTED_OUTPUT') {
return;
}
if (quote?.details?.currencyOut?.amountUsd && !isFetchingQuote) {
const quoteUsdValue = Number(quote.details.currencyOut.amountUsd);
if (!isNaN(quoteUsdValue) && quoteUsdValue >= 0) {
setUsdOutputValue(quoteUsdValue.toFixed(2));
}
}
else if (toTokenPriceData?.price &&
toTokenPriceData.price > 0 &&
amountOutputValue &&
Number(amountOutputValue) > 0) {
const tokenAmount = Number(amountOutputValue);
const usdEquivalent = tokenAmount * toTokenPriceData.price;
if (!isNaN(usdEquivalent) && usdEquivalent >= 0) {
setUsdOutputValue(usdEquivalent.toFixed(2));
}
}
else if (!amountOutputValue || Number(amountOutputValue) === 0) {
setUsdOutputValue('');
}
}
}, [
isUsdInputMode,
tradeType,
quote?.details?.currencyOut?.amountUsd,
isFetchingQuote,
toTokenPriceData?.price,
amountOutputValue
]);
(0, react_1.useEffect)(() => {
if (isUsdInputMode && tradeType === 'EXPECTED_OUTPUT') {
if (quote?.details?.currencyIn?.amountUsd && !isFetchingQuote) {
const quoteUsdValue = Number(quote.details.currencyIn.amountUsd);
if (!isNaN(quoteUsdValue) && quoteUsdValue >= 0) {
setUsdInputValue(quoteUsdValue.toFixed(2));
}
}
else if (!amountInputValue || Number(amountInputValue) === 0) {
setUsdInputValue('');
}
}
}, [
isUsdInputMode,
tradeType,
quote?.details?.currencyIn?.amountUsd,
isFetchingQuote,
amountInputValue
]);
const recipientLinkedWallet = linkedWallets?.find((wallet) => wallet.address === recipient);
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(WidgetContainer_js_1.default, { steps: steps, setSteps: setSteps, quoteInProgress: quoteInProgress, setQuoteInProgress: setQuoteInProgress, transactionModalOpen: transactionModalOpen, setTransactionModalOpen: setTransactionModalOpen, depositAddressModalOpen: depositAddressModalOpen, setDepositAddressModalOpen: setDepositAddressModalOpen, addressModalOpen: addressModalOpen, setAddressModalOpen: setAddressModalOpen, fromToken: fromToken, fromChain: fromChain, toToken: toToken, toChain: toChain, address: address, recipient: recipient, amountInputValue: amountInputValue, amountOutputValue: amountOutputValue, debouncedInputAmountValue: debouncedInputAmountValue, debouncedOutputAmountValue: debouncedOutputAmountValue, tradeType: tradeType, onTransactionModalOpenChange: (open) => {
if (!open) {
if (pendingSuccessFlush) {
setPendingSuccessFlush(false);
}
else if (steps) {
invalidateQuoteQuery();
}
if (abortController) {
abortController.abort();
}
setSwapError(null);
setSteps(null);
setQuoteInProgress(null);
}
else if (pendingSuccessFlush) {
setPendingSuccessFlush(false);
}
}, onDepositAddressModalOpenChange: (open) => {
if (!open) {
setSwapError(null);
if (pendingSuccessFlush) {
setPendingSuccessFlush(false);
}
else {
invalidateQuoteQuery();
}
}
else if (pendingSuccessFlush) {
setPendingSuccessFlush(false);
}
}, useExternalLiquidity: useExternalLiquidity, slippageTolerance: slippageTolerance, swapError: swapError, setSwapError: setSwapError, onSwapSuccess: (data) => {
setPendingSuccessFlush(true);
setGasTopUpEnabled(true);
setAmountInputValue('');
setAmountOutputValue('');
onSwapSuccess?.(data);
}, onSwapValidating: onSwapValidating, onAnalyticEvent: onAnalyticEvent, invalidateBalanceQueries: invalidateBalanceQueries, invalidateQuoteQuery: invalidateQuoteQuery, customToAddress: customToAddress, setCustomToAddress: setCustomToAddress, timeEstimate: timeEstimate, wallet: wallet, linkedWallets: linkedWallets, multiWalletSupportEnabled: multiWalletSupportEnabled, children: () => {
return ((0, jsx_runtime_1.jsxs)(index_js_1.Flex, { direction: "column", css: {
width: '100%',
overflow: 'hidden',
border: 'widget-border',
minWidth: 300,
maxWidth: 408
}, children: [(0, jsx_runtime_1.jsxs)(TokenSelectorContainer_js_1.default, { css: { backgroundColor: 'widget-background' }, id: 'from-token-section', children: [(0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", justify: "between", css: { gap: '2', width: '100%' }, children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", color: "subtle", children: "Sell" }), multiWalletSupportEnabled === true &&
fromChainWalletVMSupported ? ((0, jsx_runtime_1.jsx)(MultiWalletDropdown_js_1.MultiWalletDropdown, { context: "origin", selectedWalletAddress: address, disablePasteWalletAddressOption: disablePasteWalletAddressOption, onSelect: (wallet) => onSetPrimaryWallet?.(wallet.address), chain: fromChain, onLinkNewWallet: () => {
if (!address && fromChainWalletVMSupported) {
onConnectWallet?.();
}
else {
onLinkNewWallet?.({
chain: fromChain,
direction: 'from'
})?.then((wallet) => {
onSetPrimaryWallet?.(wallet.address);
});
}
}, setAddressModalOpen: setAddressModalOpen, wallets: linkedWallets, onAnalyticEvent: onAnalyticEvent })) : null] }), (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", justify: "between", css: { gap: '4', width: '100%' }, children: [(0, jsx_runtime_1.jsx)(AmountInput_js_1.default, { autoFocus: !disableInputAutoFocus, prefixSymbol: isUsdInputMode ? '$' : undefined, value: isUsdInputMode
? usdInputValue
: tradeType === 'EXACT_INPUT'
? amountInputValue
: amountInputValue
? (0, numbers_js_1.formatFixedLength)(amountInputValue, 8)
: amountInputValue, setValue: (e) => {
if (isUsdInputMode) {
setUsdInputValue(e);
setTradeType('EXACT_INPUT');
setTokenInputCache('');
if (Number(e) === 0) {
setAmountOutputValue('');
setUsdOutputValue('');
debouncedAmountInputControls.flush();
}
}
else {
setAmountInputValue(e);
setTradeType('EXACT_INPUT');
if (Number(e) === 0) {
setAmountOutputValue('');
debouncedAmountInputControls.flush();
}
}
}, onFocus: () => {
onAnalyticEvent?.(events_js_1.EventNames.SWAP_INPUT_FOCUSED);
}, css: {
fontWeight: '700',
fontSize: 32,
lineHeight: '36px',
py: 0,
color: isFetchingQuote && tradeType === 'EXPECTED_OUTPUT'
? 'text-subtle'
: 'input-color',
_placeholder: {
color: isFetchingQuote &&
tradeType === 'EXPECTED_OUTPUT'
? 'text-subtle'
: 'input-color'
}
} }), (0, jsx_runtime_1.jsx)(TokenSelector_js_1.default, { address: address, isValidAddress: isValidFromAddress, token: fromToken, onAnalyticEvent: onAnalyticEvent, fromChainWalletVMSupported: fromChainWalletVMSupported, supportedWalletVMs: supportedWalletVMs, setToken: (token) => {
if (token.address === toToken?.address &&
token.chainId === toToken?.chainId &&
address === recipient &&
(!lockToToken || !fromToken)) {
handleSetFromToken(toToken);
handleSetToToken(fromToken);
}
else {
handleSetFromToken(token);
}
}, context: "from", multiWalletSupportEnabled: multiWalletSupportEnabled, lockedChainIds: isSingleChainLocked
? [lockChainId]
: (0, tokenSelector_js_1.isChainLocked)(fromToken?.chainId, lockChainId, toToken?.chainId, lockFromToken) && fromToken?.chainId
? [fromToken.chainId]
: undefined, chainIdsFilter: !fromChainWalletVMSupported && toToken
? [toToken.chainId]
: undefined, popularChainIds: popularChainIds, trigger: (0, jsx_runtime_1.jsx)("div", { style: { width: 'max-content' }, children: (0, jsx_runtime_1.jsx)(TokenTrigger_js_1.TokenTrigger, { token: fromToken, locked: lockFromToken, isSingleChainLocked: isSingleChainLocked, address: address }) }) })] }), (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", justify: "between", css: { gap: '3', width: '100%' }, children: [(0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", css: { gap: '4px', _hover: { cursor: 'pointer' } }, onClick: () => {
toggleInputMode();
}, children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle3", color: "subtleSecondary", css: {
minHeight: 18,
display: 'flex',
alignItems: 'center'
}, children: isUsdInputMode ? (fromToken ? (usdInputValue && Number(usdInputValue) > 0 ? (amountInputValue &&
conversionRate &&
!isLoadingFromTokenPrice ? (`${(0, numbers_js_1.formatNumber)(amountInputValue, 4, false)} ${fromToken.symbol}`) : ((0, jsx_runtime_1.jsx)(index_js_1.Box, { css: {
width: 45,
height: 12,
backgroundColor: 'gray7',
borderRadius: 'widget-border-radius'
} }))) : (`0 ${fromToken.symbol}`)) : null) : quote?.details?.currencyIn?.amountUsd &&
!isFetchingQuote ? ((0, numbers_js_1.formatDollar)(Number(quote.details.currencyIn.amountUsd))) : isLoadingFromTokenPrice &&
amountInputValue &&
Number(amountInputValue) > 0 ? ((0, jsx_runtime_1.jsx)(index_js_1.Box, { css: {
width: 45,
height: 12,
backgroundColor: 'gray7',
borderRadius: 'widget-border-radius'
} })) : inputAmountUsd &&
inputAmountUsd > 0 &&
fromTokenPriceData?.price &&
fromTokenPriceData.price > 0 ? ((0, numbers_js_1.formatDollar)(inputAmountUsd)) : ('$0.00') }), (0, jsx_runtime_1.jsx)(index_js_1.Button, { "aria-label": "Switch Input Mode", size: "none", color: "ghost", css: {
color: 'gray11',
alignSelf: 'center',
justifyContent: 'center',
width: '20px',
height: '20px',
borderRadius: '100px',
padding: '4px',
backgroundColor: 'gray3'
}, onClick: toggleInputMode, children: (0, jsx_runtime_1.jsx)(index_js_3.SwitchIcon, { width: 16, height: 10 }) })] }), (0, jsx_runtime_1.jsxs)(index_js_1.Flex, { align: "center", css: { gap: '3', marginLeft: 'auto', height: 23 }, children: [fromToken ? ((0, jsx_runtime_1.jsx)(BalanceDisplay_js_1.BalanceDisplay, { isLoading: isLoadingFromBalance, balance: fromBalance, decimals: fromToken?.decimals, symbol: fromToken?.symbol, hasInsufficientBalance: hasInsufficientBalance, displaySymbol: false, isConnected: !(0, relay_sdk_1.isDeadAddress)(address) &&
address !== relay_sdk_1.tronDeadAddress &&
address !== undefined, pending: fromBalancePending })) : ((0, jsx_runtime_1.jsx)(index_js_1.Flex, { css: { height: 18 } })), fromBalance &&
(fromChain?.vmType === 'evm' ||
fromChain?.vmType === 'svm') ? ((0, jsx_runtime_1.jsxs)(index_js_1.Flex, { css: { gap: '1' }, children: [(0, jsx_runtime_1.jsx)(index_js_1.Button, { "aria-label": "20%", css: {
fontSize: 12,
fontWeight: '500',
px: '1',
py: '1',
minHeight: '23px',
lineHeight: '100%',
backgroundColor: 'widget-selector-background',
border: 'none',
_hover: {
backgroundColor: 'widget-selector-hover-background'
}
}, color: "white", onClick: () => {
const percentageBuffer = (fromBalance * 20n) / 100n;
handleMaxAmountClicked(percentageBuffer, '20%');
}, children: "20%" }), (0, jsx_runtime_1.jsx)(index_js_1.Button, { "aria-label": "50%", css: {
fontSize: 12,
fontWeight: '500',
px: '1',
py: '1',
minHeight: '23px',
lineHeight: '100%',
backgroundColor: 'widget-selector-background',
border: 'none',
_hover: {
backgroundColor: 'widget-selector-hover-background'
}
}, color: "white", onClick: () => {
const percentageBuffer = (fromBalance * 50n) / 100n;
handleMaxAmountClicked(percentageBuffer, '50%');
}, children: "50%" }), (0, jsx_runtime_1.jsx)(index_js_1.Button, { "aria-label": "MAX", css: {
fontSize: 12,
fontWeight: '500',
px: '1',
py: '1',
minHeight: '23px',
lineHeight: '100%',
backgroundColor: 'widget-selector-background',
border: 'none',
_hover: {
backgroundColor: 'widget-selector-hover-background'
}
}, color: "white", onMouseEnter: () => {
if (fromChain?.vmType === 'evm' &&
publicClient &&
fromBalance) {
(0, nativeMaxAmount_js_1.getFeeBufferAmount)(fromChain.vmType, fromChain.id, fromBalance, publicClient);
}
else if (fromChain?.vmType === 'svm' &&
fromChain.id) {
(0, nativeMaxAmount_js_1.getFeeBufferAmount)(fromChain.vmType, fromChain.id, 0n, null);
}
}, onClick: async () => {
if (!fromBalance || !fromToken || !fromChain)
return;
let feeBufferAmount = 0n;
if (isFromNative) {
feeBufferAmount = await (0, nativeMaxAmount_js_1.getFeeBufferAmount)(fromChain.vmType, fromChain.id, fromBalance, publicClient ?? null);
}
const finalMaxAmount = isFromNative && feeBufferAmount > 0n
? fromBalance > feeBufferAmount
? fromBalance - feeBufferAmount
: 0n
: fromBalance;
handleMaxAmountClicked(finalMaxAmount, 'max', isFromNative ? feeBufferAmount : 0n);
}, children: "MAX" })] })) : null] })] })] }), (0, jsx_runtime_1.jsx)(index_js_1.Box, { css: {
position: 'relative',
my: -13,
mx: 'auto',
height: 32,
width: 32
}, children: hasLockedToken ||
((isSvmSwap || isBvmSwap) &&
!multiWalletSupportEnabled) ? null : ((0, jsx_runtime_1.jsx)(index_js_1.Button, { "aria-label": "Swap Tokens Direction", size: "none", color: "white", css: {
mt: '4px',
color: 'gray9',
alignSelf: 'center',
justifyContent: 'center',
width: '100%',
height: '100%',
'--borderWidth': 'borders.widget-swap-currency-button-border-width',
'--borderColor': 'colors.widget-swap-currency-button-border-color',
border: `var(--borderWidth) solid var(--borderColor)`,
zIndex: 10,
borderRadius: 'widget-swap-currency-button-border-radius'
}, onClick: () => {
if (fromToken || toToken) {
if (isUsdInputMode) {
handleSetFromToken(toToken);
handleSetToToken(fromToken);
const tempUsdInput = usdInputValue;
setUsdInputValue(usdOutputValue);
setUsdOutputValue(tempUsdInput);
setTradeType('EXACT_INPUT');
debouncedAmountInputControls.flush();
debouncedAmountOutputControls.flush();
}
else {
if (tradeType === 'EXACT_INPUT') {
setTradeType('EXPECTED_OUTPUT');
setAmountInputValue('');
setAmountOutputValue(amountInputValue);
}
else {
setTradeType('EXACT_INPUT');
setAmountOutputValue('');
setAmountInputValue(amountOutputValue);
}
handleSetFromToken(toToken);
handleSetToToken(fromToken);
debouncedAmountInputControls.flush();
debouncedAmountOutputControls.flush();
}
}
}, children: (0, jsx_runtime_1.jsx)(react_fontawesome_1.FontAwesomeIcon, { icon: free_solid_svg_icons_1.faArrowDown, width: 16, height: 16 }) })) }), (0, jsx_runtime_1.jsxs)(TokenSelectorContainer_js_1.default, { css: {
backgroundColor: 'widget-background',
mb: 'widget-card-section-gutter'
}, id: 'to-token-section', children: [(0, jsx_runtime_1.jsxs)(index_js_1.Flex, { css: { width: '100%' }, align: "center", justify: "between", children: [(0, jsx_runtime_1.jsx)(index_js_1.Text, { style: "subtitle2", color: "subtle", children: "Buy" }), multiWalletSupportEnabled &&
toChainWalletVMSupported ? ((0, jsx_runtime_1.jsx)(MultiWalletDropdown_js_1.MultiWalletDropdown, { context: "destination", disablePasteWalletAddressOption: disablePasteWalletAddressOption, selectedWalletAddress: recipient, onSelect: (wallet) => {