UNPKG

@shogun-sdk/one-shot

Version:

Shogun SDK - One Shot: React Components and hooks for cross-chain swaps

106 lines 4.08 kB
import { LEGO_API } from '@shogun-sdk/money-legos'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useShogunLego } from './../contexts/ShogunLegoContext.js'; /* ============================== 🔹 useLego Hook ============================== */ /** * Hook to validate and prepare transaction data for purchasing NFTs. * * @param {UseLegoProps} props - The NFT items, token details, and user address. * @returns {UseLegoResult} - Status, error message (if any), response data, loading state, and a refetch function. */ export const useLego = ({ items, token, userAddress }) => { const { API_KEY } = useShogunLego(); // ✅ State for handling API responses, errors, and loading status const [data, setData] = useState(null); const [error, setError] = useState(null); const [isLoading, setIsLoading] = useState(false); // ✅ Ref to manage API request cancellation const abortControllerRef = useRef(null); // ✅ Memoized API request body to prevent unnecessary recalculations const requestBody = useMemo(() => { if (!items.length || !token.address || !userAddress) return null; return JSON.stringify({ tokenIn: { address: token.address, decimals: token.decimals, chainId: token.chainId, }, nft: items, address: userAddress, }); }, [items, token.address, token.decimals, token.chainId, userAddress]); // ✅ Function to fetch data from the API const fetchData = useCallback(async () => { if (!requestBody) { setError('Invalid parameters provided to useLego hook.'); return; } // Cancel any ongoing request before making a new one if (abortControllerRef.current) { abortControllerRef.current.abort(); } // Create a new AbortController for the current request const abortController = new AbortController(); abortControllerRef.current = abortController; setIsLoading(true); setError(null); try { const response = await fetch(`${LEGO_API}/nft/purchase`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'x-api-key': API_KEY, }, body: requestBody, signal: abortController.signal, // ✅ Allows request cancellation }); // Prevent state updates if request was aborted if (abortController.signal.aborted) { return; } if (!response.ok) { throw new Error(`API Error: ${response.statusText}`); } const result = await response.json(); setData(result?.data?.execute); } catch (err) { if (err instanceof Error && err.name !== 'AbortError') { console.error('NFT Purchase API Error:', err); setError(err.message); } } finally { // Ensure loading state resets only if this is the latest request if (abortControllerRef.current === abortController) { setIsLoading(false); abortControllerRef.current = null; } } }, [API_KEY, requestBody]); // ✅ Auto-fetch data when dependencies change useEffect(() => { if (requestBody) { fetchData(); } // Cleanup function to abort any ongoing requests when dependencies change return () => { if (abortControllerRef.current) { abortControllerRef.current.abort(); abortControllerRef.current = null; } }; }, [fetchData, requestBody]); // ✅ Return hook state and refetch function return { status: !error && !!data, error, data, isLoading, refetch: fetchData, }; }; //# sourceMappingURL=useLego.js.map