UNPKG

@lifi/widget

Version:

LI.FI Widget for cross-chain bridging and swapping. It will drive your multi-chain strategy and attract new users from everywhere.

111 lines 5.04 kB
import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { useAddressValidation } from '../../hooks/useAddressValidation.js'; import { useSendToWalletActions } from '../../stores/settings/useSendToWalletStore.js'; import { formatInputAmount } from '../../utils/format.js'; import { useBookmarkActions } from '../bookmarks/useBookmarkActions.js'; import { useFieldActions } from '../form/useFieldActions.js'; import { useFieldValues } from '../form/useFieldValues.js'; import { useTouchedFields } from '../form/useTouchedFields.js'; const formValueKeys = [ 'fromAmount', 'fromChain', 'fromToken', 'toAddress', 'toChain', 'toToken', ]; const getDefaultValuesFromQueryString = () => { const searchParams = Object.fromEntries(new URLSearchParams(window?.location.search)); ['from', 'to'].forEach((key) => { if (searchParams[`${key}Token`] && !searchParams[`${key}Chain`]) { delete searchParams[`${key}Token`]; } }); return { ...(Number.isFinite(Number.parseInt(searchParams.fromChain, 10)) ? { fromChain: Number.parseInt(searchParams.fromChain, 10) } : {}), ...(Number.isFinite(Number.parseInt(searchParams.toChain, 10)) ? { toChain: Number.parseInt(searchParams.toChain, 10) } : {}), ...(searchParams.fromToken ? { fromToken: searchParams.fromToken } : {}), ...(searchParams.toToken ? { toToken: searchParams.toToken } : {}), ...(Number.isFinite(Number.parseFloat(searchParams.fromAmount)) ? { fromAmount: formatInputAmount(searchParams.fromAmount) } : {}), ...(searchParams.toAddress ? { toAddress: searchParams.toAddress } : {}), }; }; export const URLSearchParamsBuilder = () => { const { pathname } = useLocation(); const touchedFields = useTouchedFields(); const values = useFieldValues(...formValueKeys); const { setSendToWallet } = useSendToWalletActions(); const { setSelectedBookmark, addRecentWallet } = useBookmarkActions(); const { validateAddress } = useAddressValidation(); // Using these methods as trying to use the touchedFields and values above // often has a lag that can effect the widgets initialisation sequence // and accidentally cause values to be wiped from the query string const { getFieldValues, isTouched, setUserAndDefaultValues } = useFieldActions(); useEffect(() => { // get the initial values from the querystring const formValues = getDefaultValuesFromQueryString(); /** * When URL builder is enabled and user opens a page with toAddress parameter, * validate the address and set it up as a bookmark. This allows direct linking * to the widget with a pre-filled destination address that will be treated the * same way as a manually entered and validated address. */ const initializeFromAddress = async () => { if (formValues.toAddress) { try { const validationResult = await validateAddress({ value: formValues.toAddress, }); // Check if the toAddress is still in the query string // Could be modified by the user before the validation is done const { toAddress } = getDefaultValuesFromQueryString(); if (validationResult.isValid && toAddress) { const bookmark = { address: validationResult.address, chainType: validationResult.chainType, }; setSelectedBookmark(bookmark); addRecentWallet(bookmark); setSendToWallet(true); } } catch (_) { // Address validation failed } } }; initializeFromAddress(); setUserAndDefaultValues(formValues); }, [ setUserAndDefaultValues, setSendToWallet, validateAddress, setSelectedBookmark, addRecentWallet, ]); // biome-ignore lint/correctness/useExhaustiveDependencies: run only when pathname changes useEffect(() => { // set the values on the querysting const url = new URL(window.location); formValueKeys.forEach((key, _index) => { const value = getFieldValues(key)[0]; if (isTouched(key) && value) { url.searchParams.set(key, value.toString()); } else if (url.searchParams.has(key) && !value) { url.searchParams.delete(key); } }); url.searchParams.sort(); window.history.replaceState(window.history.state, '', url); }, [pathname, touchedFields, values, isTouched, getFieldValues]); return null; }; //# sourceMappingURL=URLSearchParamsBuilder.js.map