@smartinvoicexyz/hooks
Version:
Unified source for React hooks used across the Smart Invoice protocol.
76 lines (75 loc) • 3.03 kB
JavaScript
import { IERC20_ABI, PAYMENT_TYPES, TOASTS } from '@smartinvoicexyz/constants';
import { waitForSubgraphSync } from '@smartinvoicexyz/graphql';
import { errorToastHandler } from '@smartinvoicexyz/utils';
import _ from 'lodash';
import { useChainId, usePublicClient, useSendTransaction, useSimulateContract, useWriteContract, } from 'wagmi';
export const useDeposit = ({ invoice, amount, hasAmount, paymentType, onTxSuccess, toast, }) => {
const chainId = useChainId();
const { tokenMetadata, address } = _.pick(invoice, [
'tokenMetadata',
'address',
]);
const publicClient = usePublicClient();
const { data, isLoading: prepareLoading, error: prepareError, } = useSimulateContract({
chainId,
address: tokenMetadata?.address,
abi: IERC20_ABI,
functionName: 'transfer',
args: [address, amount],
query: {
enabled: hasAmount && paymentType === PAYMENT_TYPES.TOKEN,
},
});
const { writeContractAsync, isPending: writeLoading, error: writeError, } = useWriteContract({
mutation: {
onSuccess: async (hash) => {
toast.loading(TOASTS.useDeposit.waitingForTx);
const receipt = await publicClient?.waitForTransactionReceipt({ hash });
toast.loading(TOASTS.useDeposit.waitingForIndex);
if (receipt && publicClient) {
await waitForSubgraphSync(publicClient.chain.id, receipt.blockNumber);
}
onTxSuccess?.();
},
},
});
const { isPending: sendLoading, sendTransactionAsync } = useSendTransaction({
mutation: {
onSuccess: async (hash) => {
toast.loading(TOASTS.useDeposit.waitingForTx);
const receipt = await publicClient?.waitForTransactionReceipt({ hash });
toast.loading(TOASTS.useDeposit.waitingForIndex);
if (receipt && publicClient) {
await waitForSubgraphSync(publicClient.chain.id, receipt.blockNumber);
}
onTxSuccess?.();
},
},
});
const handleDeposit = async () => {
try {
if (paymentType === PAYMENT_TYPES.NATIVE) {
const result = await sendTransactionAsync({
to: address,
value: amount,
});
return result;
}
if (!data) {
throw new Error('useDeposit: simulation data is not available');
}
const result = await writeContractAsync(data.request);
return result;
}
catch (error) {
errorToastHandler('useDeposit', error, toast);
return undefined;
}
};
return {
handleDeposit,
isLoading: prepareLoading || writeLoading || sendLoading,
writeError,
prepareError: paymentType === PAYMENT_TYPES.TOKEN ? prepareError : null,
};
};