UNPKG

@smartinvoicexyz/hooks

Version:

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

120 lines (119 loc) 4.71 kB
import { ESCROW_ZAP_ABI } from '@smartinvoicexyz/constants'; import { logDebug } from '@smartinvoicexyz/utils'; import _ from 'lodash'; import { useCallback, useMemo } from 'react'; import { encodeAbiParameters, isAddress, parseUnits } from 'viem'; import { useChainId, useSimulateContract, useWriteContract } from 'wagmi'; const separateOwnersAndAllocations = (ownersAndAllocations) => { const sortedOwnersAndAllocations = _.sortBy(ownersAndAllocations, 'address'); return { owners: _.map(sortedOwnersAndAllocations, 'address'), percentAllocations: _.map(sortedOwnersAndAllocations, (o) => _.toNumber(o.percent) * 1e4), }; }; export const useEscrowZap = ({ ownersAndAllocations, provider, milestones, client, threshold, arbitration = 0, projectTeamSplit = false, daoSplit = false, safetyValveDate, details, enabled = true, networkConfig, onSuccess, }) => { const chainId = useChainId(); const { owners, percentAllocations } = separateOwnersAndAllocations(ownersAndAllocations); const saltNonce = Math.floor(new Date().getTime() / 1000); const milestoneAmounts = _.map(milestones, (a) => a.value && parseUnits(a.value, networkConfig.tokenDecimals)); const { tokenAddress } = networkConfig; const resolver = daoSplit ? networkConfig.resolver : networkConfig.daoAddress; const encodedSafeData = useMemo(() => { if (!threshold || !saltNonce) return encodeAbiParameters([{ type: 'uint256' }, { type: 'uint256' }], [BigInt(0), BigInt(0)]); return encodeAbiParameters([{ type: 'uint256' }, { type: 'uint256' }], [BigInt(threshold), BigInt(saltNonce)]); }, [threshold, saltNonce]); logDebug('encodeSafeData - ', { threshold, saltNonce, compiledData: !!encodedSafeData, }); const encodedSplitData = useMemo(() => encodeAbiParameters([{ type: 'bool' }, { type: 'bool' }], [projectTeamSplit, daoSplit]), [projectTeamSplit, daoSplit]); logDebug('encodeSplitData - ', { projectTeamSplit, daoSplit, compiledData: !!encodedSplitData, }); const encodedEscrowData = useMemo(() => { if (!isAddress(client) || !(arbitration === 0 || arbitration === 1) || !details || !isAddress(resolver) || !isAddress(tokenAddress) || !safetyValveDate) return undefined; return encodeAbiParameters([ { type: 'address' }, { type: 'uint32' }, { type: 'address' }, { type: 'address' }, { type: 'uint256' }, { type: 'uint256' }, { type: 'bytes32' }, ], [ client, arbitration, resolver, tokenAddress, BigInt(Math.floor(_.toNumber(safetyValveDate) / 1000)), BigInt(saltNonce), details, ]); }, [tokenAddress, safetyValveDate, details, client, arbitration, resolver]); logDebug('encodeEscrowData - ', { client, arbitration, resolver, tokenAddress, safetyValveDate, saltNonce, details, milestoneAmounts, compiledData: !!encodedEscrowData, }); const { data, isLoading: prepareLoading, error: prepareError, status, } = useSimulateContract({ chainId, address: networkConfig.zapAddress, abi: ESCROW_ZAP_ABI, functionName: 'createSafeSplitEscrow', args: [ owners, percentAllocations, milestoneAmounts, encodedSafeData, provider, // _safeAddress encodedSplitData, encodedEscrowData, ], query: { enabled: _.isEqual(_.size(percentAllocations), _.size(owners)) && !_.isEmpty(milestoneAmounts) && !!encodedSafeData && !!provider && // _safeAddress !!encodedSplitData && !!encodedEscrowData && enabled, }, }); logDebug('prepareError', prepareError, status); const { writeContractAsync, isPending: writeLoading, error: writeError, } = useWriteContract({ mutation: { onSuccess: async (hash) => { onSuccess?.(hash); }, }, }); const writeAsync = useCallback(async () => { if (!data) { logDebug('writeAsync - no data'); return undefined; } return writeContractAsync(data.request); }, [writeContractAsync, data]); return { writeAsync, isLoading: prepareLoading || writeLoading || !details, prepareError, writeError, }; };