UNPKG

@reservoir0x/relay-kit-ui

Version:

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

286 lines 15.8 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.OnrampModal = exports.OnrampProcessingStep = exports.OnrampStep = void 0; const tslib_1 = require("tslib"); const jsx_runtime_1 = require("react/jsx-runtime"); const relay_sdk_1 = require("@reservoir0x/relay-sdk"); const react_1 = require("react"); const Modal_js_1 = require("../../../common/Modal.js"); const useRelayClient_js_1 = tslib_1.__importDefault(require("../../../../hooks/useRelayClient.js")); const events_js_1 = require("../../../../constants/events.js"); const relay_kit_hooks_1 = require("@reservoir0x/relay-kit-hooks"); const relayTransaction_js_1 = require("../../../../utils/relayTransaction.js"); const viem_1 = require("viem"); const quote_js_1 = require("../../../../utils/quote.js"); const getTxBlockExplorerUrl_js_1 = require("../../../../utils/getTxBlockExplorerUrl.js"); const OnrampConfirmingStep_js_1 = require("./steps/OnrampConfirmingStep.js"); const OnrampProcessingStepUI_js_1 = require("./steps/OnrampProcessingStepUI.js"); const OnrampProcessingPassthroughStep_js_1 = require("./steps/OnrampProcessingPassthroughStep.js"); const OnrampSuccessStep_js_1 = require("./steps/OnrampSuccessStep.js"); const OnrampMoonPayStep_js_1 = require("./steps/OnrampMoonPayStep.js"); const numbers_js_1 = require("../../../../utils/numbers.js"); const ErrorStep_js_1 = require("../../../common/TransactionModal/steps/ErrorStep.js"); const errors_js_1 = require("../../../../utils/errors.js"); const wagmi_1 = require("wagmi"); const chains_1 = require("viem/chains"); var OnrampStep; (function (OnrampStep) { OnrampStep[OnrampStep["Confirming"] = 0] = "Confirming"; OnrampStep[OnrampStep["Moonpay"] = 1] = "Moonpay"; OnrampStep[OnrampStep["Processing"] = 2] = "Processing"; OnrampStep[OnrampStep["ProcessingPassthrough"] = 3] = "ProcessingPassthrough"; OnrampStep[OnrampStep["Success"] = 4] = "Success"; OnrampStep[OnrampStep["Error"] = 5] = "Error"; })(OnrampStep || (exports.OnrampStep = OnrampStep = {})); var OnrampProcessingStep; (function (OnrampProcessingStep) { OnrampProcessingStep[OnrampProcessingStep["Finalizing"] = 0] = "Finalizing"; OnrampProcessingStep[OnrampProcessingStep["Relaying"] = 1] = "Relaying"; })(OnrampProcessingStep || (exports.OnrampProcessingStep = OnrampProcessingStep = {})); const OnrampModal = ({ open, amount, amountFormatted, recipient, fromToken, toToken, toChain, fromChain, fiatCurrency, isPassthrough, amountToTokenFormatted, moonPayCurrencyCode, usdRate, moonPayThemeId, moonPayThemeMode, moonPayApiKey, moonpayOnUrlSignatureRequested, onAnalyticEvent, onSuccess, onError, onOpenChange }) => { const [swapError, setSwapError] = (0, react_1.useState)(null); const [step, setStep] = (0, react_1.useState)(OnrampStep.Confirming); const [processingStep, setProcessingStep] = (0, react_1.useState)(); const [moonPayRequestId, setMoonPayRequestId] = (0, react_1.useState)(); const client = (0, useRelayClient_js_1.default)(); const { connector } = (0, wagmi_1.useAccount)(); const [moonPayIdAppended, setMoonPayIdAppended] = (0, react_1.useState)(false); const { data: ethTokenPriceResponse } = (0, relay_kit_hooks_1.useTokenPrice)(client?.baseApiUrl, { address: viem_1.zeroAddress, chainId: chains_1.mainnet.id, referrer: client?.source }, { refetchInterval: 60000 * 5, refetchOnWindowFocus: false }); const [passthroughExternalId, setPassthroughExternalId] = (0, react_1.useState)(); (0, react_1.useEffect)(() => { if (!open) { setStep(OnrampStep.Confirming); setProcessingStep(undefined); setMoonPayRequestId(undefined); setMoonPayIdAppended(false); setSwapError(null); setPassthroughExternalId(undefined); } else { if (isPassthrough) { setStep(OnrampStep.Moonpay); setPassthroughExternalId(`${recipient ? recipient.slice(recipient.length - 5) : ''}${Date.now()}`); } onAnalyticEvent?.(events_js_1.EventNames.ONRAMP_MODAL_OPEN, { isPassthrough }); } }, [open]); const ethAmount = ethTokenPriceResponse && ethTokenPriceResponse.price ? +(amount ?? '0') / ethTokenPriceResponse.price : 0; const { data: quote, error: quoteError, isFetching: isFetchingQuote } = (0, relay_kit_hooks_1.useQuote)(client ?? undefined, undefined, { originChainId: fromToken.chainId, originCurrency: fromToken.address, destinationChainId: toToken.chainId, destinationCurrency: toToken.address, useDepositAddress: true, tradeType: 'EXACT_INPUT', amount: fromToken.symbol === 'USDC' ? (0, viem_1.parseUnits)(`${amount}`, 6).toString() : (0, viem_1.parseUnits)(`${ethAmount}`, fromToken.decimals).toString(), user: (0, relay_sdk_1.getDeadAddress)(), recipient }, undefined, undefined, { refetchOnMount: false, refetchOnWindowFocus: false, refetchOnReconnect: false, enabled: Boolean(amount && amount.length > 0 && toToken && fromToken && !isPassthrough && recipient !== undefined && open) }); const totalAmount = quote?.fees && amount && !isPassthrough ? `${Math.floor((Number(quote.fees.relayer?.amountUsd ?? 0) + Number(quote.fees.gas?.amountUsd ?? 0) + Number(quote.fees.app?.amountUsd ?? 0) + +amount) * 100) / 100}` : amount; const ethTotalAmount = (0, numbers_js_1.formatBN)(totalAmount ? +totalAmount / (ethTokenPriceResponse?.price ?? 0) : 0, 5, 18); const toTokenTotalAmount = (0, numbers_js_1.formatBN)(+(totalAmount ?? '0') / (usdRate ?? 0), 5, toToken.decimals); const depositAddress = (0, react_1.useMemo)(() => (0, quote_js_1.extractDepositAddress)(quote?.steps), [quote]); const baseTransactionUrl = client?.baseApiUrl.includes('testnets') ? 'https://testnets.relay.link' : 'https://relay.link'; const requestId = (0, react_1.useMemo)(() => (0, relayTransaction_js_1.extractDepositRequestId)(quote?.steps), [quote]); const { data: executionStatus } = (0, relay_kit_hooks_1.useExecutionStatus)(client ? client : undefined, { requestId: requestId ?? undefined, referrer: client?.source }, undefined, undefined, { enabled: requestId !== null && step === OnrampStep.Processing && open, refetchInterval(query) { const observableStates = ['waiting', 'pending', 'delayed']; if (!query.state.data?.status || (requestId && observableStates.includes(query.state.data?.status))) { return 1000; } return 0; } }); const fillTxHash = (0, react_1.useMemo)(() => { if (executionStatus?.txHashes && executionStatus?.txHashes[0]) { return executionStatus?.txHashes[0]; } }, [executionStatus]); const { data: transactions, isLoading: isLoadingTransaction } = (0, relay_kit_hooks_1.useRequests)(step === OnrampStep.Success && fillTxHash ? { user: recipient, hash: fillTxHash } : undefined, client?.baseApiUrl, { enabled: Boolean(step === OnrampStep.Success && fillTxHash), refetchOnWindowFocus: false, refetchOnReconnect: false, refetchInterval: false, retryOnMount: false }); const transaction = transactions && transactions[0] ? transactions[0] : null; const toAmountFormatted = transaction?.data?.metadata?.currencyOut ?.amountFormatted ? ((0, numbers_js_1.formatBN)(+transaction.data.metadata.currencyOut.amountFormatted, 5, transaction?.data?.metadata?.currencyOut?.currency?.decimals ?? 18) ?? undefined) : amountToTokenFormatted; const fillTxUrl = fillTxHash ? (0, getTxBlockExplorerUrl_js_1.getTxBlockExplorerUrl)(toToken.chainId, client?.chains, fillTxHash) : undefined; const moonpayTxUrl = moonPayRequestId ? `https://buy.moonpay.com/transaction_receipt?transactionId=${moonPayRequestId}` : null; (0, react_1.useEffect)(() => { if (executionStatus?.status === 'pending' && (step !== OnrampStep.Processing || processingStep !== OnrampProcessingStep.Relaying)) { setStep(OnrampStep.Processing); setProcessingStep(OnrampProcessingStep.Relaying); } if (executionStatus?.status === 'success') { setStep(OnrampStep.Success); onAnalyticEvent?.(events_js_1.EventNames.ONRAMP_SUCCESS, { chain_id_in: fromToken?.chainId, currency_in: fromToken?.symbol, chain_id_out: toToken?.chainId, currency_out: toToken?.symbol, quote_id: requestId, txHashes: executionStatus.txHashes, amount, totalAmount, ethTotalAmount, moonPayRequestId, isPassthrough }); onSuccess?.(quote, moonPayRequestId); setProcessingStep(undefined); } if (executionStatus?.status === 'failure' || executionStatus?.status === 'refund' || quoteError) { const swapError = new Error(executionStatus?.details ?? 'Oops! Something went wrong while processing your transaction.'); onOnrampError((0, errors_js_1.errorToJSON)(executionStatus?.details ?? quoteError), swapError); } }, [executionStatus, quoteError]); (0, react_1.useEffect)(() => { if (moonPayRequestId && quote && executionStatus?.inTxHashes && executionStatus?.inTxHashes[0] && !moonPayIdAppended) { setMoonPayIdAppended(true); (0, quote_js_1.appendMetadataToRequest)(client?.baseApiUrl, `${requestId}`, { moonPayId: moonPayRequestId }, client?.source) ?.then(() => { client?.log(['Posting MoonPay request id', moonPayRequestId, requestId], relay_sdk_1.LogLevel.Verbose); }) .catch((e) => { setMoonPayIdAppended(false); throw e; }); } }, [moonPayRequestId, executionStatus]); const allTxHashes = (0, react_1.useMemo)(() => { const isRefund = executionStatus?.status === 'refund'; const _allTxHashes = []; executionStatus?.txHashes?.forEach((txHash) => { _allTxHashes.push({ txHash, chainId: isRefund ? fromToken?.chainId : toToken?.chainId }); }); executionStatus?.inTxHashes?.forEach((txHash) => { _allTxHashes.push({ txHash, chainId: fromToken?.chainId }); }); return _allTxHashes; }, [executionStatus?.txHashes, executionStatus?.inTxHashes]); const onOnrampError = (0, react_1.useCallback)((errorMsg, error) => { if (step !== OnrampStep.Error) { onError?.(error.message, quote, moonPayRequestId); } setStep(OnrampStep.Error); onAnalyticEvent?.(events_js_1.EventNames.ONRAMP_ERROR, { error_message: errorMsg, wallet_connector: connector?.name, quote_id: requestId, amount_in: amount, currency_in: fromToken?.symbol, chain_id_in: fromToken?.chainId, amount_out: quote?.details?.currencyOut?.amountFormatted, currency_out: toToken?.symbol, chain_id_out: toToken?.chainId, txHashes: executionStatus?.txHashes ?? [] }); setSwapError(error); }, [ executionStatus, connector, requestId, quote, toToken, fromToken, amount, swapError, moonPayRequestId, step ]); return ((0, jsx_runtime_1.jsxs)(Modal_js_1.Modal, { trigger: null, open: open, onOpenChange: (open) => { if (!open) { onAnalyticEvent?.(events_js_1.EventNames.ONRAMP_MODAL_CLOSE); } onOpenChange(open); }, css: { overflow: 'hidden', p: '4', maxWidth: '412px !important' }, children: [step === OnrampStep.Confirming ? ((0, jsx_runtime_1.jsx)(OnrampConfirmingStep_js_1.OnrampConfirmingStep, { toToken: toToken, fromToken: fromToken, fromChain: fromChain, toChain: toChain, requestId: requestId ?? undefined, depositAddress: depositAddress, recipient: recipient, amount: amount, totalAmount: totalAmount ?? undefined, ethTotalAmount: ethTotalAmount, isFetchingQuote: isFetchingQuote, onAnalyticEvent: onAnalyticEvent, setStep: setStep })) : null, (0, jsx_runtime_1.jsx)(OnrampMoonPayStep_js_1.OnrampMoonPayStep, { step: step, processingStep: processingStep, toToken: toToken, fromToken: fromToken, fromChain: fromChain, toChain: toChain, recipient: recipient, depositAddress: depositAddress, totalAmount: isPassthrough ? toTokenTotalAmount : fromToken.symbol === 'ETH' ? ethTotalAmount : (totalAmount ?? undefined), fiatCurrency: fiatCurrency, isPassthrough: isPassthrough, moonPayCurrencyCode: moonPayCurrencyCode, onAnalyticEvent: onAnalyticEvent, setStep: setStep, setProcessingStep: setProcessingStep, setMoonPayRequestId: setMoonPayRequestId, moonpayOnUrlSignatureRequested: moonpayOnUrlSignatureRequested, onPassthroughSuccess: () => { setStep(OnrampStep.Success); onAnalyticEvent?.(events_js_1.EventNames.ONRAMP_PASSTHROUGH_SUCCESS, { moonPayRequestId, amount, totalAmount, ethTotalAmount }); }, moonPayThemeId: moonPayThemeId, moonPayThemeMode: moonPayThemeMode, moonPayApiKey: moonPayApiKey, quoteRequestId: requestId, passthroughExternalId: passthroughExternalId, onError: (error) => { onOnrampError(error.message, error); } }), step === OnrampStep.ProcessingPassthrough ? ((0, jsx_runtime_1.jsx)(OnrampProcessingPassthroughStep_js_1.OnrampProcessingPassthroughStep, { toToken: toToken, amountToTokenFormatted: amountToTokenFormatted, moonpayTxUrl: moonpayTxUrl ?? undefined, amount: amountFormatted })) : null, step === OnrampStep.Processing ? ((0, jsx_runtime_1.jsx)(OnrampProcessingStepUI_js_1.OnrampProcessingStepUI, { toToken: toToken, fromToken: fromToken, fromChain: fromChain, toChain: toChain, moonpayTxUrl: moonpayTxUrl ?? undefined, fillTxUrl: fillTxUrl, fillTxHash: fillTxHash, processingStep: processingStep, baseTransactionUrl: baseTransactionUrl, requestId: requestId ?? undefined })) : null, step === OnrampStep.Success ? ((0, jsx_runtime_1.jsx)(OnrampSuccessStep_js_1.OnrampSuccessStep, { toToken: toToken, isLoadingTransaction: isLoadingTransaction, fillTxHash: fillTxHash, fillTxUrl: fillTxUrl, moonpayTxUrl: moonpayTxUrl ?? undefined, toAmountFormatted: toAmountFormatted, baseTransactionUrl: baseTransactionUrl, onOpenChange: onOpenChange })) : null, step === OnrampStep.Error ? ((0, jsx_runtime_1.jsx)(ErrorStep_js_1.ErrorStep, { error: quoteError || swapError, allTxHashes: allTxHashes, address: recipient, onOpenChange: onOpenChange, transaction: transaction ?? undefined, fromChain: fromChain, toChain: toChain })) : null] })); }; exports.OnrampModal = OnrampModal; //# sourceMappingURL=OnrampModal.js.map