UNPKG

@reservoir0x/relay-kit-ui

Version:

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

735 lines 36.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const jsx_runtime_1 = require("react/jsx-runtime"); const react_1 = require("react"); const index_js_1 = require("../../hooks/index.js"); const viem_1 = require("viem"); const wagmi_1 = require("wagmi"); const experimental_1 = require("wagmi/experimental"); const react_query_1 = require("@tanstack/react-query"); const quote_js_1 = require("../../utils/quote.js"); const relay_kit_hooks_1 = require("@reservoir0x/relay-kit-hooks"); const events_js_1 = require("../../constants/events.js"); const RelayKitProvider_js_1 = require("../../providers/RelayKitProvider.js"); const address_js_1 = require("../../utils/address.js"); const relay_sdk_1 = require("@reservoir0x/relay-sdk"); const errors_js_1 = require("../../utils/errors.js"); const useSwapButtonCta_js_1 = require("../../hooks/widget/useSwapButtonCta.js"); const hashing_js_1 = require("../../utils/hashing.js"); const time_js_1 = require("../../utils/time.js"); const tokenPriceQueryOptions = { staleTime: 60 * 1000, refetchInterval: 30 * 1000, refetchOnWindowFocus: false }; const SwapWidgetRenderer = ({ transactionModalOpen, setTransactionModalOpen, depositAddressModalOpen, fromToken: _fromToken, setFromToken: _setFromToken, toToken: _toToken, setToToken: _setToToken, defaultToAddress, defaultAmount, defaultTradeType, slippageTolerance, context, wallet, multiWalletSupportEnabled = false, linkedWallets, supportedWalletVMs, children, onAnalyticEvent, onSwapError }) => { const [fromToken, setFromToken] = (0, index_js_1.useFallbackState)(_setFromToken ? _fromToken : undefined, _setFromToken ? [ _fromToken, _setFromToken ] : undefined); const [toToken, setToToken] = (0, index_js_1.useFallbackState)(_setToToken ? _toToken : undefined, _setToToken ? [_toToken, _setToToken] : undefined); const providerOptionsContext = (0, react_1.useContext)(RelayKitProvider_js_1.ProviderOptionsContext); const connectorKeyOverrides = providerOptionsContext.vmConnectorKeyOverrides; const relayClient = (0, index_js_1.useRelayClient)(); const { connector } = (0, wagmi_1.useAccount)(); const walletClient = (0, wagmi_1.useWalletClient)(); const [customToAddress, setCustomToAddress] = (0, react_1.useState)(defaultToAddress); const [useExternalLiquidity, setUseExternalLiquidity] = (0, react_1.useState)(false); const address = (0, index_js_1.useWalletAddress)(wallet, linkedWallets); const [tradeType, setTradeType] = (0, react_1.useState)(defaultTradeType ?? 'EXACT_INPUT'); const queryClient = (0, react_query_1.useQueryClient)(); const [steps, setSteps] = (0, react_1.useState)(null); const [quoteInProgress, setQuoteInProgress] = (0, react_1.useState)(null); const [waitingForSteps, setWaitingForSteps] = (0, react_1.useState)(false); const [details, setDetails] = (0, react_1.useState)(null); const [gasTopUpEnabled, setGasTopUpEnabled] = (0, react_1.useState)(false); const [abortController, setAbortController] = (0, react_1.useState)(null); const { value: amountInputValue, debouncedValue: debouncedInputAmountValue, setValue: setAmountInputValue, debouncedControls: debouncedAmountInputControls } = (0, index_js_1.useDebounceState)(!defaultTradeType || defaultTradeType === 'EXACT_INPUT' ? (defaultAmount ?? '') : '', 500); const { value: amountOutputValue, debouncedValue: debouncedOutputAmountValue, setValue: setAmountOutputValue, debouncedControls: debouncedAmountOutputControls } = (0, index_js_1.useDebounceState)(defaultTradeType === 'EXPECTED_OUTPUT' ? (defaultAmount ?? '') : '', 500); const [swapError, setSwapError] = (0, react_1.useState)(null); const tokenPairIsCanonical = fromToken?.chainId !== undefined && toToken?.chainId !== undefined && fromToken.symbol === toToken.symbol; const toChain = relayClient?.chains.find((chain) => chain.id === toToken?.chainId); const fromChain = relayClient?.chains?.find((chain) => chain.id === fromToken?.chainId); const fromChainWalletVMSupported = !fromChain?.vmType || supportedWalletVMs.includes(fromChain?.vmType) || fromChain?.id === 1337; const toChainWalletVMSupported = !toChain?.vmType || supportedWalletVMs.includes(toChain?.vmType); const defaultRecipient = (0, react_1.useMemo)(() => { const _linkedWallet = linkedWallets?.find((linkedWallet) => address === (linkedWallet.vmType === 'evm' ? linkedWallet.address.toLowerCase() : linkedWallet.address)); const _isValidToAddress = (0, address_js_1.isValidAddress)(toChain?.vmType, customToAddress ?? '', toChain?.id, !customToAddress && _linkedWallet?.address === address ? _linkedWallet?.connector : undefined, connectorKeyOverrides); if (multiWalletSupportEnabled && toChain && linkedWallets && !_isValidToAddress) { const supportedAddress = (0, address_js_1.findSupportedWallet)(toChain, customToAddress, linkedWallets, connectorKeyOverrides); return supportedAddress; } }, [ multiWalletSupportEnabled, toChain, customToAddress, address, linkedWallets, setCustomToAddress ]); const recipient = customToAddress ?? defaultRecipient ?? address; const { value: fromBalance, queryKey: fromBalanceQueryKey, isLoading: isLoadingFromBalance, isError: fromBalanceErrorFetching, isDuneBalance: fromBalanceIsDune, hasPendingBalance: fromBalancePending } = (0, index_js_1.useCurrencyBalance)({ chain: fromChain, address: address, currency: fromToken?.address ? fromToken.address : undefined, enabled: fromToken !== undefined, refreshInterval: undefined, wallet }); const { value: toBalance, queryKey: toBalanceQueryKey, isLoading: isLoadingToBalance, isDuneBalance: toBalanceIsDune, hasPendingBalance: toBalancePending } = (0, index_js_1.useCurrencyBalance)({ chain: toChain, address: recipient, currency: toToken?.address ? toToken.address : undefined, enabled: toToken !== undefined, refreshInterval: undefined, wallet }); const invalidateBalanceQueries = (0, react_1.useCallback)(() => { const invalidatePeriodically = (invalidateFn) => { let maxRefreshes = 4; let refreshCount = 0; const timer = setInterval(() => { if (maxRefreshes === refreshCount) { clearInterval(timer); return; } refreshCount++; invalidateFn(); }, 3000); }; queryClient.invalidateQueries({ queryKey: ['useDuneBalances'] }); if (fromBalanceIsDune) { invalidatePeriodically(() => { queryClient.invalidateQueries({ queryKey: fromBalanceQueryKey }); }); } else { queryClient.invalidateQueries({ queryKey: fromBalanceQueryKey }); } if (toBalanceIsDune) { invalidatePeriodically(() => { queryClient.invalidateQueries({ queryKey: toBalanceQueryKey }); }); } else { queryClient.invalidateQueries({ queryKey: toBalanceQueryKey }); } }, [ queryClient, fromBalanceQueryKey, toBalanceQueryKey, toBalanceIsDune, fromBalanceIsDune, address ]); const { data: capabilities } = (0, experimental_1.useCapabilities)({ query: { enabled: connector && (connector.id === 'coinbaseWalletSDK' || connector.id === 'coinbase') } }); const hasAuxiliaryFundsSupport = Boolean(fromToken?.chainId ? capabilities?.[fromToken?.chainId]?.auxiliaryFunds?.supported : false); const isSvmSwap = fromChain?.vmType === 'svm' || toChain?.vmType === 'svm'; const isBvmSwap = fromChain?.vmType === 'bvm' || toChain?.vmType === 'bvm'; const linkedWallet = linkedWallets?.find((linkedWallet) => address === (linkedWallet.vmType === 'evm' ? linkedWallet.address.toLowerCase() : linkedWallet.address) || linkedWallet.address === address); const isRecipientLinked = (recipient ? linkedWallets?.find((wallet) => wallet.address === recipient) : undefined) !== undefined; const isValidFromAddress = (0, address_js_1.isValidAddress)(fromChain?.vmType, address ?? '', fromChain?.id, linkedWallet?.connector, connectorKeyOverrides); const fromAddressWithFallback = (0, address_js_1.addressWithFallback)(fromChain?.vmType, address, fromChain?.id, linkedWallet?.connector, connectorKeyOverrides); const isValidToAddress = (0, address_js_1.isValidAddress)(toChain?.vmType, recipient ?? '', toChain?.id); const toAddressWithFallback = (0, address_js_1.addressWithFallback)(toChain?.vmType, recipient, toChain?.id); const externalLiquiditySupport = (0, relay_kit_hooks_1.useQuote)(relayClient ? relayClient : undefined, wallet, fromToken && toToken ? { user: (0, relay_sdk_1.getDeadAddress)(fromChain?.vmType, fromChain?.id), originChainId: fromToken.chainId, destinationChainId: toToken.chainId, originCurrency: fromToken.address, destinationCurrency: toToken.address, recipient: (0, relay_sdk_1.getDeadAddress)(toChain?.vmType, toChain?.id), tradeType, appFees: providerOptionsContext.appFees, amount: '10000000000000000000000', referrer: relayClient?.source ?? undefined, useExternalLiquidity: true } : undefined, undefined, undefined, { refetchOnWindowFocus: false, enabled: fromToken !== undefined && toToken !== undefined && fromChain && toChain && (fromChain.id === toChain.baseChainId || toChain.id === fromChain.baseChainId) }); const supportsExternalLiquidity = tokenPairIsCanonical && externalLiquiditySupport.status === 'success' && fromChainWalletVMSupported ? true : false; const { displayName: toDisplayName } = (0, index_js_1.useENSResolver)(recipient, { enabled: toChain?.vmType === 'evm' && isValidToAddress }); const [currentSlippageTolerance, setCurrentSlippageTolerance] = (0, react_1.useState)(slippageTolerance); (0, react_1.useEffect)(() => { setCurrentSlippageTolerance(slippageTolerance); }, [slippageTolerance]); const { required: gasTopUpRequired, amount: _gasTopUpAmount, amountUsd: _gasTopUpAmountUsd } = (0, index_js_1.useGasTopUpRequired)(toChain, fromChain, toToken, recipient); const { data: fromTokenPriceData, isLoading: isLoadingFromTokenPrice } = (0, relay_kit_hooks_1.useTokenPrice)(relayClient?.baseApiUrl, { address: fromToken?.address ?? '', chainId: fromToken?.chainId ?? 0, referrer: relayClient?.source }, { enabled: !!(fromToken?.address && fromToken.chainId), ...tokenPriceQueryOptions }); const { data: toTokenPriceData, isLoading: isLoadingToTokenPrice } = (0, relay_kit_hooks_1.useTokenPrice)(relayClient?.baseApiUrl, { address: toToken?.address ?? '', chainId: toToken?.chainId ?? 0, referrer: relayClient?.source }, { enabled: !!(toToken?.address && toToken.chainId), ...tokenPriceQueryOptions }); const originChainSupportsProtocolv2 = fromChain?.protocol?.v2?.depository !== undefined; const quoteProtocol = (0, react_1.useMemo)(() => { if (fromChain?.id && originChainSupportsProtocolv2) { if (!fromToken && !fromTokenPriceData) { return undefined; } const relevantPrice = fromTokenPriceData?.price && !isLoadingFromTokenPrice ? fromTokenPriceData.price : undefined; const amount = tradeType === 'EXACT_INPUT' ? debouncedInputAmountValue : debouncedOutputAmountValue; if (!amount) { return undefined; } const usdAmount = relevantPrice ? (0, quote_js_1.calculateUsdValue)(relevantPrice, amount) : undefined; return usdAmount !== undefined && usdAmount <= 100 ? 'preferV2' : undefined; } else { return undefined; } }, [ fromTokenPriceData, isLoadingFromTokenPrice, debouncedInputAmountValue, tradeType, originChainSupportsProtocolv2 ]); const loadingProtocolVersion = fromChain?.id && originChainSupportsProtocolv2 && isLoadingFromTokenPrice; const quoteParameters = fromToken && toToken ? { user: fromAddressWithFallback, originChainId: fromToken.chainId, destinationChainId: toToken.chainId, originCurrency: fromToken.address, destinationCurrency: toToken.address, recipient: toAddressWithFallback, tradeType, appFees: providerOptionsContext.appFees, amount: tradeType === 'EXACT_INPUT' ? (0, viem_1.parseUnits)(debouncedInputAmountValue, fromToken.decimals).toString() : (0, viem_1.parseUnits)(debouncedOutputAmountValue, toToken.decimals).toString(), referrer: relayClient?.source ?? undefined, useExternalLiquidity, useDepositAddress: !fromChainWalletVMSupported || fromToken?.chainId === 1337, refundTo: fromToken?.chainId === 1337 ? address : undefined, slippageTolerance: slippageTolerance, topupGas: gasTopUpEnabled && gasTopUpRequired, protocolVersion: quoteProtocol } : undefined; const onQuoteRequested = (options, config) => { const interval = (0, time_js_1.get15MinuteInterval)(); const quoteRequestId = (0, hashing_js_1.sha256)({ ...options, interval }); onAnalyticEvent?.(events_js_1.EventNames.QUOTE_REQUESTED, { parameters: options, wallet_connector: linkedWallet?.connector, chain_id_in: options?.originChainId, chain_id_out: options?.destinationChainId, http_config: config, quote_request_id: quoteRequestId }); }; const onQuoteReceived = ({ details, steps }, options) => { const interval = (0, time_js_1.get15MinuteInterval)(); const quoteRequestId = (0, hashing_js_1.sha256)({ ...options, interval }); onAnalyticEvent?.(events_js_1.EventNames.QUOTE_RECEIVED, { parameters: options, wallet_connector: linkedWallet?.connector, amount_in: details?.currencyIn?.amountFormatted, amount_in_raw: details?.currencyIn?.amount, currency_in: details?.currencyIn?.currency?.symbol, chain_id_in: details?.currencyIn?.currency?.chainId, amount_out: details?.currencyOut?.amountFormatted, amount_out_raw: details?.currencyOut?.amount, currency_out: details?.currencyOut?.currency?.symbol, chain_id_out: details?.currencyOut?.currency?.chainId, slippage_tolerance_destination_percentage: details?.slippageTolerance?.destination?.percent, slippage_tolerance_origin_percentage: details?.slippageTolerance?.origin?.percent, steps, quote_request_id: quoteRequestId, quote_id: steps ? (0, quote_js_1.extractQuoteId)(steps) : undefined }); }; const quoteFetchingEnabled = Boolean(relayClient && ((tradeType === 'EXACT_INPUT' && debouncedInputAmountValue && debouncedInputAmountValue.length > 0 && Number(debouncedInputAmountValue) !== 0) || (tradeType === 'EXPECTED_OUTPUT' && debouncedOutputAmountValue && debouncedOutputAmountValue.length > 0 && Number(debouncedOutputAmountValue) !== 0)) && fromToken !== undefined && toToken !== undefined && !transactionModalOpen && !depositAddressModalOpen && !loadingProtocolVersion); const { data: _quoteData, error: quoteError, isFetching: isFetchingQuote, executeQuote: executeSwap, queryKey: quoteQueryKey } = (0, relay_kit_hooks_1.useQuote)(relayClient ? relayClient : undefined, wallet, quoteParameters, onQuoteRequested, onQuoteReceived, { refetchOnWindowFocus: false, enabled: quoteFetchingEnabled, refetchInterval: !transactionModalOpen && !depositAddressModalOpen && debouncedInputAmountValue === amountInputValue && debouncedOutputAmountValue === amountOutputValue ? 12000 : undefined }, (e) => { const errorMessage = (0, errors_js_1.errorToJSON)(e?.response?.data?.message ? new Error(e?.response?.data?.message) : e); const interval = (0, time_js_1.get15MinuteInterval)(); const quoteRequestId = (0, hashing_js_1.sha256)({ ...quoteParameters, interval }); onAnalyticEvent?.(events_js_1.EventNames.QUOTE_ERROR, { wallet_connector: linkedWallet?.connector, error_message: errorMessage, parameters: quoteParameters, quote_request_id: quoteRequestId, status_code: e.response.status ?? e.status ?? '' }); }); const invalidateQuoteQuery = (0, react_1.useCallback)(() => { queryClient.invalidateQueries({ queryKey: quoteQueryKey }); }, [queryClient, quoteQueryKey]); let error = _quoteData || (isFetchingQuote && quoteFetchingEnabled) ? null : quoteError; let quote = error ? undefined : _quoteData; const gasTopUpAmount = quote?.details?.currencyGasTopup?.amount ? BigInt(quote?.details?.currencyGasTopup?.amount) : _gasTopUpAmount; const gasTopUpAmountUsd = quote?.details?.currencyGasTopup?.amountUsd ?? _gasTopUpAmountUsd; (0, index_js_1.useDisconnected)(address, () => { setCustomToAddress(undefined); }); (0, react_1.useEffect)(() => { if (tradeType === 'EXACT_INPUT') { const amountOut = quote?.details?.currencyOut?.amount ?? ''; setAmountOutputValue(amountOut !== '' ? (0, viem_1.formatUnits)(BigInt(amountOut), Number(quote?.details?.currencyOut?.currency?.decimals ?? 18)) : ''); } else if (tradeType === 'EXPECTED_OUTPUT') { const amountIn = quote?.details?.currencyIn?.amount ?? ''; setAmountInputValue(amountIn !== '' ? (0, viem_1.formatUnits)(BigInt(amountIn), Number(quote?.details?.currencyIn?.currency?.decimals ?? 18)) : ''); } debouncedAmountInputControls.flush(); debouncedAmountOutputControls.flush(); }, [quote, tradeType]); (0, react_1.useEffect)(() => { if (useExternalLiquidity && !externalLiquiditySupport.isFetching && !supportsExternalLiquidity) { setUseExternalLiquidity(false); } }, [ supportsExternalLiquidity, useExternalLiquidity, externalLiquiditySupport.isFetching ]); const feeBreakdown = (0, react_1.useMemo)(() => { const chains = relayClient?.chains; const fromChain = chains?.find((chain) => chain.id === fromToken?.chainId); const toChain = chains?.find((chain) => chain.id === toToken?.chainId); return fromToken && toToken && fromChain && toChain && quote ? (0, quote_js_1.parseFees)(toChain, fromChain, quote) : null; }, [quote, fromToken, toToken, relayClient]); const totalAmount = BigInt(quote?.details?.currencyIn?.amount ?? 0n); const hasInsufficientBalance = Boolean(!fromBalanceErrorFetching && totalAmount && address && (fromBalance ?? 0n) < totalAmount && !hasAuxiliaryFundsSupport && fromChainWalletVMSupported); const fetchQuoteErrorMessage = error ? error?.message ? error?.message : 'Unknown Error' : null; const fetchQuoteDataErrorMessage = error ? error?.response?.data?.message ? error?.response?.data.message : 'Unknown Error' : null; const isInsufficientLiquidityError = Boolean(fetchQuoteErrorMessage?.includes('No quotes available')); const isCapacityExceededError = fetchQuoteDataErrorMessage?.includes('Amount is higher than the available liquidity') || fetchQuoteDataErrorMessage?.includes('Insufficient relayer liquidity'); const isCouldNotExecuteError = fetchQuoteDataErrorMessage?.includes('Could not execute'); const highRelayerServiceFee = (0, quote_js_1.isHighRelayerServiceFeeUsd)(quote); const relayerFeeProportion = (0, quote_js_1.calculateRelayerFeeProportionUsd)(quote); const timeEstimate = (0, quote_js_1.calculatePriceTimeEstimate)(quote?.details); const canonicalTimeEstimate = (0, quote_js_1.calculatePriceTimeEstimate)(externalLiquiditySupport.data?.details); const recipientWalletSupportsChain = (0, index_js_1.useIsWalletCompatible)(toChain?.id, recipient, linkedWallets, onAnalyticEvent); const isFromNative = fromToken?.address === fromChain?.currency?.address; const isSameCurrencySameRecipientSwap = fromToken?.address === toToken?.address && fromToken?.chainId === toToken?.chainId && address === recipient; const ctaCopy = (0, useSwapButtonCta_js_1.useSwapButtonCta)({ fromToken, toToken, multiWalletSupportEnabled, isValidFromAddress, fromChainWalletVMSupported, isValidToAddress, toChainWalletVMSupported, fromChain, toChain, isSameCurrencySameRecipientSwap, debouncedInputAmountValue, debouncedOutputAmountValue, hasInsufficientBalance, isInsufficientLiquidityError, quote, operation: quote?.details?.operation }); (0, index_js_1.usePreviousValueChange)(isCapacityExceededError && supportsExternalLiquidity, !isFetchingQuote && !externalLiquiditySupport.isFetching, (capacityExceeded) => { if (capacityExceeded) { onAnalyticEvent?.(events_js_1.EventNames.CTA_MAX_CAPACITY_PROMPTED, { inputAmount: debouncedInputAmountValue, outputAmount: debouncedOutputAmountValue }); } }); const swap = (0, react_1.useCallback)(async () => { let submittedEvents = []; const swapErrorHandler = (error, currentSteps) => { const errorMessage = (0, errors_js_1.errorToJSON)(error?.response?.data?.message ? new Error(error?.response?.data?.message) : error); if (error && ((typeof error.message === 'string' && error.message.includes('rejected')) || (typeof error === 'string' && error.includes('rejected')) || (typeof error === 'string' && error.includes('Approval Denied')) || (typeof error === 'string' && error.includes('denied transaction')) || (typeof error.message === 'string' && error.message.includes('Approval Denied')) || (typeof error.message === 'string' && error.message.includes('Plugin Closed')) || (typeof error.message === 'string' && error.message.includes('denied transaction')) || (typeof error.message === 'string' && error.message.includes('Failed to initialize request') && fromChain?.id === 2741))) { setTransactionModalOpen(false); onAnalyticEvent?.(events_js_1.EventNames.USER_REJECTED_WALLET, { error_message: errorMessage }); return; } const { step, stepItem } = (0, quote_js_1.getCurrentStep)(currentSteps); const swapEventData = { ...(0, quote_js_1.getSwapEventData)(quote?.details, currentSteps ?? null, linkedWallet?.connector, quoteParameters), error_message: errorMessage }; const isApproval = step?.id === 'approve'; const errorEvent = isApproval ? events_js_1.EventNames.APPROVAL_ERROR : events_js_1.EventNames.DEPOSIT_ERROR; const isTransactionConfirmationError = (error && typeof error.message === 'string' && error.message.includes('TransactionConfirmationError')) || (error.name && error.name.includes('TransactionConfirmationError')); if (stepItem?.receipt && stepItem.check && !isTransactionConfirmationError && (typeof stepItem.receipt === 'object' && 'status' in stepItem.receipt ? stepItem.receipt.status !== 'reverted' : true) && (!stepItem.checkStatus || stepItem.checkStatus !== 'unknown')) { const successEvent = isApproval ? events_js_1.EventNames.APPROVAL_SUCCESS : events_js_1.EventNames.DEPOSIT_SUCCESS; if (!submittedEvents.includes(successEvent)) { onAnalyticEvent?.(successEvent, swapEventData); submittedEvents.push(successEvent); setTimeout(() => { onAnalyticEvent?.(events_js_1.EventNames.FILL_ERROR, swapEventData); }, 20); } else { onAnalyticEvent?.(events_js_1.EventNames.FILL_ERROR, swapEventData); } } else if (!stepItem?.receipt || (typeof stepItem.receipt === 'object' && 'status' in stepItem.receipt && stepItem.receipt.status === 'reverted')) { onAnalyticEvent?.(errorEvent, swapEventData); } else { onAnalyticEvent?.(events_js_1.EventNames.SWAP_ERROR, swapEventData); } setSwapError(errorMessage); onSwapError?.(errorMessage, { ...quote, steps: currentSteps }); }; try { const swapEventData = (0, quote_js_1.getSwapEventData)(quote?.details, quote?.steps ? quote?.steps : null, linkedWallet?.connector, quoteParameters); onAnalyticEvent?.(events_js_1.EventNames.SWAP_CTA_CLICKED, swapEventData); setWaitingForSteps(true); if (!executeSwap) { throw 'Missing a quote'; } if (!wallet && !walletClient.data) { throw 'Missing a wallet'; } setSteps(quote?.steps); setQuoteInProgress(quote); setTransactionModalOpen(true); const _wallet = wallet ?? (0, relay_sdk_1.adaptViemWallet)(walletClient.data); const activeWalletChainId = await _wallet?.getChainId(); const activeWalletChain = relayClient?.chains?.find((chain) => chain.id === activeWalletChainId); let targetChainId = fromToken?.chainId; if (fromToken?.chainId === 1337) { targetChainId = activeWalletChain?.vmType !== 'evm' ? 1 : activeWalletChainId; } if (fromToken && targetChainId && targetChainId !== activeWalletChainId) { onAnalyticEvent?.(events_js_1.EventNames.SWAP_SWITCH_NETWORK, { activeWalletChainId, ...swapEventData }); await _wallet?.switchChain(targetChainId); } let _currentSteps = undefined; const execPromise = executeSwap(({ steps: currentSteps }) => { setSteps(currentSteps); _currentSteps = currentSteps; const { step, stepItem } = (0, quote_js_1.getCurrentStep)(currentSteps); const swapEventData = (0, quote_js_1.getSwapEventData)(quote?.details, currentSteps, linkedWallet?.connector, quoteParameters); if (step && stepItem) { const isApproval = step.id === 'approve' || step.id === 'approval'; let submittedEvent = isApproval ? events_js_1.EventNames.APPROVAL_SUBMITTED : events_js_1.EventNames.DEPOSIT_SUBMITTED; const successEvent = isApproval ? events_js_1.EventNames.APPROVAL_SUCCESS : events_js_1.EventNames.DEPOSIT_SUCCESS; const isBatchTransaction = Boolean(Array.isArray(step.items) && step.items.length > 1 && wallet?.handleBatchTransactionStep); if (!isApproval && isBatchTransaction) { submittedEvent = events_js_1.EventNames.BATCH_TX_SUBMITTED; } if (!submittedEvents.includes(submittedEvent) && !stepItem.receipt && stepItem?.txHashes && stepItem?.txHashes?.length > 0) { submittedEvents.push(submittedEvent); onAnalyticEvent?.(submittedEvent, swapEventData); } else if ((!submittedEvents.includes(successEvent) && stepItem.receipt && !(typeof stepItem.receipt === 'object' && 'status' in stepItem.receipt && stepItem.receipt.status === 'reverted')) || stepItem.checkStatus === 'pending') { onAnalyticEvent?.(successEvent, swapEventData); submittedEvents.push(successEvent); } if (stepItem.status === 'complete' && stepItem.check && !submittedEvents.includes(events_js_1.EventNames.FILL_SUCCESS)) { if (!submittedEvents.includes(events_js_1.EventNames.DEPOSIT_SUCCESS) && !isBatchTransaction) { onAnalyticEvent?.(events_js_1.EventNames.DEPOSIT_SUCCESS, swapEventData); submittedEvents.push(events_js_1.EventNames.DEPOSIT_SUCCESS); setTimeout(() => { onAnalyticEvent?.(events_js_1.EventNames.FILL_SUCCESS, swapEventData); }, 20); } else { onAnalyticEvent?.(events_js_1.EventNames.FILL_SUCCESS, swapEventData); } submittedEvents.push(events_js_1.EventNames.FILL_SUCCESS); } } else if (currentSteps?.every((step) => step.items?.every((item) => item.status === 'complete')) && !submittedEvents.includes(events_js_1.EventNames.FILL_SUCCESS)) { if (!submittedEvents.includes(events_js_1.EventNames.DEPOSIT_SUCCESS) && !submittedEvents.includes(events_js_1.EventNames.BATCH_TX_SUBMITTED)) { onAnalyticEvent?.(events_js_1.EventNames.DEPOSIT_SUCCESS, swapEventData); submittedEvents.push(events_js_1.EventNames.DEPOSIT_SUCCESS); setTimeout(() => { onAnalyticEvent?.(events_js_1.EventNames.FILL_SUCCESS, swapEventData); }, 20); } else { onAnalyticEvent?.(events_js_1.EventNames.FILL_SUCCESS, swapEventData); } submittedEvents.push(events_js_1.EventNames.FILL_SUCCESS); } }); if (execPromise && typeof execPromise === 'object' && 'abortController' in execPromise) { setAbortController(execPromise.abortController); } execPromise ?.catch((error) => { swapErrorHandler(error, _currentSteps); }) .finally(() => { setWaitingForSteps(false); setAbortController(null); invalidateBalanceQueries(); }); } catch (error) { swapErrorHandler(error); setWaitingForSteps(false); } }, [ relayClient, address, connector, wallet, walletClient, fromToken, toToken, customToAddress, recipient, debouncedInputAmountValue, debouncedOutputAmountValue, tradeType, useExternalLiquidity, waitingForSteps, executeSwap, setSteps, setQuoteInProgress, invalidateBalanceQueries, linkedWallet, abortController ]); return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: children({ quote, steps, setSteps, swap, transactionModalOpen, feeBreakdown, fromToken, setFromToken, toToken, setToToken, swapError, error, toDisplayName, address, recipient, customToAddress, setCustomToAddress, tradeType, setTradeType, details, isSameCurrencySameRecipientSwap, debouncedInputAmountValue, debouncedAmountInputControls, setAmountInputValue, amountInputValue, amountOutputValue, debouncedOutputAmountValue, debouncedAmountOutputControls, setAmountOutputValue, toBalance, toBalancePending, isLoadingToBalance, isFetchingQuote, isLoadingFromBalance, fromBalance, fromBalancePending, highRelayerServiceFee, relayerFeeProportion, hasInsufficientBalance, isInsufficientLiquidityError, isCapacityExceededError, isCouldNotExecuteError, ctaCopy, isFromNative, useExternalLiquidity, slippageTolerance: currentSlippageTolerance, supportsExternalLiquidity, timeEstimate, canonicalTimeEstimate, fetchingExternalLiquiditySupport: externalLiquiditySupport.isFetching, isSvmSwap, isBvmSwap, isValidFromAddress, isValidToAddress, supportedWalletVMs, fromChainWalletVMSupported, toChainWalletVMSupported, isRecipientLinked, recipientWalletSupportsChain, gasTopUpEnabled, setGasTopUpEnabled, gasTopUpRequired, gasTopUpAmount, gasTopUpAmountUsd, invalidateBalanceQueries, invalidateQuoteQuery, setUseExternalLiquidity, setDetails, setSwapError, quoteInProgress, setQuoteInProgress, linkedWallet, quoteParameters, abortController, fromTokenPriceData, toTokenPriceData, isLoadingFromTokenPrice, isLoadingToTokenPrice }) })); }; exports.default = SwapWidgetRenderer; //# sourceMappingURL=SwapWidgetRenderer.js.map