;
+}
+
+const EvmContractVerifySolidityOptions = ({
+ control,
+}: EvmContractVerifySolidityProps) => {
+ const verifyFormOption = useWatch({ control, name: "verifyForm.option" });
+
+ switch (verifyFormOption) {
+ case VerificationOptions.UploadFiles:
+ return ;
+ case VerificationOptions.ContractCode:
+ return ;
+ case VerificationOptions.JsonInput:
+ return ;
+ case VerificationOptions.Hardhat:
+ return ;
+ case VerificationOptions.Foundry:
+ return ;
+ default:
+ return null;
+ }
+};
+
+export const EvmContractVerifySolidity = ({
+ control,
+}: EvmContractVerifySolidityProps) => (
+
+
+
+
+
+);
diff --git a/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityContractCode.tsx b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityContractCode.tsx
new file mode 100644
index 000000000..2efeb3c33
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityContractCode.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifySolidityContractCode = () => {
+ return TODO: EvmContractVerifySolidityContractCode
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityFoundry.tsx b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityFoundry.tsx
new file mode 100644
index 000000000..fd17c8ef1
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityFoundry.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifySolidityFoundry = () => {
+ return TODO: EvmContractVerifySolidityFoundry
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityHardhat.tsx b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityHardhat.tsx
new file mode 100644
index 000000000..b7cae9211
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityHardhat.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifySolidityHardhat = () => {
+ return TODO: EvmContractVerifySolidityHardhat
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityJsonInput.tsx b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityJsonInput.tsx
new file mode 100644
index 000000000..0e11118f3
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityJsonInput.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifySolidityJsonInput = () => {
+ return TODO: EvmContractVerifySolidityJsonInput
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityUploadFiles.tsx b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityUploadFiles.tsx
new file mode 100644
index 000000000..1beaaad92
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityUploadFiles.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifySolidityUploadFiles = () => {
+ return TODO: EvmContractVerifySolidityUploadFiles
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyper.tsx b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyper.tsx
new file mode 100644
index 000000000..c7e7f12db
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyper.tsx
@@ -0,0 +1,38 @@
+import { Divider, Stack } from "@chakra-ui/react";
+import { EvmContractVerifyForm, VerificationOptions } from "../../types";
+import { Control, useWatch } from "react-hook-form";
+import { EvmContractVerifyOptions } from "../EvmContractVerifyOptions";
+import { EvmContractVerifyVyperUploadFile } from "./EvmContractVerifyVyperUploadFile";
+import { EvmContractVerifyVyperContractCode } from "./EvmContractVerifyVyperContractCode";
+import { EvmContractVerifyVyperJsonInput } from "./EvmContractVerifyVyperJsonInput";
+
+interface EvmContractVerifyVyperProps {
+ control: Control;
+}
+
+const EvmContractVerifyVyperOptions = ({
+ control,
+}: EvmContractVerifyVyperProps) => {
+ const verifyFormOption = useWatch({ control, name: "verifyForm.option" });
+
+ switch (verifyFormOption) {
+ case VerificationOptions.UploadFile:
+ return ;
+ case VerificationOptions.ContractCode:
+ return ;
+ case VerificationOptions.JsonInput:
+ return ;
+ default:
+ return null;
+ }
+};
+
+export const EvmContractVerifyVyper = ({
+ control,
+}: EvmContractVerifyVyperProps) => (
+
+
+
+
+
+);
diff --git a/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperContractCode.tsx b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperContractCode.tsx
new file mode 100644
index 000000000..79859a9b7
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperContractCode.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifyVyperContractCode = () => {
+ return TODO: EvmContractVerifyVyperContractCode
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperJsonInput.tsx b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperJsonInput.tsx
new file mode 100644
index 000000000..a38b55254
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperJsonInput.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifyVyperJsonInput = () => {
+ return TODO: EvmContractVerifyVyperJsonInput
;
+};
diff --git a/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperUploadFile.tsx b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperUploadFile.tsx
new file mode 100644
index 000000000..eb74f96e6
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperUploadFile.tsx
@@ -0,0 +1,3 @@
+export const EvmContractVerifyVyperUploadFile = () => {
+ return TODO: EvmContractVerifyVyperUploadFile
;
+};
diff --git a/src/lib/pages/evm-contract-verify/index.tsx b/src/lib/pages/evm-contract-verify/index.tsx
new file mode 100644
index 000000000..a1a4bd4b5
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/index.tsx
@@ -0,0 +1,251 @@
+import { useEvmConfig, useExampleAddresses, useMobile } from "lib/app-provider";
+import { useRouter } from "next/router";
+import { useEffect, useMemo } from "react";
+import { track } from "@amplitude/analytics-browser";
+import { AmpEvent } from "lib/amplitude";
+import PageContainer from "lib/components/PageContainer";
+import { CelatoneSeo } from "lib/components/Seo";
+import { Grid, GridItem, Heading, Stack, Text } from "@chakra-ui/react";
+import { EvmContractVerifyTop } from "./components/EvmContractVerifyTop";
+import { ContractLicenseInfoAccordion } from "./components/ContractLicenseInfoAccordion";
+import { useStepper } from "lib/hooks";
+import { EvmContractFooter } from "./components/EvmContractVerifyFooter";
+import { ControllerInput, SelectInput } from "lib/components/forms";
+import { useForm } from "react-hook-form";
+import {
+ EvmContractVerifyForm,
+ EvmProgrammingLanguage,
+ VerificationOptions,
+ zEvmContractVerifyForm,
+} from "./types";
+import { zodResolver } from "@hookform/resolvers/zod";
+import { truncate } from "lib/utils";
+import { EvmContractVerifySolidity } from "./components/solidity/EvmContractVerifySolidity";
+import { EvmContractVerifyVyper } from "./components/vyper/EvmContractVerifyVyper";
+import { NoMobile } from "lib/components/modal";
+
+export const EvmContractVerify = () => {
+ useEvmConfig({ shouldRedirect: true });
+ const isMobile = useMobile();
+ const router = useRouter();
+ // TODO: add evm contract address
+ const { contract: exampleContractAddress } = useExampleAddresses();
+
+ useEffect(() => {
+ if (router.isReady) track(AmpEvent.TO_EVM_CONTRACT_VERIFY);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [router.isReady]);
+
+ const { control, watch, handleSubmit, setValue } =
+ useForm({
+ resolver: zodResolver(zEvmContractVerifyForm),
+ mode: "all",
+ reValidateMode: "onChange",
+ defaultValues: {
+ contractAddress: "",
+ compilerVersion: "",
+ },
+ });
+ const { licenseType, language, compilerVersion } = watch();
+
+ const { handleNext, handlePrevious, hasNext, hasPrevious } = useStepper(
+ 1,
+ () => alert("Submit!")
+ );
+
+ const licenseTypeOptions = useMemo(
+ () => [
+ {
+ label: "1. No License (None)",
+ value: "no-license",
+ },
+ {
+ label: "2. The Unlicense (Unlicense)",
+ value: "the-unlicense",
+ },
+ {
+ label: "3. MIT License (MIT)",
+ value: "mit",
+ },
+ ],
+ []
+ );
+
+ const programmingLangaugeOptions = useMemo(
+ () => [
+ {
+ label: "Solidity",
+ value: EvmProgrammingLanguage.Solidity,
+ },
+ {
+ label: "Vyper",
+ value: EvmProgrammingLanguage.Vyper,
+ },
+ ],
+ []
+ );
+
+ // TODO: fetch from API
+ const compilerVersionOptions = useMemo(
+ () => [
+ {
+ label: "0.8.0",
+ value: "0.8.0",
+ },
+ {
+ label: "0.7.0",
+ value: "0.7.0",
+ },
+ {
+ label: "0.6.0",
+ value: "0.6.0",
+ },
+ ],
+ []
+ );
+
+ const isFormDisabled = () => {
+ // TODO: Update the validation
+ return false;
+ };
+
+ return (
+ <>
+
+ {isMobile ? (
+
+ ) : (
+ <>
+
+
+
+
+
+
+
+
+
+ Contract Address & License
+
+
+
+
+
+
+ {
+ if (!selectedOption) return;
+ setValue("licenseType", selectedOption.value);
+ }}
+ value={licenseTypeOptions.find(
+ (option) => option.value === licenseType
+ )}
+ />
+
+
+
+
+
+
+
+
+
+
+ Verification Method
+
+
+ Please ensure the setting is the matching with the created
+ contract
+
+
+
+ {
+ if (!selectedOption) return;
+ setValue(
+ "verifyForm.option",
+ selectedOption.value ===
+ EvmProgrammingLanguage.Solidity
+ ? VerificationOptions.UploadFiles
+ : VerificationOptions.UploadFile
+ );
+ setValue("language", selectedOption.value);
+ }}
+ value={programmingLangaugeOptions.find(
+ (option) => option.value === language
+ )}
+ menuPortalTarget={document.body}
+ />
+ {
+ if (!selectedOption) return;
+ setValue("compilerVersion", selectedOption.value);
+ }}
+ value={compilerVersionOptions.find(
+ (option) => option.value === compilerVersion
+ )}
+ menuPortalTarget={document.body}
+ isDisabled={!language}
+ />
+
+
+
+
+ {language === EvmProgrammingLanguage.Solidity && (
+
+ )}
+ {language === EvmProgrammingLanguage.Vyper && (
+
+ )}
+
+
+
+
+ >
+ )}
+ >
+ );
+};
diff --git a/src/lib/pages/evm-contract-verify/types.ts b/src/lib/pages/evm-contract-verify/types.ts
new file mode 100644
index 000000000..fa8a23f11
--- /dev/null
+++ b/src/lib/pages/evm-contract-verify/types.ts
@@ -0,0 +1,81 @@
+import { zHexAddr20 } from "lib/types";
+import { z } from "zod";
+
+export enum EvmProgrammingLanguage {
+ Solidity = "solidity",
+ Vyper = "vyper",
+}
+
+export enum VerificationOptions {
+ UploadFile = "upload-file",
+ UploadFiles = "upload-files",
+ ContractCode = "contract-code",
+ JsonInput = "json-input",
+ Hardhat = "hardhat",
+ Foundry = "foundry",
+}
+
+// MARK - Query Params
+export const zEvmContractVerifyQueryParams = z.object({
+ contractAddress: zHexAddr20,
+});
+
+// MARK - Solidity
+export const zEvmContractVerifySolidityOptionUploadFilesForm = z.object({
+ option: z.literal(VerificationOptions.UploadFiles),
+});
+
+export const zEvmContractVerifySolidityOptionContractCodeForm = z.object({
+ option: z.literal(VerificationOptions.ContractCode),
+});
+
+export const zEvmContractVerifySolidityOptionJsonInputForm = z.object({
+ option: z.literal(VerificationOptions.JsonInput),
+});
+
+export const zEvmContractVerifySolidityOptionHardhatForm = z.object({
+ option: z.literal(VerificationOptions.Hardhat),
+});
+
+export const zEvmContractVerifySolidityOptionFoundryForm = z.object({
+ option: z.literal(VerificationOptions.Foundry),
+});
+
+// MARK - Vyper
+export const zEvmContractVerifyVyperOptionUploadFileForm = z.object({
+ option: z.literal(VerificationOptions.UploadFile),
+});
+
+export const zEvmContractVerifyVyperOptionContractCodeForm = z.object({
+ option: z.literal(VerificationOptions.ContractCode),
+});
+
+export const zEvmContractVerifyVyperOptionJsonInputForm = z.object({
+ option: z.literal(VerificationOptions.JsonInput),
+});
+
+// MARK - Union of all options
+export const zEvmContractVerifyOptionForm = z.union([
+ zEvmContractVerifyVyperOptionUploadFileForm,
+ zEvmContractVerifyVyperOptionContractCodeForm,
+ zEvmContractVerifyVyperOptionJsonInputForm,
+ zEvmContractVerifySolidityOptionUploadFilesForm,
+ zEvmContractVerifySolidityOptionContractCodeForm,
+ zEvmContractVerifySolidityOptionJsonInputForm,
+ zEvmContractVerifySolidityOptionHardhatForm,
+ zEvmContractVerifySolidityOptionFoundryForm,
+]);
+
+export const zEvmContractAddressAndLicenseForm = z.object({
+ contractAddress: zHexAddr20,
+ licenseType: z.string().refine((val) => val !== ""),
+ language: z.nativeEnum(EvmProgrammingLanguage),
+ compilerVersion: z.string().refine((val) => val !== ""),
+});
+
+export const zEvmContractVerifyForm = zEvmContractAddressAndLicenseForm.merge(
+ z.object({
+ verifyForm: zEvmContractVerifyOptionForm,
+ })
+);
+export type EvmContractVerifyForm = z.infer;
diff --git a/src/pages/[network]/evm-contracts/verify.tsx b/src/pages/[network]/evm-contracts/verify.tsx
new file mode 100644
index 000000000..58ac04251
--- /dev/null
+++ b/src/pages/[network]/evm-contracts/verify.tsx
@@ -0,0 +1,3 @@
+import { EvmContractVerify } from "lib/pages/evm-contract-verify";
+
+export default EvmContractVerify;
diff --git a/src/pages/evm-contracts/verify.tsx b/src/pages/evm-contracts/verify.tsx
new file mode 100644
index 000000000..58ac04251
--- /dev/null
+++ b/src/pages/evm-contracts/verify.tsx
@@ -0,0 +1,3 @@
+import { EvmContractVerify } from "lib/pages/evm-contract-verify";
+
+export default EvmContractVerify;