UNPKG

@reown/appkit-pay

Version:
177 lines • 6.74 kB
import { useCallback, useEffect, useRef, useState } from 'react'; import { getPayUrl as clientGetPayUrl, openPayUrl as clientOpenPayUrl, getAvailableExchanges } from '../src/client.js'; import { PayController } from '../src/controllers/PayController.js'; import { AppKitPayError, AppKitPayErrorCodes } from '../src/types/errors.js'; const MINIMUM_POLLING_INTERVAL = 3000; export function usePay(parameters) { const { onSuccess, onError } = parameters ?? {}; const [isControllerLoading, setIsControllerLoading] = useState(PayController.state.isLoading); const [isPaymentInProgress, setIsPaymentInProgress] = useState(PayController.state.isPaymentInProgress); const [error, setError] = useState(PayController.state.error); const [data, setData] = useState(PayController.state.currentPayment?.result ?? null); useEffect(() => { const unsubLoading = PayController.subscribeKey('isLoading', val => setIsControllerLoading(val)); const unsubProgress = PayController.subscribeKey('isPaymentInProgress', val => { setIsPaymentInProgress(val); const payResult = PayController.state.currentPayment?.result ?? null; setData(payResult); if (payResult && onSuccess) { onSuccess(payResult); } if (payResult) { setError(null); } }); const unsubError = PayController.subscribeKey('error', val => { setError(val); if (val && onError) { onError(val); } if (val) { setData(null); } }); return () => { unsubLoading(); unsubProgress(); unsubError(); }; }, [onSuccess, onError]); const open = useCallback(async (options) => { setError(null); setData(null); await PayController.handleOpenPay(options); }, []); const isPending = isControllerLoading || isPaymentInProgress; const isError = error !== null; const isSuccess = data !== null && !isError; return { open, isPending, isSuccess, isError, error, data }; } export function useAvailableExchanges(options) { const { shouldFetchOnInit = true, page: initialPage, asset, amount, network } = options ?? {}; const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(shouldFetchOnInit); const [error, setError] = useState(null); const fetchExchanges = useCallback(async (params) => { setIsLoading(true); setError(null); try { const response = await getAvailableExchanges(params); setData(response.exchanges); } catch (err) { const fetchError = err instanceof Error ? err : new AppKitPayError(AppKitPayErrorCodes.UNABLE_TO_GET_EXCHANGES); setError(fetchError); setData(null); } finally { setIsLoading(false); } }, []); useEffect(() => { if (shouldFetchOnInit) { fetchExchanges({ page: initialPage, asset, amount, network }).catch(() => { }); } }, [shouldFetchOnInit, initialPage]); const fetch = useCallback(async (params) => { await fetchExchanges(params); }, [fetchExchanges]); return { data, isLoading, error, fetch }; } export function usePayUrlActions() { const getUrl = useCallback(async (exchangeId, params) => clientGetPayUrl(exchangeId, params), []); const openUrl = useCallback(async (exchangeId, params, openInNewTab) => clientOpenPayUrl(exchangeId, params, openInNewTab), []); return { getUrl, openUrl }; } export function useExchangeBuyStatus(params) { const { exchangeId, sessionId, pollingInterval, isEnabled = true, onSuccess, onError } = params; const [data, setData] = useState(null); const [isLoading, setIsLoading] = useState(isEnabled); const [error, setError] = useState(null); const intervalRef = useRef(null); const fetchAndSetStatus = useCallback(async (options) => { if (options.showLoading) { setIsLoading(true); } if (options.showLoading) { setError(null); } try { const status = await PayController.getBuyStatus(exchangeId, sessionId); setData(status); setError(null); if (onSuccess) { onSuccess(status); } return status; } catch (err) { const fetchError = err instanceof Error ? err : new AppKitPayError(AppKitPayErrorCodes.UNABLE_TO_GET_BUY_STATUS); setError(fetchError); if (onError) { onError(fetchError); } throw fetchError; } finally { if (options.showLoading) { setIsLoading(false); } } }, [exchangeId, sessionId, onSuccess, onError]); useEffect(() => { if (isEnabled) { fetchAndSetStatus({ showLoading: true }); } else { setData(null); setError(null); setIsLoading(false); if (intervalRef.current !== null) { clearInterval(intervalRef.current); intervalRef.current = null; } } }, [isEnabled, exchangeId, sessionId]); useEffect(() => { const isTerminalStatus = data?.status === 'SUCCESS' || data?.status === 'FAILED'; const shouldPoll = isEnabled && pollingInterval && pollingInterval > 0 && !isTerminalStatus; function clearPollingInterval() { if (intervalRef.current !== null) { clearInterval(intervalRef.current); intervalRef.current = null; } } if (shouldPoll) { clearPollingInterval(); const interval = pollingInterval < MINIMUM_POLLING_INTERVAL ? MINIMUM_POLLING_INTERVAL : pollingInterval; intervalRef.current = setInterval(() => { fetchAndSetStatus({ showLoading: false }).catch(() => { clearPollingInterval(); }); }, interval); } else { clearPollingInterval(); } return clearPollingInterval; }, [isEnabled, pollingInterval, data?.status]); const refetch = useCallback(async () => { if (!isEnabled) { return; } await fetchAndSetStatus({ showLoading: true }); }, [fetchAndSetStatus, isEnabled]); return { data, isLoading, error, refetch }; } //# sourceMappingURL=react.js.map