diff --git a/apps/portal/app/components/create-claim/create-claim-form.tsx b/apps/portal/app/components/create-claim/create-claim-form.tsx index 2b61f7d49..b236b3612 100644 --- a/apps/portal/app/components/create-claim/create-claim-form.tsx +++ b/apps/portal/app/components/create-claim/create-claim-form.tsx @@ -8,7 +8,6 @@ import { DialogTitle, Icon, Input, - Label, Text, toast, } from '@0xintuition/1ui' @@ -18,13 +17,6 @@ import { IdentityPopover } from '@components/create-claim/create-claim-popovers' import CreateClaimReview from '@components/create-claim/create-claim-review' import { InfoTooltip } from '@components/info-tooltip' import WrongNetworkButton from '@components/wrong-network-button' -import { - getFormProps, - getInputProps, - SubmissionResult, - useForm, -} from '@conform-to/react' -import { parseWithZod } from '@conform-to/zod' import { multivaultAbi } from '@lib/abis/multivault' import { useCreateTriple } from '@lib/hooks/useCreateTriple' import { useGetWalletBalance } from '@lib/hooks/useGetWalletBalance' @@ -35,12 +27,12 @@ import { transactionReducer, useTransactionState, } from '@lib/hooks/useTransactionReducer' -import { createClaimSchema } from '@lib/schemas/create-claim-schema' import { createClaimModalAtom } from '@lib/state/store' import { getChainEnvConfig } from '@lib/utils/environment' import logger from '@lib/utils/logger' import { useFetcher, useNavigate } from '@remix-run/react' import { CreateClaimLoaderData } from '@routes/resources+/create-claim' +import { GetClaimLoaderData } from '@routes/resources+/get-claim' import { TagLoaderData } from '@routes/resources+/tag' import { CREATE_CLAIM_RESOURCE_ROUTE, @@ -57,10 +49,9 @@ import { TransactionSuccessActionType, } from 'app/types/transaction' import { useAtomValue } from 'jotai' -import { parseUnits } from 'viem' -import { useAccount, usePublicClient, useWalletClient } from 'wagmi' +import { Address, decodeEventLog, parseUnits } from 'viem' +import { useAccount, usePublicClient } from 'wagmi' -import ErrorList from '../error-list' import { TransactionState } from '../transaction-state' interface ClaimFormProps { @@ -81,9 +72,6 @@ export function ClaimForm({ TransactionActionType >(transactionReducer, initialTransactionState) - const [transactionResponseData, setTransactionResponseData] = - useState(null) - const isTransactionStarted = [ 'approve', 'awaiting', @@ -122,8 +110,6 @@ export function ClaimForm({ onClose={onClose} onSuccess={onSuccess} successAction={successAction} - setTransactionResponseData={setTransactionResponseData} - transactionResponseData={transactionResponseData} /> @@ -134,10 +120,6 @@ interface CreateClaimFormProps { wallet: string state: TransactionStateType dispatch: React.Dispatch - setTransactionResponseData: React.Dispatch< - React.SetStateAction - > - transactionResponseData: ClaimPresenter | null onSuccess?: (claim: ClaimPresenter) => void successAction?: TransactionSuccessActionType onClose: () => void @@ -147,26 +129,22 @@ function CreateClaimForm({ wallet, state, dispatch, - setTransactionResponseData, - transactionResponseData, onClose, - onSuccess, successAction = TransactionSuccessAction.VIEW, }: CreateClaimFormProps) { const { subject, predicate, object } = useAtomValue(createClaimModalAtom) const feeFetcher = useLoaderFetcher( CREATE_CLAIM_RESOURCE_ROUTE, ) + const claimChecker = useFetcher() + const claimFetcher = useFetcher() + const { fees } = (feeFetcher.data as CreateClaimLoaderData) ?? {} + const [lastTxHash, setLastTxHash] = useState(undefined) const [initialDeposit, setInitialDeposit] = useState('0') - + const [vaultId, setVaultId] = useState(undefined) const navigate = useNavigate() - interface OffChainClaimFetcherData { - success: 'success' | 'error' - claim: ClaimPresenter - submission: SubmissionResult | null - } // const [searchQuery, setSearchQuery] = useState('') const [isSubjectPopoverOpen, setIsSubjectPopoverOpen] = useState(false) @@ -176,7 +154,6 @@ function CreateClaimForm({ const { setSearchQuery, identities, handleInput } = useIdentityServerSearch() - const { data: walletClient } = useWalletClient() const publicClient = usePublicClient() const { address, chain } = useAccount() @@ -184,6 +161,7 @@ function CreateClaimForm({ writeContractAsync: writeCreateTriple, awaitingWalletConfirmation, awaitingOnChainConfirmation, + receipt: txReceipt, } = useCreateTriple() // form @@ -224,11 +202,30 @@ function CreateClaimForm({ hash: txHash, }) - dispatch({ - type: 'TRANSACTION_COMPLETE', - txHash, - txReceipt: receipt, - }) + type EventLogArgs = { + sender: Address + receiver?: Address + owner?: Address + vaultId: string + } + + if ( + receipt?.logs[0].data && + receipt?.transactionHash !== lastTxHash + ) { + const decodedLog = decodeEventLog({ + abi: multivaultAbi, + data: receipt?.logs[0].data, + topics: receipt?.logs[0].topics, + }) + + const topics = decodedLog as unknown as { + eventName: string + args: EventLogArgs + } + setVaultId(topics.args.vaultId.toString()) + setLastTxHash(receipt.transactionHash) + } } } catch (error) { console.error('error', error) @@ -252,90 +249,51 @@ function CreateClaimForm({ } } - const claimFetcher = useFetcher() - const lastOffChainSubmission = claimFetcher.data?.submission + useEffect(() => { + if (txReceipt && vaultId) { + claimFetcher.load(`/resources/get-claim?vaultId=${vaultId}`) + } + }, [txReceipt, vaultId]) useEffect(() => { - if ( - claimFetcher.state === 'idle' && - claimFetcher.data !== null && - claimFetcher.data !== undefined - ) { - const responseData = claimFetcher.data as OffChainClaimFetcherData - if (responseData !== null) { - setTransactionResponseData(responseData.claim) - logger('responseData', responseData) - if ( - responseData.claim !== undefined && - selectedIdentities.subject !== null && - selectedIdentities.predicate !== null && - selectedIdentities.object !== null - ) { - handleOnChainCreateTriple({ - subjectVaultId: selectedIdentities.subject.vault_id, - predicateVaultId: selectedIdentities.predicate.vault_id, - objectVaultId: selectedIdentities.object.vault_id, - }) - } - } - if (claimFetcher.data === null || claimFetcher.data === undefined) { - console.error('Error in offchain data creation.:', claimFetcher.data) + if (txReceipt) { + if (claimFetcher.data && 'claim' in claimFetcher.data) { + console.log('claimFetcher.data', claimFetcher.data) + dispatch({ + type: 'TRANSACTION_COMPLETE', + txHash: txReceipt.transactionHash, + txReceipt, + }) + } else if (claimFetcher.data && 'error' in claimFetcher.data) { + const errorMessage = `Your claim was created, but we're having trouble fetching its details. Vault ID: ${vaultId}` dispatch({ type: 'TRANSACTION_ERROR', - error: 'Error in offchain claim creation.', + error: errorMessage, }) + toast.error(errorMessage) } } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [claimFetcher.state, claimFetcher.data, dispatch]) + }, [claimFetcher.data, txReceipt, vaultId]) - const handleSubmit = async (event: React.FormEvent) => { - event.preventDefault() + const handleSubmit = async () => { try { + dispatch({ type: 'CONFIRM_TRANSACTION' }) if ( - walletClient && - selectedIdentities.subject && - selectedIdentities.predicate && - selectedIdentities.object + selectedIdentities.subject !== null && + selectedIdentities.predicate !== null && + selectedIdentities.object !== null ) { - const formData = new FormData() - formData.append('subject_id', selectedIdentities.subject.id) - formData.append('predicate_id', selectedIdentities.predicate.id) - formData.append('object_id', selectedIdentities.object.id) - const submission = parseWithZod(formData, { - schema: createClaimSchema, + handleOnChainCreateTriple({ + subjectVaultId: selectedIdentities.subject.vault_id, + predicateVaultId: selectedIdentities.predicate.vault_id, + objectVaultId: selectedIdentities.object.vault_id, }) - - if (event.currentTarget.initial_deposit?.value !== undefined) { - setInitialDeposit(event.currentTarget.initial_deposit.value) - } - - logger('submission', submission) - - if ( - submission.status === 'error' && - submission.error !== null && - Object.keys(submission.error).length - ) { - console.error('Create claim validation errors: ', submission.error) - } - claimFetcher.submit(formData, { - action: '/actions/create-claim', - method: 'post', - }) - dispatch({ type: 'CONFIRM_TRANSACTION' }) } } catch (error: unknown) { logger(error) } } - const [form, fields] = useForm({ - id: 'create-claim', - lastResult: lastOffChainSubmission, - onSubmit: async (event) => handleSubmit(event), - }) - const [selectedIdentities, setSelectedIdentities] = useState<{ subject: IdentityPresenter | null predicate: IdentityPresenter | null @@ -380,8 +338,6 @@ function CreateClaimForm({ address ?? (wallet as `0x${string}`), ) - const claimChecker = useFetcher() - useEffect(() => { if ( selectedIdentities.subject && @@ -404,14 +360,6 @@ function CreateClaimForm({ } }, [claimChecker.data, selectedIdentities]) - useEffect(() => { - if (state.status === 'complete') { - if (transactionResponseData) { - onSuccess?.(transactionResponseData) - } - } - }, [state.status, transactionResponseData]) - const Divider = () => ( ) @@ -420,12 +368,6 @@ function CreateClaimForm({ return ( <> -