UNPKG

@smartinvoicexyz/hooks

Version:

Unified source for React hooks used across the Smart Invoice protocol.

83 lines (82 loc) 3.34 kB
import { INVOICE_VERSION, SMART_INVOICE_UPDATABLE_ABI, TOASTS, } from '@smartinvoicexyz/constants'; import { waitForSubgraphSync } from '@smartinvoicexyz/graphql'; import { errorToastHandler, getDateString, uriToDocument, } from '@smartinvoicexyz/utils'; import _ from 'lodash'; import { useCallback, useMemo, useState } from 'react'; import { useChainId, usePublicClient, useSimulateContract, useWriteContract, } from 'wagmi'; import { useDetailsPin } from './useDetailsPin'; export const useLock = ({ invoice, localForm, onTxSuccess, toast, details, }) => { const currentChainId = useChainId(); const { chainId: invoiceChainId, metadata } = _.pick(invoice, [ 'chainId', 'metadata', ]); const { description, document } = localForm.getValues(); const publicClient = usePublicClient(); const detailsData = useMemo(() => { if (details) { return null; } const now = Math.floor(new Date().getTime() / 1000); const title = `Dispute ${metadata?.title} at ${getDateString(now)}`; return { version: INVOICE_VERSION, id: _.join([title, now, INVOICE_VERSION], '-'), title, description, documents: document ? [uriToDocument(document)] : [], createdAt: now, }; }, [description, document, metadata, details]); const { data: detailsHash, isLoading: detailsLoading } = useDetailsPin(detailsData, true); const { data, isLoading: prepareLoading, error: prepareError, } = useSimulateContract({ address: invoice?.address, functionName: 'lock', abi: SMART_INVOICE_UPDATABLE_ABI, args: [details ?? detailsHash], query: { enabled: !!invoice?.address && !!description && (!!details || !!detailsHash) && currentChainId === invoiceChainId, }, }); const [waitingForTx, setWaitingForTx] = useState(false); const { writeContractAsync, isPending: writeLoading, error: writeError, } = useWriteContract({ mutation: { onSuccess: async (hash) => { setWaitingForTx(true); toast.loading(TOASTS.useLock.waitingForTx); const receipt = await publicClient?.waitForTransactionReceipt({ hash }); toast.loading(TOASTS.useLock.waitingForIndex); if (receipt && publicClient) { await waitForSubgraphSync(publicClient.chain.id, receipt.blockNumber); } setWaitingForTx(false); onTxSuccess?.(); }, onError: error => errorToastHandler('useLock', error, toast), }, }); const writeAsync = useCallback(async () => { try { if (!data) { throw new Error('simulation data is not available'); } return writeContractAsync(data.request); } catch (error) { errorToastHandler('useLock', error, toast); return undefined; } }, [writeContractAsync, data]); return { writeAsync, isLoading: prepareLoading || writeLoading || waitingForTx || !(details || !detailsLoading), prepareError, writeError, }; };