From 7ca5e620371157a35d9f05286614d61ae49d7a33 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Thu, 9 Jan 2025 13:06:56 +0700 Subject: [PATCH 1/7] feat: add verify onboarding --- .../evm-verify-section/NotVerifiedDetails.tsx | 53 +++++++++++++++++++ .../components/evm-verify-section/index.ts | 1 + .../components/EvmContractDetailsOverview.tsx | 30 +++++++---- src/lib/pages/evm-contract-details/index.tsx | 3 +- 4 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 src/lib/components/evm-verify-section/NotVerifiedDetails.tsx create mode 100644 src/lib/components/evm-verify-section/index.ts diff --git a/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx b/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx new file mode 100644 index 000000000..801651f42 --- /dev/null +++ b/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx @@ -0,0 +1,53 @@ +import { Button, Flex, Text } from "@chakra-ui/react"; + +import { useInternalNavigate } from "lib/app-provider"; +import type { HexAddr20 } from "lib/types"; + +interface NotVerifiedDetailsProps { + contractAddress: HexAddr20; +} + +export const NotVerifiedDetails = ({ + contractAddress, +}: NotVerifiedDetailsProps) => { + const navigate = useInternalNavigate(); + + const handleNavigate = () => + navigate({ + pathname: "/evm-contracts/[contractAddress]/verify", + query: { contractAddress }, + }); + + return ( + + + This contract has not been verified. If you are the owner, you can{" "} + + verify it + {" "} + to allow other users to view the source code + + + + ); +}; diff --git a/src/lib/components/evm-verify-section/index.ts b/src/lib/components/evm-verify-section/index.ts new file mode 100644 index 000000000..c97512379 --- /dev/null +++ b/src/lib/components/evm-verify-section/index.ts @@ -0,0 +1 @@ +export * from "./NotVerifiedDetails"; diff --git a/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx b/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx index 2efd6a792..a3216bfdf 100644 --- a/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx +++ b/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx @@ -1,18 +1,26 @@ -import { Flex, Grid, Heading, Spinner, Stack, Text } from "@chakra-ui/react"; +import { Flex, Grid, Spinner, Stack, Text } from "@chakra-ui/react"; import type { TxsTabIndex } from "../types"; import { useCelatoneApp, useMobile } from "lib/app-provider"; import { AssetsSection } from "lib/components/asset"; +import { NotVerifiedDetails } from "lib/components/evm-verify-section"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { LabelText } from "lib/components/LabelText"; import { useFormatAddresses } from "lib/hooks/useFormatAddresses"; -import type { BechAddr, BechAddr20, Nullish, Option } from "lib/types"; +import type { + BechAddr, + BechAddr20, + HexAddr20, + Nullish, + Option, +} from "lib/types"; import { dateFromNow, formatEvmTxHash, formatUTC } from "lib/utils"; import { EvmContractDetailsTxs } from "./EvmContractDetailsTxs"; interface EvmContractDetailsOverviewProps { - contractAddress: BechAddr20; + contractAddressBech: BechAddr20; + contractAddress: HexAddr20; hash: Option; evmHash: Nullish; sender: Option; @@ -25,6 +33,7 @@ interface EvmContractDetailsOverviewProps { } export const EvmContractDetailsOverview = ({ + contractAddressBech, contractAddress, hash, evmHash, @@ -42,18 +51,16 @@ export const EvmContractDetailsOverview = ({ return ( + {/* // TODO: Support all status */} + - - Contract Info - - + Date: Thu, 9 Jan 2025 13:10:03 +0700 Subject: [PATCH 2/7] docs: changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d61af53f1..2e8baff0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#1187](https://github.com/alleslabs/celatone-frontend/pull/1187) Add onboarding section to EVM contract details page - [#1184](https://github.com/alleslabs/celatone-frontend/pull/1184) Add custom layer to Initia Widget - [#1182](https://github.com/alleslabs/celatone-frontend/pull/1182) Add Initia Widget From e59f7160f77eaa9f3810554c17f6b456068781c9 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Thu, 9 Jan 2025 17:42:48 +0700 Subject: [PATCH 3/7] feat(pages): verify page --- src/lib/amplitude/types.ts | 1 + .../components/EvmContractVerifyTop.tsx | 14 ++++ src/lib/pages/evm-contract-verify/index.tsx | 70 +++++++++++++++++++ src/lib/pages/evm-contract-verify/types.ts | 6 ++ .../[contractAddress]/verify/index.tsx | 3 + .../[contractAddress]/verify/index.tsx | 3 + 6 files changed, 97 insertions(+) create mode 100644 src/lib/pages/evm-contract-verify/components/EvmContractVerifyTop.tsx create mode 100644 src/lib/pages/evm-contract-verify/index.tsx create mode 100644 src/lib/pages/evm-contract-verify/types.ts create mode 100644 src/pages/[network]/evm-contracts/[contractAddress]/verify/index.tsx create mode 100644 src/pages/evm-contracts/[contractAddress]/verify/index.tsx diff --git a/src/lib/amplitude/types.ts b/src/lib/amplitude/types.ts index d88441143..fb44e746b 100644 --- a/src/lib/amplitude/types.ts +++ b/src/lib/amplitude/types.ts @@ -55,6 +55,7 @@ export enum AmpEvent { TO_CONTRACT_DETAILS = "To Contract Detail", TO_CODE_DETAILS = "To Code Detail", TO_EVM_CONTRACT_DETAILS = "To EVM Contract Detail", + TO_EVM_CONTRACT_VERIFY = "To EVM Contract Verify", TO_PROJECT_DETAILS = "To Public Project Detail", TO_EVM_TRANSACTION_DETAILS = "To EVM Transaction Detail", TO_TRANSACTION_DETAILS = "To Transaction Detail", diff --git a/src/lib/pages/evm-contract-verify/components/EvmContractVerifyTop.tsx b/src/lib/pages/evm-contract-verify/components/EvmContractVerifyTop.tsx new file mode 100644 index 000000000..385e48912 --- /dev/null +++ b/src/lib/pages/evm-contract-verify/components/EvmContractVerifyTop.tsx @@ -0,0 +1,14 @@ +import { Heading, Stack, Text } from "@chakra-ui/react"; + +export const EvmContractVerifyTop = () => ( + + + Verify & Publish Contract + + + Verifying your contract offers enhanced credibility with a verified badge. + Once verified, users will able to access its source code in contract + details page. + + +); 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..d965f2776 --- /dev/null +++ b/src/lib/pages/evm-contract-verify/index.tsx @@ -0,0 +1,70 @@ +import { useConvertHexAddress, useEvmConfig } from "lib/app-provider"; +import { zEvmContractVerifyQueryParams } from "./types"; +import { useRouter } from "next/router"; +import { useEffect } from "react"; +import { track } from "@amplitude/analytics-browser"; +import { AmpEvent } from "lib/amplitude"; +import PageContainer from "lib/components/PageContainer"; +import { isHexWalletAddress } from "lib/utils"; +import { ErrorFetching, InvalidState } from "lib/components/state"; +import { HexAddr20 } from "lib/types"; +import { useEvmCodesByAddress } from "lib/services/evm"; +import { Loading } from "lib/components/Loading"; +import { CelatoneSeo } from "lib/components/Seo"; +import { truncate } from "lodash"; +import { Stack } from "@chakra-ui/react"; +import { EvmContractVerifyTop } from "./components/EvmContractVerifyTop"; + +const InvalidContract = () => ; + +interface EvmContractVerifyBodyProps { + contractAddress: HexAddr20; +} + +const EvmContractVerifyBody = ({ + contractAddress, +}: EvmContractVerifyBodyProps) => { + // const { convertHexWalletAddress } = useConvertHexAddress(); + // const contractAddressBechAddr = convertHexWalletAddress(contractAddress); + + const { data: evmCodesByAddressData, isLoading: isEvmCodesByAddressLoading } = + useEvmCodesByAddress(contractAddress); + + if (isEvmCodesByAddressLoading) return ; + if (!evmCodesByAddressData) + return ; + if (!evmCodesByAddressData.code) return ; + + return ( + <> + + + + + + ); +}; + +export const EvmContractVerify = () => { + // useEvmConfig({ shouldRedirect: true }); + const router = useRouter(); + + const validated = zEvmContractVerifyQueryParams.safeParse(router.query); + + useEffect(() => { + if (router.isReady && validated.success) + track(AmpEvent.TO_EVM_CONTRACT_VERIFY); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [router.isReady]); + + return ( + + {!validated.success || + !isHexWalletAddress(validated.data.contractAddress) ? ( + + ) : ( + + )} + + ); +}; 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..c5a354a87 --- /dev/null +++ b/src/lib/pages/evm-contract-verify/types.ts @@ -0,0 +1,6 @@ +import { zHexAddr20 } from "lib/types"; +import { z } from "zod"; + +export const zEvmContractVerifyQueryParams = z.object({ + contractAddress: zHexAddr20, +}); diff --git a/src/pages/[network]/evm-contracts/[contractAddress]/verify/index.tsx b/src/pages/[network]/evm-contracts/[contractAddress]/verify/index.tsx new file mode 100644 index 000000000..58ac04251 --- /dev/null +++ b/src/pages/[network]/evm-contracts/[contractAddress]/verify/index.tsx @@ -0,0 +1,3 @@ +import { EvmContractVerify } from "lib/pages/evm-contract-verify"; + +export default EvmContractVerify; diff --git a/src/pages/evm-contracts/[contractAddress]/verify/index.tsx b/src/pages/evm-contracts/[contractAddress]/verify/index.tsx new file mode 100644 index 000000000..58ac04251 --- /dev/null +++ b/src/pages/evm-contracts/[contractAddress]/verify/index.tsx @@ -0,0 +1,3 @@ +import { EvmContractVerify } from "lib/pages/evm-contract-verify"; + +export default EvmContractVerify; From 5bf33a31831d68619f57d3399ad0e456e283767a Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Thu, 9 Jan 2025 18:01:30 +0700 Subject: [PATCH 4/7] feat(pages): add verify page --- .../evm-verify-section/NotVerifiedDetails.tsx | 2 +- src/lib/pages/evm-contract-verify/index.tsx | 56 +++---------------- .../verify/index.tsx => verify.tsx} | 0 .../verify/index.tsx => verify.tsx} | 0 4 files changed, 8 insertions(+), 50 deletions(-) rename src/pages/[network]/evm-contracts/{[contractAddress]/verify/index.tsx => verify.tsx} (100%) rename src/pages/evm-contracts/{[contractAddress]/verify/index.tsx => verify.tsx} (100%) diff --git a/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx b/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx index 801651f42..8c3c20d5b 100644 --- a/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx +++ b/src/lib/components/evm-verify-section/NotVerifiedDetails.tsx @@ -14,7 +14,7 @@ export const NotVerifiedDetails = ({ const handleNavigate = () => navigate({ - pathname: "/evm-contracts/[contractAddress]/verify", + pathname: "/evm-contracts/verify", query: { contractAddress }, }); diff --git a/src/lib/pages/evm-contract-verify/index.tsx b/src/lib/pages/evm-contract-verify/index.tsx index d965f2776..668762cd4 100644 --- a/src/lib/pages/evm-contract-verify/index.tsx +++ b/src/lib/pages/evm-contract-verify/index.tsx @@ -1,70 +1,28 @@ -import { useConvertHexAddress, useEvmConfig } from "lib/app-provider"; -import { zEvmContractVerifyQueryParams } from "./types"; +import { useEvmConfig } from "lib/app-provider"; import { useRouter } from "next/router"; import { useEffect } from "react"; import { track } from "@amplitude/analytics-browser"; import { AmpEvent } from "lib/amplitude"; import PageContainer from "lib/components/PageContainer"; -import { isHexWalletAddress } from "lib/utils"; -import { ErrorFetching, InvalidState } from "lib/components/state"; -import { HexAddr20 } from "lib/types"; -import { useEvmCodesByAddress } from "lib/services/evm"; -import { Loading } from "lib/components/Loading"; import { CelatoneSeo } from "lib/components/Seo"; -import { truncate } from "lodash"; import { Stack } from "@chakra-ui/react"; import { EvmContractVerifyTop } from "./components/EvmContractVerifyTop"; -const InvalidContract = () => ; - -interface EvmContractVerifyBodyProps { - contractAddress: HexAddr20; -} - -const EvmContractVerifyBody = ({ - contractAddress, -}: EvmContractVerifyBodyProps) => { - // const { convertHexWalletAddress } = useConvertHexAddress(); - // const contractAddressBechAddr = convertHexWalletAddress(contractAddress); - - const { data: evmCodesByAddressData, isLoading: isEvmCodesByAddressLoading } = - useEvmCodesByAddress(contractAddress); - - if (isEvmCodesByAddressLoading) return ; - if (!evmCodesByAddressData) - return ; - if (!evmCodesByAddressData.code) return ; - - return ( - <> - - - - - - ); -}; - export const EvmContractVerify = () => { - // useEvmConfig({ shouldRedirect: true }); + useEvmConfig({ shouldRedirect: true }); const router = useRouter(); - const validated = zEvmContractVerifyQueryParams.safeParse(router.query); - useEffect(() => { - if (router.isReady && validated.success) - track(AmpEvent.TO_EVM_CONTRACT_VERIFY); + if (router.isReady) track(AmpEvent.TO_EVM_CONTRACT_VERIFY); // eslint-disable-next-line react-hooks/exhaustive-deps }, [router.isReady]); return ( - {!validated.success || - !isHexWalletAddress(validated.data.contractAddress) ? ( - - ) : ( - - )} + + + + ); }; diff --git a/src/pages/[network]/evm-contracts/[contractAddress]/verify/index.tsx b/src/pages/[network]/evm-contracts/verify.tsx similarity index 100% rename from src/pages/[network]/evm-contracts/[contractAddress]/verify/index.tsx rename to src/pages/[network]/evm-contracts/verify.tsx diff --git a/src/pages/evm-contracts/[contractAddress]/verify/index.tsx b/src/pages/evm-contracts/verify.tsx similarity index 100% rename from src/pages/evm-contracts/[contractAddress]/verify/index.tsx rename to src/pages/evm-contracts/verify.tsx From d37f1eb814d88fecd9dd5c447f1c1b6d5e37fd6d Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Sun, 12 Jan 2025 14:28:55 +0700 Subject: [PATCH 5/7] feat(pages): add entry form --- src/lib/components/forms/SelectInput.tsx | 146 +++++++---- src/lib/hooks/index.ts | 1 + src/lib/hooks/useStepper.ts | 48 ++++ .../manual/components/AddNetworkStepper.tsx | 2 +- .../manual/{hooks/utils.tsx => helpers.tsx} | 0 .../manual/hooks/useNetworkStepper.ts | 58 ----- src/lib/pages/custom-network/manual/index.tsx | 13 +- .../ContractLicenseInfoAccordion.tsx | 52 ++++ .../components/EvmContractVerifyFooter.tsx | 47 ++++ .../components/EvmContractVerifyOptions.tsx | 108 ++++++++ .../solidity/EvmContractVerifySolidity.tsx | 44 ++++ .../EvmContractVerifySolidityContractCode.tsx | 3 + .../EvmContractVerifySolidityFoundry.tsx | 3 + .../EvmContractVerifySolidityHardhat.tsx | 3 + .../EvmContractVerifySolidityJsonInput.tsx | 3 + .../EvmContractVerifySolidityUploadFiles.tsx | 3 + .../vyper/EvmContractVerifyVyper.tsx | 38 +++ .../EvmContractVerifyVyperContractCode.tsx | 3 + .../vyper/EvmContractVerifyVyperJsonInput.tsx | 3 + .../EvmContractVerifyVyperUploadFile.tsx | 3 + src/lib/pages/evm-contract-verify/index.tsx | 241 +++++++++++++++++- src/lib/pages/evm-contract-verify/types.ts | 82 ++++++ 22 files changed, 778 insertions(+), 126 deletions(-) create mode 100644 src/lib/hooks/useStepper.ts rename src/lib/pages/custom-network/manual/{hooks/utils.tsx => helpers.tsx} (100%) delete mode 100644 src/lib/pages/custom-network/manual/hooks/useNetworkStepper.ts create mode 100644 src/lib/pages/evm-contract-verify/components/ContractLicenseInfoAccordion.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/EvmContractVerifyFooter.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/EvmContractVerifyOptions.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidity.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityContractCode.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityFoundry.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityHardhat.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityJsonInput.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidityUploadFiles.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyper.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperContractCode.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperJsonInput.tsx create mode 100644 src/lib/pages/evm-contract-verify/components/vyper/EvmContractVerifyVyperUploadFile.tsx diff --git a/src/lib/components/forms/SelectInput.tsx b/src/lib/components/forms/SelectInput.tsx index 960ba26f5..0273ab6cd 100644 --- a/src/lib/components/forms/SelectInput.tsx +++ b/src/lib/components/forms/SelectInput.tsx @@ -1,3 +1,4 @@ +import { Flex, Stack, Text } from "@chakra-ui/react"; import type { SystemStyleObject } from "@chakra-ui/styled-system"; import type { Props } from "chakra-react-select"; import { Select } from "chakra-react-select"; @@ -13,7 +14,10 @@ export interface SelectInputOption { interface SelectInputProps< OptionValue extends SelectInputOptionValue, IsMulti extends boolean = false, -> extends Props, IsMulti> {} +> extends Props, IsMulti> { + label?: string; + isRequired?: boolean; +} const handleFilterOption = ( candidate: { label: string; value: string }, @@ -48,60 +52,90 @@ export const SelectInput = < onFocus, autoFocus, classNamePrefix, + label, + isRequired, + isDisabled, }: SelectInputProps) => ( - , IsMulti> - menuPosition="fixed" - menuPortalTarget={menuPortalTarget} - placeholder={placeholder} - options={options} - value={value} - onChange={onChange} - size={size} - filterOption={handleFilterOption} - formatOptionLabel={formatOptionLabel} - components={components} - isSearchable={isSearchable} - chakraStyles={{ - container: (provided: SystemStyleObject) => ({ - ...provided, - width: "100%", - }), - valueContainer: (provided: SystemStyleObject) => ({ - ...provided, - pl: 3, - pr: 0, - }), - dropdownIndicator: (provided: SystemStyleObject) => ({ - ...provided, - px: 2, - color: "gray.600", - }), - placeholder: (provided: SystemStyleObject) => ({ - ...provided, - color: "gray.500", - fontSize: "14px", - whiteSpace: "nowrap", - }), - option: (provided) => ({ - ...provided, - color: "text.main", - fontSize: "16px", - _hover: { - bg: "gray.700", - }, - _selected: { - bg: "gray.800", - }, - }), - ...chakraStyles, - }} - inputId={inputId} - name={name} - isMulti={isMulti} - closeMenuOnSelect={closeMenuOnSelect} - onBlur={onBlur} - onFocus={onFocus} - autoFocus={autoFocus} - classNamePrefix={classNamePrefix} - /> + + {label && ( + + {label} + + )} + , IsMulti> + menuPosition="fixed" + menuPortalTarget={menuPortalTarget} + placeholder={placeholder} + options={options} + value={value} + isDisabled={isDisabled} + onChange={onChange} + size={size} + filterOption={handleFilterOption} + formatOptionLabel={formatOptionLabel} + components={components} + isSearchable={isSearchable} + chakraStyles={{ + container: (provided: SystemStyleObject) => ({ + ...provided, + width: "100%", + }), + valueContainer: (provided: SystemStyleObject) => ({ + ...provided, + pl: 3, + pr: 0, + }), + dropdownIndicator: (provided: SystemStyleObject) => ({ + ...provided, + px: 2, + color: "gray.600", + }), + placeholder: (provided: SystemStyleObject) => ({ + ...provided, + color: "gray.500", + fontSize: "14px", + whiteSpace: "nowrap", + }), + option: (provided) => ({ + ...provided, + color: "text.main", + fontSize: "16px", + _hover: { + bg: "gray.700", + }, + _selected: { + bg: "gray.800", + }, + }), + ...chakraStyles, + }} + inputId={inputId} + name={name} + isMulti={isMulti} + closeMenuOnSelect={closeMenuOnSelect} + onBlur={onBlur} + onFocus={onFocus} + autoFocus={autoFocus} + classNamePrefix={classNamePrefix} + /> + ); diff --git a/src/lib/hooks/index.ts b/src/lib/hooks/index.ts index 40d47cfb5..40356db72 100644 --- a/src/lib/hooks/index.ts +++ b/src/lib/hooks/index.ts @@ -13,3 +13,4 @@ export * from "./useGetMaxLengthError"; export * from "./useLocalStorage"; export * from "./useUploadCode"; export * from "./useTxBroadcast"; +export * from "./useStepper"; diff --git a/src/lib/hooks/useStepper.ts b/src/lib/hooks/useStepper.ts new file mode 100644 index 000000000..d46335c5e --- /dev/null +++ b/src/lib/hooks/useStepper.ts @@ -0,0 +1,48 @@ +import { usePathname, useRouter, useSearchParams } from "next/navigation"; +import { useCallback, useEffect } from "react"; + +export const useStepper = ( + total: number, + handleSubmit: () => void, + handleBack?: () => void +) => { + const router = useRouter(); + const pathname = usePathname(); + const searchParams = useSearchParams(); + + const currentStep = searchParams.get("step") ?? "1"; + + useEffect(() => { + if (Number(currentStep) === 1) return; + const params = new URLSearchParams(searchParams); + params.set("step", "1"); + router.replace(`${pathname}?${params.toString()}`); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const handleNext = useCallback(() => { + const params = new URLSearchParams(searchParams); + params.set("step", String(Number(currentStep) + 1)); + + return currentStep && Number(currentStep) < total + ? router.replace(`${pathname}?${params.toString()}`) + : handleSubmit(); + }, [currentStep, handleSubmit, total, pathname, router, searchParams]); + + const handlePrevious = useCallback(() => { + const params = new URLSearchParams(searchParams); + params.set("step", String(Number(currentStep) - 1)); + + return currentStep && Number(currentStep) > 1 + ? router.replace(`${pathname}?${params.toString()}`) + : (handleBack?.() ?? router.back()); + }, [currentStep, pathname, router, searchParams, handleBack]); + + return { + currentStepIndex: Number(currentStep) - 1, + handleNext, + handlePrevious, + hasNext: Number(currentStep) < total, + hasPrevious: Number(currentStep) > 1, + }; +}; diff --git a/src/lib/pages/custom-network/manual/components/AddNetworkStepper.tsx b/src/lib/pages/custom-network/manual/components/AddNetworkStepper.tsx index 592981a9a..4024b1767 100644 --- a/src/lib/pages/custom-network/manual/components/AddNetworkStepper.tsx +++ b/src/lib/pages/custom-network/manual/components/AddNetworkStepper.tsx @@ -1,6 +1,6 @@ import { Flex, Text } from "@chakra-ui/react"; -import { getStepStyles } from "../hooks/utils"; +import { getStepStyles } from "../helpers"; const steps = [ { label: "Network Details" }, diff --git a/src/lib/pages/custom-network/manual/hooks/utils.tsx b/src/lib/pages/custom-network/manual/helpers.tsx similarity index 100% rename from src/lib/pages/custom-network/manual/hooks/utils.tsx rename to src/lib/pages/custom-network/manual/helpers.tsx diff --git a/src/lib/pages/custom-network/manual/hooks/useNetworkStepper.ts b/src/lib/pages/custom-network/manual/hooks/useNetworkStepper.ts deleted file mode 100644 index 995f355e9..000000000 --- a/src/lib/pages/custom-network/manual/hooks/useNetworkStepper.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { useRouter } from "next/router"; -import { useEffect } from "react"; - -import { useCelatoneApp, useInternalNavigate } from "lib/app-provider"; - -export const useNetworkStepper = (limit: number, handleSubmit: () => void) => { - const router = useRouter(); - const navigate = useInternalNavigate(); - const currentStep = router.query.step; - const { currentChainId } = useCelatoneApp(); - - useEffect(() => { - if (Number(currentStep) === 1) return; - - router.push( - { - query: { - network: currentChainId, - step: 1, - }, - }, - undefined, - { shallow: true } - ); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const handleNext = () => - currentStep && Number(currentStep) < limit - ? router.push( - { - query: { - network: currentChainId, - step: Number(currentStep) + 1, - }, - }, - undefined, - { shallow: true } - ) - : handleSubmit(); - - const handlePrevious = () => { - if (Number(currentStep) === 1) { - navigate({ pathname: "/custom-network/add" }); - return; - } - - router.back(); - }; - - return { - currentStepIndex: Number(currentStep) - 1, - handleNext, - handlePrevious, - hasNext: Number(currentStep) < limit, - hasPrevious: Number(currentStep) > 1, - }; -}; diff --git a/src/lib/pages/custom-network/manual/index.tsx b/src/lib/pages/custom-network/manual/index.tsx index 46a0796a3..8f14ab7e0 100644 --- a/src/lib/pages/custom-network/manual/index.tsx +++ b/src/lib/pages/custom-network/manual/index.tsx @@ -13,7 +13,11 @@ import { zWalletRegistryForm, } from "../types"; import type { AddNetworkManualForm } from "../types"; -import { useAllowCustomNetworks, useChainConfigs } from "lib/app-provider"; +import { + useAllowCustomNetworks, + useChainConfigs, + useInternalNavigate, +} from "lib/app-provider"; import ActionPageContainer from "lib/components/ActionPageContainer"; import { CustomIcon } from "lib/components/icon"; import { FooterCta } from "lib/components/layouts"; @@ -21,10 +25,11 @@ import { CelatoneSeo } from "lib/components/Seo"; import { useLocalChainConfigStore } from "lib/providers/store"; import { AddNetworkForm, AddNetworkStepper } from "./components"; -import { useNetworkStepper } from "./hooks/useNetworkStepper"; +import { useStepper } from "lib/hooks"; export const AddNetworkManual = () => { useAllowCustomNetworks({ shouldRedirect: true }); + const navigate = useInternalNavigate(); const { isOpen, onClose, onOpen } = useDisclosure(); const { addLocalChainConfig } = useLocalChainConfigStore(); const { isChainIdExist } = useChainConfigs(); @@ -95,7 +100,9 @@ export const AddNetworkManual = () => { }; const { currentStepIndex, handleNext, handlePrevious, hasNext, hasPrevious } = - useNetworkStepper(3, handleSubmit(handleSubmitForm)); + useStepper(3, handleSubmit(handleSubmitForm), () => + navigate({ pathname: "/custom-network/add" }) + ); const isFormDisabled = () => { if (currentStepIndex === 0) diff --git a/src/lib/pages/evm-contract-verify/components/ContractLicenseInfoAccordion.tsx b/src/lib/pages/evm-contract-verify/components/ContractLicenseInfoAccordion.tsx new file mode 100644 index 000000000..bea1386a3 --- /dev/null +++ b/src/lib/pages/evm-contract-verify/components/ContractLicenseInfoAccordion.tsx @@ -0,0 +1,52 @@ +import { + Accordion, + AccordionButton, + AccordionIcon, + AccordionItem, + AccordionPanel, + Text, +} from "@chakra-ui/react"; +import { UserDocsLink } from "lib/components/UserDocsLink"; + +export const ContractLicenseInfoAccordion = () => ( + + + + + What is contract license? + + + + + + A contract license specifies how a smart contract's code can be used, + modified, and distributed, ensuring legal clarity and protecting + creators' rights. + + + + + +); diff --git a/src/lib/pages/evm-contract-verify/components/EvmContractVerifyFooter.tsx b/src/lib/pages/evm-contract-verify/components/EvmContractVerifyFooter.tsx new file mode 100644 index 000000000..c9f2d0146 --- /dev/null +++ b/src/lib/pages/evm-contract-verify/components/EvmContractVerifyFooter.tsx @@ -0,0 +1,47 @@ +import { CustomIcon } from "lib/components/icon"; +import { FooterCta } from "lib/components/layouts"; + +interface EvmContractFooterProps { + handleNext: () => void; + handlePrevious: () => void; + hasNext: boolean; + hasPrevious: boolean; + isDisabled: boolean; +} + +export const EvmContractFooter = ({ + handleNext, + handlePrevious, + hasNext, + hasPrevious, + isDisabled, +}: EvmContractFooterProps) => ( + + ) : undefined, + }} + cancelLabel={hasPrevious ? "Previous" : "Cancel"} + actionButton={{ + onClick: handleNext, + isDisabled, + rightIcon: hasNext ? ( + + ) : undefined, + }} + actionLabel="Verify & Publish Contract" + sx={{ + backgroundColor: "background.main", + borderColor: "gray.700", + display: "grid", + gridTemplateColumns: "6fr 4fr", + px: "96px", + "> div": { + width: "100%", + }, + }} + /> +); diff --git a/src/lib/pages/evm-contract-verify/components/EvmContractVerifyOptions.tsx b/src/lib/pages/evm-contract-verify/components/EvmContractVerifyOptions.tsx new file mode 100644 index 000000000..890675c4a --- /dev/null +++ b/src/lib/pages/evm-contract-verify/components/EvmContractVerifyOptions.tsx @@ -0,0 +1,108 @@ +import { Grid, Heading, Radio, RadioGroup, Stack } from "@chakra-ui/react"; +import { Control, useController, useWatch } from "react-hook-form"; +import { + EvmContractVerifyForm, + EvmProgrammingLanguage, + VerificationOptions, +} from "../types"; + +interface EvmContractVerifyVyperProps { + control: Control; +} + +export const EvmContractVerifyOptions = ({ + control, +}: EvmContractVerifyVyperProps) => { + const { field: verifyFormOptinField } = useController({ + control, + name: "verifyForm.option", + }); + + const [verifyFormOption, language] = useWatch({ + control, + name: ["verifyForm.option", "language"], + }); + + return ( + + + Select Verification Option + + verifyFormOptinField.onChange(nextVal)} + value={verifyFormOption} + > + + {language === EvmProgrammingLanguage.Solidity && ( + + Upload Files + + )} + {language === EvmProgrammingLanguage.Vyper && ( + + Upload File + + )} + + Contract Code + + + JSON Input + + {language === EvmProgrammingLanguage.Solidity && ( + <> + + Hardhat + + + Foundry + + + )} + + + + ); +}; diff --git a/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidity.tsx b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidity.tsx new file mode 100644 index 000000000..7479c381c --- /dev/null +++ b/src/lib/pages/evm-contract-verify/components/solidity/EvmContractVerifySolidity.tsx @@ -0,0 +1,44 @@ +import { Divider, Stack } from "@chakra-ui/react"; +import { EvmContractVerifyOptions } from "../EvmContractVerifyOptions"; +import { Control, useWatch } from "react-hook-form"; +import { EvmContractVerifyForm, VerificationOptions } from "../../types"; +import { EvmContractVerifySolidityUploadFiles } from "./EvmContractVerifySolidityUploadFiles"; +import { EvmContractVerifySolidityContractCode } from "./EvmContractVerifySolidityContractCode"; +import { EvmContractVerifySolidityJsonInput } from "./EvmContractVerifySolidityJsonInput"; +import { EvmContractVerifySolidityHardhat } from "./EvmContractVerifySolidityHardhat"; +import { EvmContractVerifySolidityFoundry } from "./EvmContractVerifySolidityFoundry"; + +interface EvmContractVerifySolidityProps { + control: Control; +} + +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 index 668762cd4..7632c7ba4 100644 --- a/src/lib/pages/evm-contract-verify/index.tsx +++ b/src/lib/pages/evm-contract-verify/index.tsx @@ -1,28 +1,253 @@ -import { useEvmConfig } from "lib/app-provider"; +import { useEvmConfig, useExampleAddresses, useMobile } from "lib/app-provider"; import { useRouter } from "next/router"; -import { useEffect } from "react"; +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 { Stack } from "@chakra-ui/react"; +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, + LicenseType, + VerificationOptions, + zEvmContractVerifyForm, + zEvmContractVerifyOptionForm, +} 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: LicenseType.NoLicense, + }, + { + label: "2. The Unlicense (Unlicense)", + value: LicenseType.TheUnLicense, + }, + { + label: "3. MIT License (MIT)", + value: LicenseType.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 index c5a354a87..248085906 100644 --- a/src/lib/pages/evm-contract-verify/types.ts +++ b/src/lib/pages/evm-contract-verify/types.ts @@ -1,6 +1,88 @@ import { zHexAddr20 } from "lib/types"; import { z } from "zod"; +// TODO: Add more license types +export enum LicenseType { + NoLicense = "no-license", + TheUnLicense = "the-unlicense", + MIT = "mit", +} + +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.nativeEnum(LicenseType), + language: z.nativeEnum(EvmProgrammingLanguage), + compilerVersion: z.string().refine((val) => val !== ""), +}); + +export const zEvmContractVerifyForm = zEvmContractAddressAndLicenseForm.merge( + z.object({ + verifyForm: zEvmContractVerifyOptionForm, + }) +); +export type EvmContractVerifyForm = z.infer; From 4cfa0558d945c0e9a60f07c39264acaafe1d95c4 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Sun, 12 Jan 2025 14:31:22 +0700 Subject: [PATCH 6/7] docs: update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d0e86a946..3cf81252d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features -- [#1187](https://github.com/alleslabs/celatone-frontend/pull/1187) Add onboarding section to EVM contract details page +- [#1187](https://github.com/alleslabs/celatone-frontend/pull/1187) Add onboarding section to EVM contract details page and add EVM contract verify page - [#1184](https://github.com/alleslabs/celatone-frontend/pull/1184) Add custom layer to Initia Widget - [#1182](https://github.com/alleslabs/celatone-frontend/pull/1182) Add Initia Widget From 2ac6106979c8cf0a94b51faca49b30090f558776 Mon Sep 17 00:00:00 2001 From: Poafs1 Date: Mon, 13 Jan 2025 14:40:58 +0700 Subject: [PATCH 7/7] fix(pages): pr comment --- .../components/EvmContractDetailsOverview.tsx | 6 +++--- src/lib/pages/evm-contract-details/index.tsx | 2 +- src/lib/pages/evm-contract-verify/index.tsx | 8 +++----- src/lib/pages/evm-contract-verify/types.ts | 9 +-------- 4 files changed, 8 insertions(+), 17 deletions(-) diff --git a/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx b/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx index a3216bfdf..6e484da65 100644 --- a/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx +++ b/src/lib/pages/evm-contract-details/components/EvmContractDetailsOverview.tsx @@ -20,7 +20,7 @@ import { EvmContractDetailsTxs } from "./EvmContractDetailsTxs"; interface EvmContractDetailsOverviewProps { contractAddressBech: BechAddr20; - contractAddress: HexAddr20; + contractAddressHex: HexAddr20; hash: Option; evmHash: Nullish; sender: Option; @@ -34,7 +34,7 @@ interface EvmContractDetailsOverviewProps { export const EvmContractDetailsOverview = ({ contractAddressBech, - contractAddress, + contractAddressHex, hash, evmHash, sender, @@ -52,7 +52,7 @@ export const EvmContractDetailsOverview = ({ return ( {/* // TODO: Support all status */} - + { () => [ { label: "1. No License (None)", - value: LicenseType.NoLicense, + value: "no-license", }, { label: "2. The Unlicense (Unlicense)", - value: LicenseType.TheUnLicense, + value: "the-unlicense", }, { label: "3. MIT License (MIT)", - value: LicenseType.MIT, + value: "mit", }, ], [] diff --git a/src/lib/pages/evm-contract-verify/types.ts b/src/lib/pages/evm-contract-verify/types.ts index 248085906..fa8a23f11 100644 --- a/src/lib/pages/evm-contract-verify/types.ts +++ b/src/lib/pages/evm-contract-verify/types.ts @@ -1,13 +1,6 @@ import { zHexAddr20 } from "lib/types"; import { z } from "zod"; -// TODO: Add more license types -export enum LicenseType { - NoLicense = "no-license", - TheUnLicense = "the-unlicense", - MIT = "mit", -} - export enum EvmProgrammingLanguage { Solidity = "solidity", Vyper = "vyper", @@ -75,7 +68,7 @@ export const zEvmContractVerifyOptionForm = z.union([ export const zEvmContractAddressAndLicenseForm = z.object({ contractAddress: zHexAddr20, - licenseType: z.nativeEnum(LicenseType), + licenseType: z.string().refine((val) => val !== ""), language: z.nativeEnum(EvmProgrammingLanguage), compilerVersion: z.string().refine((val) => val !== ""), });