UNPKG

@shogun-sdk/one-shot

Version:

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

133 lines (118 loc) 3.63 kB
import { decodeErrorMessage, DEFAULT_ERROR_MESSAGE, FeeService, getMaxAmount, getSwapWeiAmount, ICollectedFees, INSUFFICIENT_FUNDS_ERROR_MSG, QuoteParams, QuoteTypes, Token, } from '@shogun-sdk/money-legos'; import { useCallback, useEffect, useState } from 'react'; // Custom hook to handle fee calculations export const useFeeCalculations = (props: { address: string | undefined; inputAmount: string; tokenIn: Token; hasInput: boolean; tokenInBalance: bigint | undefined; queryParams: QuoteParams | null; setLatestSuggestedAutoSlippageValue: (slippage: number) => void; notifyAboutError: (error: Error) => void; }) => { const { address, inputAmount, tokenIn, hasInput, tokenInBalance, queryParams, setLatestSuggestedAutoSlippageValue, notifyAboutError, } = props; const [fees, setFees] = useState<ICollectedFees | undefined>(undefined); const [balanceError, setBalanceError] = useState<string | null>(null); const resetBalanceError = useCallback(() => { if (tokenInBalance && getSwapWeiAmount(inputAmount, tokenIn.decimals) > tokenInBalance) { setBalanceError(INSUFFICIENT_FUNDS_ERROR_MSG); return { fees: undefined, maxAmount: null }; } setBalanceError(null); return { fees: undefined, maxAmount: null }; }, [tokenIn, tokenInBalance, inputAmount]); useEffect(() => { resetBalanceError(); }, [resetBalanceError]); const calculateFees = useCallback( async (quotes: QuoteTypes): Promise<{ fees: ICollectedFees | undefined; maxAmount: string | null }> => { if (!quotes || !address || !queryParams || !tokenIn || !hasInput) { resetBalanceError(); return { fees: undefined, maxAmount: null }; } try { const feeService = new FeeService(); const feeData = await feeService.checkHasSufficientBalanceForGas( address as string, queryParams.srcChain as number, quotes, setLatestSuggestedAutoSlippageValue, ); if (!feeData) { return { fees: undefined, maxAmount: null }; } setFees(feeData.fees); if (feeData.error && feeData.error !== DEFAULT_ERROR_MESSAGE) { const decodedError = decodeErrorMessage(feeData.error); if (decodedError !== DEFAULT_ERROR_MESSAGE) { setBalanceError(decodedError); } else { resetBalanceError(); } } else { resetBalanceError(); } if (!tokenInBalance) { return { fees: feeData.fees, maxAmount: null }; } const { maxAmount } = getMaxAmount({ balance: tokenInBalance, tokenAddress: tokenIn.address, chainId: tokenIn.chainId, decimals: tokenIn.decimals, fees: feeData.fees, quote: quotes, }); if (!maxAmount) { setBalanceError(INSUFFICIENT_FUNDS_ERROR_MSG); return { fees: feeData.fees, maxAmount: null }; } return { fees: feeData.fees, maxAmount }; } catch (error: unknown) { console.error('Error in fee calculation:', error); notifyAboutError(error as Error); resetBalanceError(); return { fees: undefined, maxAmount: null }; } }, [ address, queryParams, tokenIn, tokenInBalance, notifyAboutError, setLatestSuggestedAutoSlippageValue, hasInput, resetBalanceError, setBalanceError, ], ); return { fees, balanceError, calculateFees, setFees, resetBalanceError, }; };