"use client"; import { useState } from "react"; import { IntegerInput } from "@scaffold-ui/debug-contracts"; import { parseEther } from "viem"; import { usePublicClient } from "wagmi"; import TooltipInfo from "~~/components/TooltipInfo"; import { useScaffoldWriteContract } from "~~/hooks/scaffold-eth"; import { useChallengeState } from "~~/services/store/challengeStore"; import { getRandomQuestion } from "~~/utils/helpers"; import { notification } from "~~/utils/scaffold-eth"; const MINIMUM_ASSERTION_WINDOW = 3; const getStartTimestamp = (timestamp: bigint, startInMinutes: string) => { if (startInMinutes.length === 0) return 0n; if (Number(startInMinutes) === 0) return 0n; return timestamp + BigInt(startInMinutes) * 60n; }; const getEndTimestamp = (timestamp: bigint, startTimestamp: bigint, durationInMinutes: string) => { if (durationInMinutes.length === 0) return 0n; if (Number(durationInMinutes) === MINIMUM_ASSERTION_WINDOW) return 0n; if (startTimestamp === 0n) return timestamp + BigInt(durationInMinutes) * 60n; return startTimestamp + BigInt(durationInMinutes) * 60n; }; interface SubmitAssertionModalProps { isOpen: boolean; onClose: () => void; } const SubmitAssertionModal = ({ isOpen, onClose }: SubmitAssertionModalProps) => { const { timestamp } = useChallengeState(); const [isLoading, setIsLoading] = useState(false); const publicClient = usePublicClient(); const [description, setDescription] = useState(""); const [reward, setReward] = useState(""); const [startInMinutes, setStartInMinutes] = useState(""); const [durationInMinutes, setDurationInMinutes] = useState(""); const { writeContractAsync } = useScaffoldWriteContract({ contractName: "OptimisticOracle" }); const handleRandomQuestion = () => { setDescription(getRandomQuestion()); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (durationInMinutes.length > 0 && Number(durationInMinutes) < MINIMUM_ASSERTION_WINDOW) { notification.error( `Duration must be at least ${MINIMUM_ASSERTION_WINDOW} minutes or leave blank to use default value`, ); return; } if (Number(reward) === 0) { notification.error(`Reward must be greater than 0 ETH`); return; } if (!publicClient) { notification.error("Public client not found"); return; } try { setIsLoading(true); let recentTimestamp = timestamp; if (!recentTimestamp) { const block = await publicClient.getBlock(); recentTimestamp = block.timestamp; } const startTimestamp = getStartTimestamp(recentTimestamp, startInMinutes); const endTimestamp = getEndTimestamp(recentTimestamp, startTimestamp, durationInMinutes); await writeContractAsync({ functionName: "assertEvent", args: [description.trim(), startTimestamp, endTimestamp], value: parseEther(reward), }); // Reset form after successful submission setDescription(""); setReward(""); setStartInMinutes(""); setDurationInMinutes(""); onClose(); } catch (error) { console.log("Error with submission", error); } finally { setIsLoading(false); } }; const handleClose = () => { onClose(); // Reset form when closing setDescription(""); setReward(""); setStartInMinutes(""); setDurationInMinutes(""); }; if (!isOpen) return null; const readyToSubmit = description.trim().length > 0 && reward.trim().length > 0; return ( <>