diff --git a/app/api/contracts/route.ts b/app/api/contracts/route.ts index f30adc6..5312cab 100644 --- a/app/api/contracts/route.ts +++ b/app/api/contracts/route.ts @@ -1,5 +1,5 @@ -import { FEATURED_CONTRACTS } from "@/constants"; import { contractCollection } from "@/utils/collections"; +import { setAbi } from "@/utils/etherscan"; import { NextRequest, NextResponse } from "next/server"; export const runtime = "nodejs"; @@ -18,7 +18,6 @@ export async function GET() { export async function POST(req: NextRequest) { try { const body = await req.json(); - const existingContracts = await contractCollection.get(); if ( @@ -33,13 +32,19 @@ export async function POST(req: NextRequest) { throw new Error("Contract address is not valid"); } - // TODO: fetch abi and throw if not found + if (body.abi) { + const isValidABI = await setAbi(body.address, body.chainId, body.abi); + if (!isValidABI) { + throw new Error("Contract ABI is not valid"); + } + } await contractCollection.add({ address: body.address, name: body.name, chainId: body.chainId, }); + const contracts = await contractCollection.get(); return NextResponse.json({ contracts }, { status: 200 }); diff --git a/components/UploadContractModal.tsx b/components/UploadContractModal.tsx index 6d6a79a..4de0a3e 100644 --- a/components/UploadContractModal.tsx +++ b/components/UploadContractModal.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useCallback, useEffect, useState } from "react"; import { Input } from "./ui/input"; import { Button } from "./ui/button"; import { LoadingIcon } from "./LoadingIcon"; @@ -23,6 +23,7 @@ import { NETWORKS } from "@/constants"; import { IContract, ChainIdEnum } from "@/types"; import { useContracts } from "../utils/useContracts"; import { shortenAddress } from "../utils/shortenAddress"; +import { Textarea } from "./ui/textarea"; export function UploadContractModal({ isOpen, @@ -34,18 +35,20 @@ export function UploadContractModal({ const { onUpload, setErrorMessage, errorMessage, isLoading } = useContracts(); const [address, setAddress] = useState(""); const [name, setName] = useState(""); + const [abi, setABI] = useState(""); const [chainId, setChainId] = useState(-1); - const onResetForm = () => { + const onResetForm = useCallback(() => { setAddress(""); setChainId(-1); setName(""); + setABI(""); setErrorMessage(""); - }; + }, [setErrorMessage]); useEffect(() => { onResetForm(); - }, [isOpen]); + }, [isOpen, onResetForm]); return ( @@ -58,7 +61,7 @@ export function UploadContractModal({ className="flex w-full flex-col gap-4 mt-4" onSubmit={(e) => { e.preventDefault(); - onUpload({ address, name, chainId }).then((contracts) => { + onUpload({ address, name, chainId, abi }).then((contracts) => { if (contracts) onClose(); }); }} @@ -71,7 +74,6 @@ export function UploadContractModal({ placeholder="Enter a name" value={name} onChange={(e) => setName(e.target.value)} - className="col-span-3" /> @@ -82,11 +84,20 @@ export function UploadContractModal({ value={address} placeholder="Enter a contract address" onChange={(e) => setAddress(e.target.value)} - className="col-span-3" /> + +
+ +