From 9a3612f384ab1ac113e45989d14327d14d8f9f54 Mon Sep 17 00:00:00 2001 From: Jennie Alles Date: Thu, 1 Aug 2024 12:44:49 +0700 Subject: [PATCH 01/27] fix(components): add ui for verification in upload section --- .../json-schema/upload/UploadSchema.tsx | 30 ++- .../upload/IndirectlyVerifiedAlert.tsx | 16 ++ src/lib/components/upload/OptionButton.tsx | 30 +++ src/lib/components/upload/UploadSection.tsx | 2 + .../components/upload/VerificationStatus.tsx | 39 ++++ src/lib/components/upload/index.ts | 8 + .../components/UploadScriptCard.tsx | 2 +- .../migrate/components/UploadNewCode.tsx | 2 +- src/lib/pages/proposal/store-code/index.tsx | 10 +- .../components/UploadModuleCard.tsx | 2 +- src/lib/pages/upload/completed.tsx | 173 ++++++++++-------- src/lib/pages/upload/upload.tsx | 2 +- 12 files changed, 221 insertions(+), 95 deletions(-) create mode 100644 src/lib/components/upload/IndirectlyVerifiedAlert.tsx create mode 100644 src/lib/components/upload/OptionButton.tsx create mode 100644 src/lib/components/upload/VerificationStatus.tsx create mode 100644 src/lib/components/upload/index.ts diff --git a/src/lib/components/json-schema/upload/UploadSchema.tsx b/src/lib/components/json-schema/upload/UploadSchema.tsx index dafc060e4..a35b7eb51 100644 --- a/src/lib/components/json-schema/upload/UploadSchema.tsx +++ b/src/lib/components/json-schema/upload/UploadSchema.tsx @@ -1,4 +1,5 @@ -import { useDisclosure } from "@chakra-ui/react"; +import { Flex, useDisclosure } from "@chakra-ui/react"; +import type { ReactNode } from "react"; import { AttachSchemaCard } from "../AttachSchemaCard"; import { JsonSchemaModal } from "../JsonSchemaModal"; @@ -10,6 +11,7 @@ interface UploadSchemaContentInterface { schema: Option; codeId: number; codeHash: string; + triggerElement?: ReactNode; } export const UploadSchema = ({ @@ -17,17 +19,29 @@ export const UploadSchema = ({ schema, codeId, codeHash, + triggerElement, }: UploadSchemaContentInterface) => { const { isOpen, onOpen, onClose } = useDisclosure(); return ( <> - + {triggerElement ? ( + { + e.stopPropagation(); + onOpen(); + }} + > + {triggerElement} + + ) : ( + + )} ( + + + + {/* TODO: add code that have the same hash */} + + This code has the same code hash as the following verified stored codes: + 1234, 1235, 1236 and more + + + +); diff --git a/src/lib/components/upload/OptionButton.tsx b/src/lib/components/upload/OptionButton.tsx new file mode 100644 index 000000000..9f8f5d614 --- /dev/null +++ b/src/lib/components/upload/OptionButton.tsx @@ -0,0 +1,30 @@ +import { Flex, Text } from "@chakra-ui/react"; + +import { CustomIcon } from "lib/components/icon"; + +interface OptionButtonProps { + title: string; + description: string; +} + +export const OptionButton = ({ title, description }: OptionButtonProps) => ( + + + + {title} + + + {description} + + + + +); diff --git a/src/lib/components/upload/UploadSection.tsx b/src/lib/components/upload/UploadSection.tsx index 22c02d381..9582594b7 100644 --- a/src/lib/components/upload/UploadSection.tsx +++ b/src/lib/components/upload/UploadSection.tsx @@ -17,6 +17,7 @@ import type { import { getCodeHash } from "lib/utils"; import { CodeHashBox } from "./CodeHashBox"; +import { IndirectlyVerifiedAlert } from "./IndirectlyVerifiedAlert"; import { InstantiatePermissionRadio } from "./InstantiatePermissionRadio"; import { SimulateMessageRender } from "./SimulateMessageRender"; import { UploadCard } from "./UploadCard"; @@ -112,6 +113,7 @@ export const UploadSection = ({ } variant="fixed-floating" /> + Instantiate Permission diff --git a/src/lib/components/upload/VerificationStatus.tsx b/src/lib/components/upload/VerificationStatus.tsx new file mode 100644 index 000000000..fa152c887 --- /dev/null +++ b/src/lib/components/upload/VerificationStatus.tsx @@ -0,0 +1,39 @@ +import { Flex, Text } from "@chakra-ui/react"; + +import { AppLink } from "lib/components/AppLink"; +import { CustomIcon } from "lib/components/icon"; + +interface VerificationStatusProps { + codeId: string; +} +export const VerificationStatus = ({ codeId }: VerificationStatusProps) => ( + + + + + Code verification is in progress + + + This process may take several hours depending on code complexity. View + status on + + + code details + + + page + + + +); diff --git a/src/lib/components/upload/index.ts b/src/lib/components/upload/index.ts new file mode 100644 index 000000000..aff3e8150 --- /dev/null +++ b/src/lib/components/upload/index.ts @@ -0,0 +1,8 @@ +export * from "./CodeHashBox"; +export * from "./IndirectlyVerifiedAlert"; +export * from "./InstantiatePermissionRadio"; +export * from "./OptionButton"; +export * from "./SimulateMessageRender"; +export * from "./UploadCard"; +export * from "./UploadSection"; +export * from "./VerificationStatus"; diff --git a/src/lib/pages/deploy-script/components/UploadScriptCard.tsx b/src/lib/pages/deploy-script/components/UploadScriptCard.tsx index 1c80cfcb6..142b03115 100644 --- a/src/lib/pages/deploy-script/components/UploadScriptCard.tsx +++ b/src/lib/pages/deploy-script/components/UploadScriptCard.tsx @@ -4,7 +4,7 @@ import { useCallback, useState } from "react"; import type { FileState } from ".."; import { ComponentLoader } from "lib/components/ComponentLoader"; import { DropZone } from "lib/components/dropzone"; -import { UploadCard } from "lib/components/upload/UploadCard"; +import { UploadCard } from "lib/components/upload"; import { useDecodeScript } from "lib/services/move/module"; import type { ExposedFunction, Option } from "lib/types"; diff --git a/src/lib/pages/migrate/components/UploadNewCode.tsx b/src/lib/pages/migrate/components/UploadNewCode.tsx index 65f0ea44a..120ea37d8 100644 --- a/src/lib/pages/migrate/components/UploadNewCode.tsx +++ b/src/lib/pages/migrate/components/UploadNewCode.tsx @@ -2,7 +2,7 @@ import { Heading } from "@chakra-ui/react"; import type { StdFee } from "@cosmjs/amino"; import type { UseFormReturn } from "react-hook-form"; -import { UploadSection } from "lib/components/upload/UploadSection"; +import { UploadSection } from "lib/components/upload"; import type { Option, SimulateStatus, UploadSectionState } from "lib/types"; interface UploadNewCodeProps { diff --git a/src/lib/pages/proposal/store-code/index.tsx b/src/lib/pages/proposal/store-code/index.tsx index c4c663342..6da3201f4 100644 --- a/src/lib/pages/proposal/store-code/index.tsx +++ b/src/lib/pages/proposal/store-code/index.tsx @@ -49,10 +49,12 @@ import { CustomIcon } from "lib/components/icon"; import PageContainer from "lib/components/PageContainer"; import { StickySidebar } from "lib/components/StickySidebar"; import { Tooltip } from "lib/components/Tooltip"; -import { CodeHashBox } from "lib/components/upload/CodeHashBox"; -import { InstantiatePermissionRadio } from "lib/components/upload/InstantiatePermissionRadio"; -import { SimulateMessageRender } from "lib/components/upload/SimulateMessageRender"; -import { UploadCard } from "lib/components/upload/UploadCard"; +import { + CodeHashBox, + InstantiatePermissionRadio, + SimulateMessageRender, + UploadCard, +} from "lib/components/upload"; import { useGetMaxLengthError, useTxBroadcast } from "lib/hooks"; import { useGovParamsDeprecated } from "lib/model/proposal"; import { useUploadAccessParamsLcd } from "lib/services/wasm/code"; diff --git a/src/lib/pages/publish-module/components/UploadModuleCard.tsx b/src/lib/pages/publish-module/components/UploadModuleCard.tsx index 5d8bae9b8..44970ba70 100644 --- a/src/lib/pages/publish-module/components/UploadModuleCard.tsx +++ b/src/lib/pages/publish-module/components/UploadModuleCard.tsx @@ -9,7 +9,7 @@ import { ComponentLoader } from "lib/components/ComponentLoader"; import { DropZone } from "lib/components/dropzone"; import { CustomIcon } from "lib/components/icon"; import { Tooltip } from "lib/components/Tooltip"; -import { UploadCard } from "lib/components/upload/UploadCard"; +import { UploadCard } from "lib/components/upload"; import { useDecodeModule } from "lib/services/move/module"; import type { DecodeModuleQueryResponse } from "lib/services/types"; import type { Option, UpgradePolicy } from "lib/types"; diff --git a/src/lib/pages/upload/completed.tsx b/src/lib/pages/upload/completed.tsx index 971a45252..e2e16e0b7 100644 --- a/src/lib/pages/upload/completed.tsx +++ b/src/lib/pages/upload/completed.tsx @@ -1,9 +1,8 @@ -import { Box, Button, Divider, Flex, Heading, Text } from "@chakra-ui/react"; +import { Button, Divider, Flex, Heading, Text } from "@chakra-ui/react"; import { observer } from "mobx-react-lite"; import type { StoreCodeTxInternalResult } from "lib/app-fns/tx/storeCode"; import { useInternalNavigate } from "lib/app-provider"; -import { ConnectingLine } from "lib/components/ConnectingLine"; import { EstimatedFeeRender } from "lib/components/EstimatedFeeRender"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { CustomIcon } from "lib/components/icon"; @@ -11,6 +10,11 @@ import { UploadSchema } from "lib/components/json-schema"; import { VerifyPublishCodeModal } from "lib/components/modal"; import { Stepper } from "lib/components/stepper"; import { TxReceiptRender } from "lib/components/tx"; +import { + IndirectlyVerifiedAlert, + OptionButton, + VerificationStatus, +} from "lib/components/upload"; import WasmPageContainer from "lib/components/WasmPageContainer"; import { useSchemaStore } from "lib/providers/store"; import { feeFromStr } from "lib/utils"; @@ -27,89 +31,100 @@ export const UploadComplete = observer(({ txResult }: UploadCompleteProps) => { return ( - - Deploy new contract - - - - - Upload Wasm File Complete! - - - ‘{txResult.codeDisplayName}’ has been uploaded. - - - , - }, - { - title: "Tx Hash", - html: , - }, - { - title: "Tx Fee", - html: ( - - ), - }, - ]} - variant="full" + + + Deploy new contract + + + - - - Would you like to attach JSON Schema to this code? - - - Your attached JSON schema will be stored locally on your device - - + + Upload Wasm File Complete! + + + ‘{txResult.codeDisplayName}’ has been uploaded. + - - Code ID: {txResult.codeId} + , + }, + { + title: "Tx Hash", + html: , + }, + { + title: "Tx Fee", + html: ( + + ), + }, + ]} + variant="full" + /> - - - - - Verfiy Code} - /> + + {!attached && ( + <> + + Would you like to: + + + + } + /> + + } + /> + + + )} + {/* TODO: add condition to show only when user submit the verification */} + + {attached && ( + + + + )} {!attached && ( diff --git a/src/lib/pages/upload/upload.tsx b/src/lib/pages/upload/upload.tsx index 278b5d747..dc82f2b1c 100644 --- a/src/lib/pages/upload/upload.tsx +++ b/src/lib/pages/upload/upload.tsx @@ -10,7 +10,7 @@ import { CustomIcon } from "lib/components/icon"; import { FooterCta } from "lib/components/layouts"; import { CelatoneSeo } from "lib/components/Seo"; import { Stepper } from "lib/components/stepper"; -import { UploadSection } from "lib/components/upload/UploadSection"; +import { UploadSection } from "lib/components/upload"; import { UserDocsLink } from "lib/components/UserDocsLink"; import WasmPageContainer from "lib/components/WasmPageContainer"; import { useUploadCode } from "lib/hooks"; From 63131395e0d688d695cabd77597a149ee3cf05c3 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:33:09 +0700 Subject: [PATCH 02/27] fix: invalidate query after submitting request --- .../upload/IndirectlyVerifiedAlert.tsx | 5 ++-- src/lib/pages/upload/completed.tsx | 5 ++-- src/lib/services/verification/wasm/index.ts | 24 +++++++++++++++---- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/lib/components/upload/IndirectlyVerifiedAlert.tsx b/src/lib/components/upload/IndirectlyVerifiedAlert.tsx index c0babc806..10a41185f 100644 --- a/src/lib/components/upload/IndirectlyVerifiedAlert.tsx +++ b/src/lib/components/upload/IndirectlyVerifiedAlert.tsx @@ -14,12 +14,11 @@ export const IndirectlyVerifiedAlert = ({ - {/* TODO: add code that have the same hash */} - + This code has the same code hash as the following verified stored codes: - + {" "} {formatRelatedVerifiedCodes(relatedVerifiedCodes)} diff --git a/src/lib/pages/upload/completed.tsx b/src/lib/pages/upload/completed.tsx index 06bbc32dc..26ffc2351 100644 --- a/src/lib/pages/upload/completed.tsx +++ b/src/lib/pages/upload/completed.tsx @@ -108,6 +108,9 @@ export const UploadComplete = observer(({ txResult }: UploadCompleteProps) => { /> )} + {wasmVerifyStatus === WasmVerifyStatus.IN_PROGRESS && ( + + )} {!attached && ( <> @@ -141,8 +144,6 @@ export const UploadComplete = observer(({ txResult }: UploadCompleteProps) => { )} - {/* TODO: add condition to show only when user submit the verification */} - {attached && ( - useMutation({ +export const useSubmitWasmVerify = () => { + const queryClient = useQueryClient(); + const { currentChainId } = useCelatoneApp(); + + return useMutation({ mutationFn: submitWasmVerify, + onSuccess(data, variables) { + queryClient.invalidateQueries({ + queryKey: [ + CELATONE_QUERY_KEYS.WASM_VERIFICATION_INFOS, + currentChainId, + variables.codeId, + ], + }); + }, }); +}; export const useWasmVerifyInfos = (codeIds: number[], enabled = true) => { const { currentChainId } = useCelatoneApp(); @@ -37,7 +50,7 @@ const useWasmRelatedVerifyInfos = (hashes: string[], enabled = true) => { const { currentChainId } = useCelatoneApp(); return useQuery( [ - CELATONE_QUERY_KEYS.WASM_VERIFICATION_INFOS, + CELATONE_QUERY_KEYS.WASM_RELATED_VERIFICATION_INFOS, currentChainId, ...hashes.sort(), ], @@ -65,7 +78,8 @@ export const useDerivedWasmVerifyInfo = ( return { data: undefined, isLoading: true }; const wasmVerifyInfo = wasmVerifyInfos?.[Number(codeId)]; - const wasmRelatedVerifyInfo = wasmRelatedVerifyInfos?.[hash ?? ""]; + const wasmRelatedVerifyInfo = + wasmRelatedVerifyInfos?.[hash?.toUpperCase() ?? ""]; return { data: { verificationInfo: wasmVerifyInfo?.verificationInfo ?? null, From d62aa8708288c1e5efee51ea83ad9d5fd7f48ade Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:46:50 +0700 Subject: [PATCH 03/27] fix: layout --- ...atus.tsx => InProgressVerifiedSection.tsx} | 6 +- src/lib/components/upload/index.ts | 2 +- .../IndirectlyVerifiedDetails.tsx | 4 +- src/lib/pages/upload/completed.tsx | 137 +++++++++--------- src/lib/utils/verification.ts | 6 +- 5 files changed, 81 insertions(+), 74 deletions(-) rename src/lib/components/upload/{VerificationStatus.tsx => InProgressVerifiedSection.tsx} (87%) diff --git a/src/lib/components/upload/VerificationStatus.tsx b/src/lib/components/upload/InProgressVerifiedSection.tsx similarity index 87% rename from src/lib/components/upload/VerificationStatus.tsx rename to src/lib/components/upload/InProgressVerifiedSection.tsx index fa152c887..731334d0a 100644 --- a/src/lib/components/upload/VerificationStatus.tsx +++ b/src/lib/components/upload/InProgressVerifiedSection.tsx @@ -3,10 +3,12 @@ import { Flex, Text } from "@chakra-ui/react"; import { AppLink } from "lib/components/AppLink"; import { CustomIcon } from "lib/components/icon"; -interface VerificationStatusProps { +interface InProgressVerifiedSectionProps { codeId: string; } -export const VerificationStatus = ({ codeId }: VerificationStatusProps) => ( +export const InProgressVerifiedSection = ({ + codeId, +}: InProgressVerifiedSectionProps) => ( ))} {relatedVerifiedCodes.length > 3 && " and more"} diff --git a/src/lib/pages/upload/completed.tsx b/src/lib/pages/upload/completed.tsx index 26ffc2351..bfb195fbd 100644 --- a/src/lib/pages/upload/completed.tsx +++ b/src/lib/pages/upload/completed.tsx @@ -1,4 +1,4 @@ -import { Button, Divider, Flex, Heading, Text } from "@chakra-ui/react"; +import { Box, Button, Divider, Flex, Heading, Text } from "@chakra-ui/react"; import { observer } from "mobx-react-lite"; import type { StoreCodeTxInternalResult } from "lib/app-fns/tx/storeCode"; @@ -12,8 +12,8 @@ import { Stepper } from "lib/components/stepper"; import { TxReceiptRender } from "lib/components/tx"; import { IndirectlyVerifiedAlert, + InProgressVerifiedSection, OptionButton, - VerificationStatus, } from "lib/components/upload"; import WasmPageContainer from "lib/components/WasmPageContainer"; import { WasmVerifyBadge } from "lib/components/WasmVerifyBadge"; @@ -40,76 +40,75 @@ export const UploadComplete = observer(({ txResult }: UploadCompleteProps) => { return ( - - - Deploy new contract - - - + Deploy new contract + + + + + Upload Wasm File Complete! + + + ‘{txResult.codeDisplayName}’ has been uploaded. + + + + } + /> + ), + }, + { + title: "Tx Hash", + html: , + }, + { + title: "Tx Fee", + html: ( + + ), + }, + ]} + variant="full" /> - - Upload Wasm File Complete! - - - ‘{txResult.codeDisplayName}’ has been uploaded. - - - - } - /> - ), - }, - { - title: "Tx Hash", - html: , - }, - { - title: "Tx Fee", - html: ( - - ), - }, - ]} - variant="full" - /> - - {wasmVerifyStatus === WasmVerifyStatus.INDIRECTLY_VERIFIED && ( - - )} + {wasmVerifyStatus === WasmVerifyStatus.INDIRECTLY_VERIFIED && ( + + )} + {wasmVerifyStatus === WasmVerifyStatus.IN_PROGRESS && ( - + )} {!attached && ( <> diff --git a/src/lib/utils/verification.ts b/src/lib/utils/verification.ts index 07dd154bb..acd459143 100644 --- a/src/lib/utils/verification.ts +++ b/src/lib/utils/verification.ts @@ -31,7 +31,11 @@ export const formatRelatedVerifiedCodes = (relatedVerifiedCodes: number[]) => { if (relatedVerifiedCodes.length > 2 && index < displayedCodes.length - 1) res += ","; if (index < displayedCodes.length - 1) res += " "; - if (index === relatedVerifiedCodes.length - 2) res += "and "; + if ( + index === relatedVerifiedCodes.length - 2 && + index < displayedCodes.length - 1 + ) + res += "and "; return res; }); if (relatedVerifiedCodes.length > 3) res += " and more"; From 3475d278d7c5999935c8d4c39da31feadd513f48 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Tue, 6 Aug 2024 18:48:10 +0700 Subject: [PATCH 04/27] fix: reordering --- src/lib/components/upload/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/components/upload/index.ts b/src/lib/components/upload/index.ts index 4622392f8..b97d3a01e 100644 --- a/src/lib/components/upload/index.ts +++ b/src/lib/components/upload/index.ts @@ -1,8 +1,8 @@ export * from "./CodeHashBox"; export * from "./IndirectlyVerifiedAlert"; +export * from "./InProgressVerifiedSection"; export * from "./InstantiatePermissionRadio"; export * from "./OptionButton"; export * from "./SimulateMessageRender"; export * from "./UploadCard"; export * from "./UploadSection"; -export * from "./InProgressVerifiedSection"; From 9f4cf8c8f55c4d157ef254dd2470ccec3151c921 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 7 Aug 2024 16:13:17 +0700 Subject: [PATCH 05/27] feat: support verified schema --- .../json-schema/AttachSchemaCard.tsx | 3 +- .../section/SchemaInputNotExist.tsx | 64 ++++++ .../section/SchemaInputSection.tsx | 65 ++---- .../json-schema/upload/UploadSchema.tsx | 3 +- .../upload/UploadSchemaSection.tsx | 3 +- .../json-schema/view/ViewSchemaModal.tsx | 5 +- .../WasmVerifyRequestInfo.tsx | 1 + src/lib/components/upload/OptionButton.tsx | 25 +++ .../wasm-verify-section/FailedDetails.tsx | 1 + .../components/code-local-schema/index.tsx | 5 +- src/lib/pages/instantiate/instantiate.tsx | 21 +- .../components/execute-area/index.tsx | 204 +++++++++--------- .../schema-execute/ExecuteBox.tsx | 8 +- .../execute-area/schema-execute/index.tsx | 55 ++--- .../components/query-area/index.tsx | 194 +++++++++-------- .../schema-query/SchemaQueryComponent.tsx | 2 +- .../schema-query/SchemaQueryResponse.tsx | 3 +- .../query-area/schema-query/index.tsx | 58 ++--- src/lib/pages/interact-contract/index.tsx | 13 ++ .../migrate/components/MigrateContract.tsx | 20 +- src/lib/pages/upload/completed.tsx | 83 +++---- src/lib/services/types/verification/wasm.ts | 4 +- src/lib/stores/schema.test.ts | 125 ++--------- src/lib/stores/schema.ts | 166 +------------- src/lib/types/verification.ts | 72 ++++++- .../_suites/verification/wasm/example.ts | 11 + .../wasm}/execute-schema-output.json | 0 .../wasm}/query-schema-output.json | 0 .../verification/wasm}/schema-example.json | 0 src/lib/utils/json.ts | 3 +- src/lib/utils/verification.ts | 43 ---- src/lib/utils/verification/index.ts | 1 + src/lib/utils/verification/wasm.test.ts | 87 ++++++++ src/lib/utils/verification/wasm.ts | 183 ++++++++++++++++ 34 files changed, 856 insertions(+), 675 deletions(-) create mode 100644 src/lib/components/json-schema/section/SchemaInputNotExist.tsx create mode 100644 src/lib/utils/_suites/verification/wasm/example.ts rename src/lib/{stores/schema-test-suite => utils/_suites/verification/wasm}/execute-schema-output.json (100%) rename src/lib/{stores/schema-test-suite => utils/_suites/verification/wasm}/query-schema-output.json (100%) rename src/lib/{stores/schema-test-suite => utils/_suites/verification/wasm}/schema-example.json (100%) delete mode 100644 src/lib/utils/verification.ts create mode 100644 src/lib/utils/verification/index.ts create mode 100644 src/lib/utils/verification/wasm.test.ts create mode 100644 src/lib/utils/verification/wasm.ts diff --git a/src/lib/components/json-schema/AttachSchemaCard.tsx b/src/lib/components/json-schema/AttachSchemaCard.tsx index 34303bdd4..d2602f6b5 100644 --- a/src/lib/components/json-schema/AttachSchemaCard.tsx +++ b/src/lib/components/json-schema/AttachSchemaCard.tsx @@ -4,8 +4,7 @@ import { useCallback } from "react"; import { RemoveSchemaModal } from "../modal/RemoveSchemaModal"; import { AmpEvent, track } from "lib/amplitude"; import { CustomIcon } from "lib/components/icon"; -import type { CodeSchema } from "lib/stores/schema"; -import type { Option } from "lib/types"; +import type { CodeSchema, Option } from "lib/types"; import { ViewSchemaModal } from "./view/ViewSchemaModal"; diff --git a/src/lib/components/json-schema/section/SchemaInputNotExist.tsx b/src/lib/components/json-schema/section/SchemaInputNotExist.tsx new file mode 100644 index 000000000..5fd401f43 --- /dev/null +++ b/src/lib/components/json-schema/section/SchemaInputNotExist.tsx @@ -0,0 +1,64 @@ +import { Text } from "@chakra-ui/react"; + +import { AttachSchemaCard } from "../AttachSchemaCard"; +import { CustomIcon } from "lib/components/icon"; +import type { CodeSchema, Nullish, Option } from "lib/types"; + +interface SchemaInputNotExistProps { + prettyType: string; + verifiedSchema: Nullish; + localSchema: Option; + codeId: number; + codeHash: string; + openModal: () => void; +} + +export const SchemaInputNotExist = ({ + prettyType, + verifiedSchema, + localSchema, + codeId, + codeHash, + openModal, +}: SchemaInputNotExistProps) => { + if (verifiedSchema) + return ( + + `Verified JSON Schema doesn’t have ${prettyType}Msg` + + ); + + return ( + <> + + {localSchema ? ( + `Attached JSON Schema doesn’t have ${prettyType}Msg` + ) : ( + <> + You haven't attached the JSON Schema for{" "} + + code {codeId} yet + + )} + + + {localSchema + ? `Please fill in ${prettyType} Message manually or change the schema` + : "Your attached JSON schema will be stored locally on your device"} + + + + ); +}; diff --git a/src/lib/components/json-schema/section/SchemaInputSection.tsx b/src/lib/components/json-schema/section/SchemaInputSection.tsx index 43bba5263..a5b8c8008 100644 --- a/src/lib/components/json-schema/section/SchemaInputSection.tsx +++ b/src/lib/components/json-schema/section/SchemaInputSection.tsx @@ -1,23 +1,23 @@ import { Button, Flex, Text, useDisclosure } from "@chakra-ui/react"; -import type { RJSFSchema, RJSFValidationError } from "@rjsf/utils"; +import type { RJSFValidationError } from "@rjsf/utils"; import { capitalize } from "lodash"; import { observer } from "mobx-react-lite"; import { useCallback } from "react"; -import { AttachSchemaCard } from "../AttachSchemaCard"; import { JsonSchemaForm } from "../form"; import { JsonSchemaModal } from "../JsonSchemaModal"; import { ViewSchemaModal } from "../view/ViewSchemaModal"; import { AmpEvent, track } from "lib/amplitude"; -import { CustomIcon } from "lib/components/icon"; -import type { CodeSchema } from "lib/stores/schema"; -import type { Option } from "lib/types"; +import type { CodeSchema, Nullish, Option } from "lib/types"; + +import { SchemaInputNotExist } from "./SchemaInputNotExist"; interface SchemaSectionProps { type: "migrate" | "instantiate"; codeHash: string; codeId: number; - jsonSchema: Option; + verifiedSchema: Nullish; + localSchema: Option; initialFormData?: Record; handleChange: (data: unknown, errors: RJSFValidationError[]) => void; onSchemaSave?: () => void; @@ -28,13 +28,14 @@ export const SchemaInputSection = observer( type, codeHash, codeId, - jsonSchema, + verifiedSchema, + localSchema, initialFormData, handleChange, onSchemaSave, }: SchemaSectionProps) => { const { isOpen, onClose, onOpen } = useDisclosure(); - const msgSchema = jsonSchema?.[type]; + const msgSchema = verifiedSchema?.[type] ?? localSchema?.[type]; const prettyType = capitalize(type); const handleReattach = useCallback(() => { @@ -54,11 +55,10 @@ export const SchemaInputSection = observer( > {msgSchema ? ( <> - {/* TODO: revisit type assertion later */} {msgSchema.properties ? (
) : ( - <> - - {jsonSchema ? ( - `Attached JSON Schema doesn’t have ${prettyType}Msg` - ) : ( - <> - You haven't attached the JSON Schema for{" "} - - code {codeId} yet - - )} - - - {jsonSchema - ? `Please fill in ${prettyType} Message manually or change the schema` - : "Your attached JSON schema will be stored locally on your device"} - - - + )} - You are using a locally attached JSON Schema + {verifiedSchema + ? "The schema is available because the code is verified" + : "You are using a locally attached JSON Schema"} - + diff --git a/src/lib/components/json-schema/upload/UploadSchema.tsx b/src/lib/components/json-schema/upload/UploadSchema.tsx index a35b7eb51..9dd7a5834 100644 --- a/src/lib/components/json-schema/upload/UploadSchema.tsx +++ b/src/lib/components/json-schema/upload/UploadSchema.tsx @@ -3,8 +3,7 @@ import type { ReactNode } from "react"; import { AttachSchemaCard } from "../AttachSchemaCard"; import { JsonSchemaModal } from "../JsonSchemaModal"; -import type { CodeSchema } from "lib/stores/schema"; -import type { Option } from "lib/types"; +import type { CodeSchema, Option } from "lib/types"; interface UploadSchemaContentInterface { attached: boolean; diff --git a/src/lib/components/json-schema/upload/UploadSchemaSection.tsx b/src/lib/components/json-schema/upload/UploadSchemaSection.tsx index b4d6d9fda..af068c059 100644 --- a/src/lib/components/json-schema/upload/UploadSchemaSection.tsx +++ b/src/lib/components/json-schema/upload/UploadSchemaSection.tsx @@ -2,8 +2,7 @@ import { Flex, Text } from "@chakra-ui/react"; import { ConnectingLine } from "../../ConnectingLine"; import { CustomIcon } from "../../icon"; -import type { CodeSchema } from "lib/stores/schema"; -import type { Option } from "lib/types"; +import type { CodeSchema, Option } from "lib/types"; import { UploadSchema } from "./UploadSchema"; diff --git a/src/lib/components/json-schema/view/ViewSchemaModal.tsx b/src/lib/components/json-schema/view/ViewSchemaModal.tsx index d1953569c..de0cb918b 100644 --- a/src/lib/components/json-schema/view/ViewSchemaModal.tsx +++ b/src/lib/components/json-schema/view/ViewSchemaModal.tsx @@ -24,9 +24,8 @@ import { AppLink } from "lib/components/AppLink"; import { CustomTab } from "lib/components/CustomTab"; import { CustomIcon } from "lib/components/icon"; import { Tooltip } from "lib/components/Tooltip"; -import type { CodeSchema } from "lib/stores/schema"; -import { SchemaProperties } from "lib/stores/schema"; -import type { Option } from "lib/types"; +import { SchemaProperties } from "lib/types"; +import type { CodeSchema, Option } from "lib/types"; import { ViewSchemaPanel } from "./ViewSchemaPanel"; diff --git a/src/lib/components/modal/wasm-verify-status/WasmVerifyRequestInfo.tsx b/src/lib/components/modal/wasm-verify-status/WasmVerifyRequestInfo.tsx index ecbbc8289..06e92687a 100644 --- a/src/lib/components/modal/wasm-verify-status/WasmVerifyRequestInfo.tsx +++ b/src/lib/components/modal/wasm-verify-status/WasmVerifyRequestInfo.tsx @@ -33,6 +33,7 @@ export const WasmVerifyRequestInfo = ({ }: WasmVerifyRequestInfoProps) => { const wasmVerifyStatus = getWasmVerifyStatus({ verificationInfo, + schema: null, relatedVerifiedCodes, }); diff --git a/src/lib/components/upload/OptionButton.tsx b/src/lib/components/upload/OptionButton.tsx index 9f8f5d614..019af8869 100644 --- a/src/lib/components/upload/OptionButton.tsx +++ b/src/lib/components/upload/OptionButton.tsx @@ -28,3 +28,28 @@ export const OptionButton = ({ title, description }: OptionButtonProps) => ( ); + +export const OptionButtonDisabled = ({ + title, + description, +}: OptionButtonProps) => ( + + + + {title} + + + {description} + + + + +); diff --git a/src/lib/components/wasm-verify-section/FailedDetails.tsx b/src/lib/components/wasm-verify-section/FailedDetails.tsx index 5e5160fb4..5a4d2a496 100644 --- a/src/lib/components/wasm-verify-section/FailedDetails.tsx +++ b/src/lib/components/wasm-verify-section/FailedDetails.tsx @@ -72,6 +72,7 @@ export const FailedDetails = ({ codeHash={codeHash} wasmVerifyStatus={getWasmVerifyStatus({ verificationInfo, + schema: null, relatedVerifiedCodes, })} relatedVerifiedCodes={relatedVerifiedCodes} diff --git a/src/lib/pages/code-details/components/code-local-schema/index.tsx b/src/lib/pages/code-details/components/code-local-schema/index.tsx index e6ee3fceb..2738794a2 100644 --- a/src/lib/pages/code-details/components/code-local-schema/index.tsx +++ b/src/lib/pages/code-details/components/code-local-schema/index.tsx @@ -13,9 +13,8 @@ import { capitalize } from "lodash"; import { CustomTab } from "lib/components/CustomTab"; import { EditSchemaButtons, JsonSchemaModal } from "lib/components/json-schema"; -import type { CodeSchema } from "lib/stores/schema"; -import { SchemaProperties } from "lib/stores/schema"; -import type { Option } from "lib/types"; +import { SchemaProperties } from "lib/types"; +import type { CodeSchema, Option } from "lib/types"; import { SchemaPanel } from "./SchemaPanel"; diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 1cdaa388b..b7fe525e0 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -51,6 +51,7 @@ import { UserDocsLink } from "lib/components/UserDocsLink"; import { useTxBroadcast } from "lib/hooks"; import { useSchemaStore } from "lib/providers/store"; import type { Code } from "lib/services/types"; +import { useDerivedWasmVerifyInfo } from "lib/services/verification/wasm"; import { useCodeLcd } from "lib/services/wasm/code"; import type { BechAddr, BechAddr20, ComposedMsg } from "lib/types"; import { MsgType } from "lib/types"; @@ -100,7 +101,6 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { const getAttachFunds = useAttachFunds(); const { getSchemaByCodeHash } = useSchemaStore(); const { isFullTier } = useTierConfig(); - // ------------------------------------------// // ------------------STATES------------------// // ------------------------------------------// @@ -150,10 +150,20 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { }); const { assetsSelect, assetsJsonStr, attachFundsOption } = watchAssets(); + // ------------------------------------------// + // -------------------DATA-------------------// + // ------------------------------------------// + const { data: derivedWasmVerifyInfo } = useDerivedWasmVerifyInfo( + codeId.length ? Number(codeId) : undefined, + codeHash + ); + // ------------------------------------------// // ------------------LOGICS------------------// // ------------------------------------------// - const jsonSchema = getSchemaByCodeHash(codeHash); + const verifiedSchema = derivedWasmVerifyInfo?.schema; + const localSchema = getSchemaByCodeHash(codeHash); + const funds = getAttachFunds(attachFundsOption, assetsJsonStr, assetsSelect); const enableInstantiate = useMemo(() => { const generalChecks = @@ -378,10 +388,10 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { ]); useEffect(() => { - if (jsonSchema) { + if (localSchema) { setTab(MessageTabs.YOUR_SCHEMA); } - }, [jsonSchema, setValue]); + }, [localSchema, setValue]); useEffect(() => { if (router.isReady) trackToInstantiate(!!msgQuery, !!codeIdQuery); @@ -495,7 +505,8 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { type="instantiate" codeHash={codeHash} codeId={Number(codeId)} - jsonSchema={jsonSchema} + verifiedSchema={verifiedSchema} + localSchema={localSchema} initialFormData={JSON.parse(msgInput[yourSchemaInputFormKey])} handleChange={handleChange} onSchemaSave={resetMsgInputSchema} diff --git a/src/lib/pages/interact-contract/components/execute-area/index.tsx b/src/lib/pages/interact-contract/components/execute-area/index.tsx index acd9452a7..91d4b1779 100644 --- a/src/lib/pages/interact-contract/components/execute-area/index.tsx +++ b/src/lib/pages/interact-contract/components/execute-area/index.tsx @@ -1,6 +1,5 @@ import { Flex, TabList, Tabs } from "@chakra-ui/react"; import type { Coin } from "@cosmjs/stargate"; -import { observer } from "mobx-react-lite"; import { useCallback, useEffect, useState } from "react"; import { trackUseTab } from "lib/amplitude"; @@ -13,13 +12,14 @@ import { UploadSchemaSection, } from "lib/components/json-schema"; import { Tooltip } from "lib/components/Tooltip"; -import { useSchemaStore } from "lib/providers/store"; -import type { BechAddr32, Option } from "lib/types"; +import type { BechAddr32, CodeSchema, Nullish, Option } from "lib/types"; import { JsonExecute } from "./JsonExecute"; import { SchemaExecute } from "./schema-execute"; interface ExecuteAreaProps { + verifiedSchema: Nullish; + localSchema: Option; contractAddress: BechAddr32; initialMsg: string; initialFunds: Coin[]; @@ -27,108 +27,108 @@ interface ExecuteAreaProps { codeHash: Option; } -export const ExecuteArea = observer( - ({ - contractAddress, - initialMsg, - initialFunds, - codeHash, - codeId, - }: ExecuteAreaProps) => { - const [tab, setTab] = useState(MessageTabs.JSON_INPUT); +export const ExecuteArea = ({ + verifiedSchema, + localSchema, + contractAddress, + initialMsg, + initialFunds, + codeHash, + codeId, +}: ExecuteAreaProps) => { + const [tab, setTab] = useState(MessageTabs.JSON_INPUT); - const { getExecuteSchema, getSchemaByCodeHash } = useSchemaStore(); - const attached = Boolean(codeHash && getSchemaByCodeHash(codeHash)); - const schema = codeHash ? getExecuteSchema(codeHash) : undefined; + const schema = verifiedSchema ?? localSchema; + const attached = Boolean(codeHash && schema); - const handleTabChange = useCallback( - (nextTab: MessageTabs) => { - if (nextTab === tab) return; - trackUseTab(nextTab); - setTab(nextTab); - }, - [tab] - ); + const handleTabChange = useCallback( + (nextTab: MessageTabs) => { + if (nextTab === tab) return; + trackUseTab(nextTab); + setTab(nextTab); + }, + [tab] + ); - useEffect(() => { - if (!schema) setTab(MessageTabs.JSON_INPUT); - else setTab(MessageTabs.YOUR_SCHEMA); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [JSON.stringify(schema)]); + useEffect(() => { + if (!schema) setTab(MessageTabs.JSON_INPUT); + else setTab(MessageTabs.YOUR_SCHEMA); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [JSON.stringify(schema)]); - return ( - <> - - - - handleTabChange(MessageTabs.JSON_INPUT)}> - JSON Input - - handleTabChange(MessageTabs.YOUR_SCHEMA)} - isDisabled={!contractAddress} + return ( + <> + + + + handleTabChange(MessageTabs.JSON_INPUT)}> + JSON Input + + handleTabChange(MessageTabs.YOUR_SCHEMA)} + isDisabled={!contractAddress} + > + - - - - } - schemaContent={ - codeId && - codeHash && ( - <> - {attached ? ( - - ) : ( - - - You haven't attached the JSON Schema for - - code {codeId} - - - from which this contract is instantiated yet. - + Your Schema + + + + + + } + schemaContent={ + codeId && + codeHash && ( + <> + {attached ? ( + + ) : ( + + + You haven't attached the JSON Schema for + + code {codeId} - } - /> - )} - - ) - } - /> - - ); - } -); + + from which this contract is instantiated yet. + + + } + /> + )} + + ) + } + /> + + ); +}; diff --git a/src/lib/pages/interact-contract/components/execute-area/schema-execute/ExecuteBox.tsx b/src/lib/pages/interact-contract/components/execute-area/schema-execute/ExecuteBox.tsx index 3c0b85b72..e23e0c186 100644 --- a/src/lib/pages/interact-contract/components/execute-area/schema-execute/ExecuteBox.tsx +++ b/src/lib/pages/interact-contract/components/execute-area/schema-execute/ExecuteBox.tsx @@ -42,8 +42,12 @@ import { JsonSchemaForm } from "lib/components/json-schema"; import { useTxBroadcast } from "lib/hooks"; import { useContractStore } from "lib/providers/store"; import type { Activity } from "lib/stores/contract"; -import type { SchemaInfo } from "lib/stores/schema"; -import type { BechAddr32, ComposedMsg, JsonDataType } from "lib/types"; +import type { + BechAddr32, + ComposedMsg, + JsonDataType, + SchemaInfo, +} from "lib/types"; import { MsgType } from "lib/types"; import { composeMsg, diff --git a/src/lib/pages/interact-contract/components/execute-area/schema-execute/index.tsx b/src/lib/pages/interact-contract/components/execute-area/schema-execute/index.tsx index fb9ef4dfd..b9ffcda38 100644 --- a/src/lib/pages/interact-contract/components/execute-area/schema-execute/index.tsx +++ b/src/lib/pages/interact-contract/components/execute-area/schema-execute/index.tsx @@ -7,15 +7,14 @@ import { CustomIcon } from "lib/components/icon"; import InputWithIcon from "lib/components/InputWithIcon"; import { UploadSchema } from "lib/components/json-schema"; import { EmptyState, StateImage } from "lib/components/state"; -import { useSchemaStore } from "lib/providers/store"; -import type { ExecuteSchema } from "lib/stores/schema"; -import type { BechAddr32, Option } from "lib/types"; -import { jsonPrettify, resolveInitialMsg } from "lib/utils"; +import type { BechAddr32, CodeSchema, Nullish, Option } from "lib/types"; +import { getExecuteSchema, jsonPrettify, resolveInitialMsg } from "lib/utils"; import { ExecuteBox } from "./ExecuteBox"; interface SchemaExecuteProps { - schema: Option; + verifiedSchema: Nullish; + localSchema: Option; contractAddress: BechAddr32; initialMsg: string; initialFunds: Coin[]; @@ -24,8 +23,9 @@ interface SchemaExecuteProps { } export const SchemaExecute = ({ + verifiedSchema, + localSchema, contractAddress, - schema, initialMsg, initialFunds, codeId, @@ -35,8 +35,7 @@ export const SchemaExecute = ({ // -----------------REFERENCE----------------// // ------------------------------------------// const accordionRef = useRef(null); - const { getSchemaByCodeHash } = useSchemaStore(); - const fullSchema = getSchemaByCodeHash(codeHash); + // ------------------------------------------// // -------------------STATES-----------------// // ------------------------------------------// @@ -46,6 +45,7 @@ export const SchemaExecute = ({ // ------------------------------------------// // -------------------LOGICS-----------------// // ------------------------------------------// + const schema = getExecuteSchema(verifiedSchema ?? localSchema); const filteredMsgs = useMemo(() => { if (!keyword) return schema; @@ -91,23 +91,28 @@ export const SchemaExecute = ({ - Attached JSON Schema doesn’t have ExecuteMsg - - - Please fill in Execute Message manually or change the schema + {verifiedSchema ? "Verified" : "Attached"} JSON Schema doesn’t have + ExecuteMsg - + {!verifiedSchema && ( + <> + + Please fill in Execute Message manually or change the schema + + + + )} ); @@ -119,7 +124,7 @@ export const SchemaExecute = ({ placeholder="Search with Execute Message" value={keyword} onChange={(e) => setKeyword(e.target.value)} - size={{ base: "md", md: "lg" }} + size="md" amptrackSection="execute-message-search" /> diff --git a/src/lib/services/types/verification/wasm.ts b/src/lib/services/types/verification/wasm.ts index 89dedc69c..b347e1790 100644 --- a/src/lib/services/types/verification/wasm.ts +++ b/src/lib/services/types/verification/wasm.ts @@ -1,6 +1,6 @@ import { z } from "zod"; -import { zWasmVerifyInfo } from "lib/types"; +import { zRelatedWasmVerifyInfo, zWasmVerifyInfo } from "lib/types"; export interface WasmVerifyRequest { chainId: string; @@ -18,5 +18,5 @@ export const zWasmVerifyInfosResponse = z.record( export const zWasmRelatedVerifyInfosResponse = z.record( z.string(), - zWasmVerifyInfo.omit({ verificationInfo: true }) + zRelatedWasmVerifyInfo ); diff --git a/src/lib/stores/schema.test.ts b/src/lib/stores/schema.test.ts index 5d5ce167a..77658cf33 100644 --- a/src/lib/stores/schema.test.ts +++ b/src/lib/stores/schema.test.ts @@ -1,16 +1,14 @@ -import type { CodeSchema } from "./schema"; -import { SchemaProperties, SchemaStore } from "./schema"; -import executeSchemaOutput from "./schema-test-suite/execute-schema-output.json"; -import querySchemaOutput from "./schema-test-suite/query-schema-output.json"; -import schema from "./schema-test-suite/schema-example.json"; +import type { CodeSchema } from "lib/types"; +import { + exampleCodeHash, + exampleCodeId, + exampleSchema, +} from "lib/utils/_suites/verification/wasm/example"; +import schema from "lib/utils/_suites/verification/wasm/schema-example.json"; + +import { SchemaStore } from "./schema"; let schemaStore: SchemaStore; -const codeHash = "a1b2c3d4e5f6g7"; -const codeId = "1234"; -const exampleSchema = { - ...schema, - [SchemaProperties.ATTACHED_CODE_ID]: codeId, -} as unknown as CodeSchema; beforeAll(() => { schemaStore = new SchemaStore(); @@ -18,8 +16,8 @@ beforeAll(() => { beforeEach(() => { schemaStore.saveNewSchema( - codeHash, - codeId, + exampleCodeHash, + exampleCodeId, JSON.parse(JSON.stringify(schema)) as CodeSchema ); }); @@ -33,108 +31,25 @@ describe("SchemaStore initialization", () => { describe("saveNewSchema and deleteSchema", () => { test("correctly save new schema and delete schema by codeHash", () => { expect(schemaStore.jsonSchemas).toEqual({ - [codeHash]: exampleSchema, + [exampleCodeHash]: exampleSchema, }); - schemaStore.deleteSchema(codeHash); - expect(schemaStore.jsonSchemas[codeHash]).toBeUndefined(); + schemaStore.deleteSchema(exampleCodeHash); + expect(schemaStore.jsonSchemas[exampleCodeHash]).toBeUndefined(); }); }); describe("getSchemaByCodeHash", () => { test("correctly get schema by code hash", () => { - expect(schemaStore.getSchemaByCodeHash(codeHash)).toEqual(exampleSchema); - }); - test("correctly get schema by uppercase code hash", () => { - expect(schemaStore.getSchemaByCodeHash(codeHash.toUpperCase())).toEqual( + expect(schemaStore.getSchemaByCodeHash(exampleCodeHash)).toEqual( exampleSchema ); }); - test("return undefined on code hash not found", () => { - expect(schemaStore.getSchemaByCodeHash("randomHash")).toBeUndefined(); - }); -}); - -describe("getSchemaProperty", () => { - test("correctly retrieve schema property", () => { - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.CONTRACT_NAME) - ).toEqual(exampleSchema.contract_name); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.CONTRACT_VERSION) - ).toEqual(exampleSchema.contract_version); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.IDL_VERSION) - ).toEqual(exampleSchema.idl_version); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.INSTANTIATE) - ).toEqual(exampleSchema.instantiate); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.EXECUTE) - ).toEqual(exampleSchema.execute); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.QUERY) - ).toEqual(exampleSchema.query); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.MIGRATE) - ).toEqual(exampleSchema.migrate); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.SUDO) - ).toEqual(exampleSchema.sudo); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.RESPONSES) - ).toEqual(exampleSchema.responses); - expect( - schemaStore.getSchemaProperty(codeHash, SchemaProperties.ATTACHED_CODE_ID) - ).toEqual(codeId); - }); - - test("correctly retrieve schema property from uppercase code hash", () => { - expect( - schemaStore.getSchemaProperty( - codeHash.toUpperCase(), - SchemaProperties.CONTRACT_NAME - ) - ).toStrictEqual(exampleSchema.contract_name); - }); - - test("correctly return undefined on code hash not found", () => { + test("correctly get schema by uppercase code hash", () => { expect( - schemaStore.getSchemaProperty( - "randomHash", - SchemaProperties.CONTRACT_NAME - ) - ).toBeUndefined(); - }); -}); - -describe("getQuerySchemaFormArray", () => { - test("correctly get form array for query schema", () => { - expect(schemaStore.getQuerySchema(codeHash)).toEqual(querySchemaOutput); - expect(schemaStore.getQuerySchema(codeHash)).toEqual(querySchemaOutput); - }); - - test("correctly get form array for query schema from uppercase code hash", () => { - expect(schemaStore.getQuerySchema(codeHash.toUpperCase())).toEqual( - querySchemaOutput - ); + schemaStore.getSchemaByCodeHash(exampleCodeHash.toUpperCase()) + ).toEqual(exampleSchema); }); - - test("correctly return undefined for non-existent code hash", () => { - expect(schemaStore.getQuerySchema("randomHash")).toBeUndefined(); - }); -}); - -describe("getExecuteSchemaFormArray", () => { - test("correctly get form array for execute schema", () => { - expect(schemaStore.getExecuteSchema(codeHash)).toEqual(executeSchemaOutput); - expect(schemaStore.getExecuteSchema(codeHash)).toEqual(executeSchemaOutput); - }); - test("correctly get form array for execute schema from uppercase code hash", () => { - expect(schemaStore.getExecuteSchema(codeHash.toUpperCase())).toEqual( - executeSchemaOutput - ); - }); - test("correctly return undefined for non-existent code hash", () => { - expect(schemaStore.getExecuteSchema("randomHash")).toBeUndefined(); + test("return undefined on code hash not found", () => { + expect(schemaStore.getSchemaByCodeHash("randomHash")).toBeUndefined(); }); }); diff --git a/src/lib/stores/schema.ts b/src/lib/stores/schema.ts index 1dd7cbc4d..54957781d 100644 --- a/src/lib/stores/schema.ts +++ b/src/lib/stores/schema.ts @@ -1,45 +1,8 @@ -import type { RJSFSchema as JsonSchema } from "@rjsf/utils"; import { makeAutoObservable } from "mobx"; import { makePersistable } from "mobx-persist-store"; -import type { Dict, Nullable, Option } from "lib/types"; - -export enum SchemaProperties { - CONTRACT_NAME = "contract_name", - CONTRACT_VERSION = "contract_version", - IDL_VERSION = "idl_version", - INSTANTIATE = "instantiate", - EXECUTE = "execute", - QUERY = "query", - MIGRATE = "migrate", - SUDO = "sudo", - RESPONSES = "responses", - ATTACHED_CODE_ID = "attached_code_id", -} - -export interface SchemaInfo { - title: Option; - description: Option; - schema: JsonSchema; - inputRequired?: boolean; -} - -export interface CodeSchema { - [SchemaProperties.CONTRACT_NAME]: string; - [SchemaProperties.CONTRACT_VERSION]: string; - [SchemaProperties.IDL_VERSION]: string; - [SchemaProperties.INSTANTIATE]: JsonSchema; - [SchemaProperties.EXECUTE]: Nullable; - [SchemaProperties.QUERY]: Nullable; - [SchemaProperties.MIGRATE]: Nullable; - [SchemaProperties.SUDO]: Nullable; - [SchemaProperties.RESPONSES]: { [key: string]: JsonSchema }; - [SchemaProperties.ATTACHED_CODE_ID]: string; -} - -export type QuerySchema = Array<[SchemaInfo, SchemaInfo]>; - -export type ExecuteSchema = Array; +import type { CodeSchema, Dict, Option } from "lib/types"; +import { SchemaProperties } from "lib/types"; const normalize = (codeHash: string) => { return codeHash.toLowerCase(); @@ -85,131 +48,6 @@ export class SchemaStore { return this.jsonSchemas[normalize(codeHash)]; } - getSchemaProperty(codeHash: string, property: T) { - return this.jsonSchemas[normalize(codeHash)]?.[property]; - } - - getQuerySchema(codeHash: string): Option { - const querySchema = this.getSchemaProperty( - normalize(codeHash), - SchemaProperties.QUERY - ); - - const responsesSchema = this.getSchemaProperty( - normalize(codeHash), - SchemaProperties.RESPONSES - ); - - if (!querySchema || !responsesSchema) return undefined; - - const getResponseSchema = (responseSchema: JsonSchema): SchemaInfo => { - const { title, description, ...resSchema } = responseSchema; - return { - title, - description, - schema: { - ...resSchema, - readOnly: true, - }, - }; - }; - - return querySchema.oneOf?.reduce>( - (acc, msg) => { - const eachQuerySchema = msg as JsonSchema; - const { type, enum: enumOptions, required } = eachQuerySchema; - if (type === "string" && enumOptions) { - return [ - ...acc, - ...enumOptions.map<[SchemaInfo, SchemaInfo]>((enumOption) => [ - { - title: enumOption as string, - description: eachQuerySchema.description, - schema: { - $schema: querySchema.$schema, - type, - enum: [enumOption], - }, - inputRequired: false, - }, - getResponseSchema(responsesSchema[enumOption as string]), - ]), - ]; - } - if (required) { - const { description, ...msgSchema } = eachQuerySchema; - - const title = required[0]; - const propertyKey = eachQuerySchema.properties?.[title] as JsonSchema; - const noInputRequired = - propertyKey.type === "object" && !("properties" in propertyKey); - - return [ - ...acc, - [ - { - title, - description, - schema: { - ...msgSchema, - $schema: querySchema.$schema, - definitions: querySchema.definitions, - }, - inputRequired: !noInputRequired, - }, - getResponseSchema(responsesSchema[required[0]]), - ], - ]; - } - - return acc; - }, - [] - ); - } - - getExecuteSchema(codeHash: string): Option { - const executeSchema = this.getSchemaProperty( - normalize(codeHash), - SchemaProperties.EXECUTE - ); - - if (!executeSchema) return undefined; - - return executeSchema.oneOf?.reduce>((acc, msg) => { - const eachExecuteSchema = msg as JsonSchema; - const { type, required, enum: enumOptions } = eachExecuteSchema; - const { description, ...msgSchema } = eachExecuteSchema; - - if (type === "string" && enumOptions) { - return [ - ...acc, - ...enumOptions.map((enumOption) => ({ - title: enumOption as string, - description: eachExecuteSchema.description, - schema: { - $schema: eachExecuteSchema.$schema, - type, - enum: [enumOption], - }, - })), - ]; - } - return [ - ...acc, - { - title: required?.[0], - description, - schema: { - ...msgSchema, - $schema: executeSchema.$schema, - definitions: executeSchema.definitions, - }, - }, - ]; - }, []); - } - // TODO: add test getSchemaCount(): number { return Object.keys(this.jsonSchemas).length; diff --git a/src/lib/types/verification.ts b/src/lib/types/verification.ts index 1154987c3..b489b6eda 100644 --- a/src/lib/types/verification.ts +++ b/src/lib/types/verification.ts @@ -1,7 +1,53 @@ +import type { RJSFSchema as JsonSchema } from "@rjsf/utils"; import { z } from "zod"; +import type { Nullable, Option } from "./common"; import { zUtcDate } from "./time"; +// ------------------------------------------// +// ------------------SCHEMA------------------// +// ------------------------------------------// + +export enum SchemaProperties { + CONTRACT_NAME = "contract_name", + CONTRACT_VERSION = "contract_version", + IDL_VERSION = "idl_version", + INSTANTIATE = "instantiate", + EXECUTE = "execute", + QUERY = "query", + MIGRATE = "migrate", + SUDO = "sudo", + RESPONSES = "responses", + ATTACHED_CODE_ID = "attached_code_id", +} + +export interface SchemaInfo { + title: Option; + description: Option; + schema: JsonSchema; + inputRequired?: boolean; +} + +export interface CodeSchema { + [SchemaProperties.CONTRACT_NAME]: string; + [SchemaProperties.CONTRACT_VERSION]: string; + [SchemaProperties.IDL_VERSION]: string; + [SchemaProperties.INSTANTIATE]: JsonSchema; + [SchemaProperties.EXECUTE]: Nullable; + [SchemaProperties.QUERY]: Nullable; + [SchemaProperties.MIGRATE]: Nullable; + [SchemaProperties.SUDO]: Nullable; + [SchemaProperties.RESPONSES]: { [key: string]: JsonSchema }; + [SchemaProperties.ATTACHED_CODE_ID]: string; +} + +export type QuerySchema = Array<[SchemaInfo, SchemaInfo]>; +export type ExecuteSchema = Array; + +// ------------------------------------------// +// ---------------VERIFICATION---------------// +// ------------------------------------------// + export enum WasmVerifyStatus { NOT_VERIFIED, IN_PROGRESS, @@ -25,9 +71,25 @@ const zWasmVerifyInfoBase = z.object({ }); export type WasmVerifyInfoBase = z.infer; -export const zWasmVerifyInfo = z.object({ - verificationInfo: zWasmVerifyInfoBase.nullable(), - schema: z.unknown().nullable(), - relatedVerifiedCodes: z.number().array(), -}); +export const zWasmVerifyInfo = z + .object({ + verificationInfo: zWasmVerifyInfoBase.nullable(), + schema: z.unknown().nullable(), + relatedVerifiedCodes: z.number().array(), + }) + .transform(({ verificationInfo, schema, relatedVerifiedCodes }) => ({ + verificationInfo, + schema: schema !== null ? (schema as CodeSchema) : null, + relatedVerifiedCodes, + })); export type WasmVerifyInfo = z.infer; + +export const zRelatedWasmVerifyInfo = z + .object({ + schema: z.unknown().nullable(), + relatedVerifiedCodes: z.number().array(), + }) + .transform(({ schema, relatedVerifiedCodes }) => ({ + schema: schema !== null ? (schema as CodeSchema) : null, + relatedVerifiedCodes, + })); diff --git a/src/lib/utils/_suites/verification/wasm/example.ts b/src/lib/utils/_suites/verification/wasm/example.ts new file mode 100644 index 000000000..913f62794 --- /dev/null +++ b/src/lib/utils/_suites/verification/wasm/example.ts @@ -0,0 +1,11 @@ +import type { CodeSchema } from "lib/types"; +import { SchemaProperties } from "lib/types"; + +import schema from "./schema-example.json"; + +export const exampleCodeHash = "a1b2c3d4e5f6g7"; +export const exampleCodeId = "1234"; +export const exampleSchema = { + ...schema, + [SchemaProperties.ATTACHED_CODE_ID]: exampleCodeId, +} as unknown as CodeSchema; diff --git a/src/lib/stores/schema-test-suite/execute-schema-output.json b/src/lib/utils/_suites/verification/wasm/execute-schema-output.json similarity index 100% rename from src/lib/stores/schema-test-suite/execute-schema-output.json rename to src/lib/utils/_suites/verification/wasm/execute-schema-output.json diff --git a/src/lib/stores/schema-test-suite/query-schema-output.json b/src/lib/utils/_suites/verification/wasm/query-schema-output.json similarity index 100% rename from src/lib/stores/schema-test-suite/query-schema-output.json rename to src/lib/utils/_suites/verification/wasm/query-schema-output.json diff --git a/src/lib/stores/schema-test-suite/schema-example.json b/src/lib/utils/_suites/verification/wasm/schema-example.json similarity index 100% rename from src/lib/stores/schema-test-suite/schema-example.json rename to src/lib/utils/_suites/verification/wasm/schema-example.json diff --git a/src/lib/utils/json.ts b/src/lib/utils/json.ts index 89fe79233..e2db9b222 100644 --- a/src/lib/utils/json.ts +++ b/src/lib/utils/json.ts @@ -1,8 +1,7 @@ import { getSchemaType } from "@rjsf/utils"; import type { RJSFSchema } from "@rjsf/utils"; -import type { SchemaInfo } from "lib/stores/schema"; -import type { JsonDataType } from "lib/types"; +import type { JsonDataType, SchemaInfo } from "lib/types"; export const jsonValidate = (text: string) => { try { diff --git a/src/lib/utils/verification.ts b/src/lib/utils/verification.ts deleted file mode 100644 index ad164514a..000000000 --- a/src/lib/utils/verification.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { WasmVerifyStatus } from "lib/types"; -import type { Nullish, WasmVerifyInfo } from "lib/types"; - -export const getWasmVerifyStatus = ( - wasmVerifyInfo: Nullish -) => { - if (!wasmVerifyInfo) return WasmVerifyStatus.NOT_VERIFIED; - - if (wasmVerifyInfo.verificationInfo === null) { - if (wasmVerifyInfo.relatedVerifiedCodes.length === 0) - return WasmVerifyStatus.NOT_VERIFIED; - - return WasmVerifyStatus.INDIRECTLY_VERIFIED; - } - - if (wasmVerifyInfo.verificationInfo.errorMessage) - return WasmVerifyStatus.FAILED; - - if (wasmVerifyInfo.verificationInfo.comparedTimestamp === null) - return WasmVerifyStatus.IN_PROGRESS; - - return WasmVerifyStatus.VERIFIED; -}; - -export const formatRelatedVerifiedCodes = (relatedVerifiedCodes: number[]) => { - const displayedCodes = relatedVerifiedCodes.slice(0, 3); - - let res = ""; - displayedCodes.forEach((code, index) => { - res += code.toString(); - if (relatedVerifiedCodes.length > 2 && index < displayedCodes.length - 1) - res += ","; - if (index < displayedCodes.length - 1) res += " "; - if ( - index === relatedVerifiedCodes.length - 2 && - index < displayedCodes.length - 1 - ) - res += "and "; - }); - if (relatedVerifiedCodes.length > 3) res += " and more"; - - return res; -}; diff --git a/src/lib/utils/verification/index.ts b/src/lib/utils/verification/index.ts new file mode 100644 index 000000000..e4638e151 --- /dev/null +++ b/src/lib/utils/verification/index.ts @@ -0,0 +1 @@ +export * from "./wasm"; diff --git a/src/lib/utils/verification/wasm.test.ts b/src/lib/utils/verification/wasm.test.ts new file mode 100644 index 000000000..8500bf37e --- /dev/null +++ b/src/lib/utils/verification/wasm.test.ts @@ -0,0 +1,87 @@ +import { + exampleCodeId, + exampleSchema, +} from "../_suites/verification/wasm/example"; +import type { CodeSchema } from "lib/types"; +import { SchemaProperties } from "lib/types"; +import executeSchemaOutput from "lib/utils/_suites/verification/wasm/execute-schema-output.json"; +import querySchemaOutput from "lib/utils/_suites/verification/wasm/query-schema-output.json"; + +import { getExecuteSchema, getQuerySchema, getSchemaProperty } from "./wasm"; + +const randomSchema = {} as CodeSchema; + +describe("getSchemaProperty", () => { + test("correctly retrieve schema property", () => { + expect( + getSchemaProperty(exampleSchema, SchemaProperties.CONTRACT_NAME) + ).toEqual(exampleSchema.contract_name); + expect( + getSchemaProperty(exampleSchema, SchemaProperties.CONTRACT_VERSION) + ).toEqual(exampleSchema.contract_version); + expect( + getSchemaProperty(exampleSchema, SchemaProperties.IDL_VERSION) + ).toEqual(exampleSchema.idl_version); + expect( + getSchemaProperty(exampleSchema, SchemaProperties.INSTANTIATE) + ).toEqual(exampleSchema.instantiate); + expect(getSchemaProperty(exampleSchema, SchemaProperties.EXECUTE)).toEqual( + exampleSchema.execute + ); + expect(getSchemaProperty(exampleSchema, SchemaProperties.QUERY)).toEqual( + exampleSchema.query + ); + expect(getSchemaProperty(exampleSchema, SchemaProperties.MIGRATE)).toEqual( + exampleSchema.migrate + ); + expect(getSchemaProperty(exampleSchema, SchemaProperties.SUDO)).toEqual( + exampleSchema.sudo + ); + expect( + getSchemaProperty(exampleSchema, SchemaProperties.RESPONSES) + ).toEqual(exampleSchema.responses); + expect( + getSchemaProperty(exampleSchema, SchemaProperties.ATTACHED_CODE_ID) + ).toEqual(exampleCodeId); + }); + + test("correctly retrieve schema property from uppercase code hash", () => { + expect( + getSchemaProperty(exampleSchema, SchemaProperties.CONTRACT_NAME) + ).toStrictEqual(exampleSchema.contract_name); + }); + + test("correctly return undefined on code hash not found", () => { + expect( + getSchemaProperty(randomSchema, SchemaProperties.CONTRACT_NAME) + ).toBeUndefined(); + }); +}); + +describe("getQuerySchemaFormArray", () => { + test("correctly get form array for query schema", () => { + expect(getQuerySchema(exampleSchema)).toEqual(querySchemaOutput); + expect(getQuerySchema(exampleSchema)).toEqual(querySchemaOutput); + }); + + test("correctly get form array for query schema from uppercase code hash", () => { + expect(getQuerySchema(exampleSchema)).toEqual(querySchemaOutput); + }); + + test("correctly return undefined for non-existent code hash", () => { + expect(getQuerySchema(randomSchema)).toBeUndefined(); + }); +}); + +describe("getExecuteSchemaFormArray", () => { + test("correctly get form array for execute schema", () => { + expect(getExecuteSchema(exampleSchema)).toEqual(executeSchemaOutput); + expect(getExecuteSchema(exampleSchema)).toEqual(executeSchemaOutput); + }); + test("correctly get form array for execute schema from uppercase code hash", () => { + expect(getExecuteSchema(exampleSchema)).toEqual(executeSchemaOutput); + }); + test("correctly return undefined for non-existent code hash", () => { + expect(getExecuteSchema(randomSchema)).toBeUndefined(); + }); +}); diff --git a/src/lib/utils/verification/wasm.ts b/src/lib/utils/verification/wasm.ts new file mode 100644 index 000000000..3585bf737 --- /dev/null +++ b/src/lib/utils/verification/wasm.ts @@ -0,0 +1,183 @@ +import type { RJSFSchema as JsonSchema } from "@rjsf/utils"; + +import { SchemaProperties, WasmVerifyStatus } from "lib/types"; +import type { + CodeSchema, + ExecuteSchema, + Nullish, + Option, + QuerySchema, + SchemaInfo, + WasmVerifyInfo, +} from "lib/types"; + +// ------------------------------------------// +// ------------------SCHEMA------------------// +// ------------------------------------------// + +const getResponseSchema = (responseSchema: JsonSchema): SchemaInfo => { + const { title, description, ...resSchema } = responseSchema; + return { + title, + description, + schema: { + ...resSchema, + readOnly: true, + }, + }; +}; + +export const getSchemaProperty = ( + schema: Nullish, + property: T +) => { + return schema?.[property]; +}; + +export const getQuerySchema = ( + schema: Nullish +): Option => { + const querySchema = getSchemaProperty(schema, SchemaProperties.QUERY); + const responsesSchema = getSchemaProperty(schema, SchemaProperties.RESPONSES); + + if (!querySchema || !responsesSchema) return undefined; + + return querySchema.oneOf?.reduce>( + (acc, msg) => { + const eachQuerySchema = msg as JsonSchema; + const { type, enum: enumOptions, required } = eachQuerySchema; + if (type === "string" && enumOptions) { + return [ + ...acc, + ...enumOptions.map<[SchemaInfo, SchemaInfo]>((enumOption) => [ + { + title: enumOption as string, + description: eachQuerySchema.description, + schema: { + $schema: querySchema.$schema, + type, + enum: [enumOption], + }, + inputRequired: false, + }, + getResponseSchema(responsesSchema[enumOption as string]), + ]), + ]; + } + if (required) { + const { description, ...msgSchema } = eachQuerySchema; + + const title = required[0]; + const propertyKey = eachQuerySchema.properties?.[title] as JsonSchema; + const noInputRequired = + propertyKey.type === "object" && !("properties" in propertyKey); + + return [ + ...acc, + [ + { + title, + description, + schema: { + ...msgSchema, + $schema: querySchema.$schema, + definitions: querySchema.definitions, + }, + inputRequired: !noInputRequired, + }, + getResponseSchema(responsesSchema[required[0]]), + ], + ]; + } + + return acc; + }, + [] + ); +}; + +export const getExecuteSchema = ( + schema: Nullish +): Option => { + const executeSchema = getSchemaProperty(schema, SchemaProperties.EXECUTE); + + if (!executeSchema) return undefined; + + return executeSchema.oneOf?.reduce>((acc, msg) => { + const eachExecuteSchema = msg as JsonSchema; + const { type, required, enum: enumOptions } = eachExecuteSchema; + const { description, ...msgSchema } = eachExecuteSchema; + + if (type === "string" && enumOptions) { + return [ + ...acc, + ...enumOptions.map((enumOption) => ({ + title: enumOption as string, + description: eachExecuteSchema.description, + schema: { + $schema: eachExecuteSchema.$schema, + type, + enum: [enumOption], + }, + })), + ]; + } + return [ + ...acc, + { + title: required?.[0], + description, + schema: { + ...msgSchema, + $schema: executeSchema.$schema, + definitions: executeSchema.definitions, + }, + }, + ]; + }, []); +}; + +// ------------------------------------------// +// ---------------VERIFICATION---------------// +// ------------------------------------------// + +export const getWasmVerifyStatus = ( + wasmVerifyInfo: Nullish +) => { + if (!wasmVerifyInfo) return WasmVerifyStatus.NOT_VERIFIED; + + if (wasmVerifyInfo.verificationInfo === null) { + if (wasmVerifyInfo.relatedVerifiedCodes.length === 0) + return WasmVerifyStatus.NOT_VERIFIED; + + return WasmVerifyStatus.INDIRECTLY_VERIFIED; + } + + if (wasmVerifyInfo.verificationInfo.errorMessage) + return WasmVerifyStatus.FAILED; + + if (wasmVerifyInfo.verificationInfo.comparedTimestamp === null) + return WasmVerifyStatus.IN_PROGRESS; + + return WasmVerifyStatus.VERIFIED; +}; + +export const formatRelatedVerifiedCodes = (relatedVerifiedCodes: number[]) => { + const displayedCodes = relatedVerifiedCodes.slice(0, 3); + + let res = ""; + displayedCodes.forEach((code, index) => { + res += code.toString(); + if (relatedVerifiedCodes.length > 2 && index < displayedCodes.length - 1) + res += ","; + if (index < displayedCodes.length - 1) res += " "; + if ( + index === relatedVerifiedCodes.length - 2 && + index < displayedCodes.length - 1 + ) + res += "and "; + }); + if (relatedVerifiedCodes.length > 3) res += " and more"; + + return res; +}; From fd71d20b64e5f07382f335d12def23d12dc03069 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 7 Aug 2024 19:14:24 +0700 Subject: [PATCH 06/27] fix: verify text --- .../wasm-verify-section/IndirectlyVerifiedDetails.tsx | 2 +- .../wasm-verify-section/NotVerifiedDetails.tsx | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/lib/components/wasm-verify-section/IndirectlyVerifiedDetails.tsx b/src/lib/components/wasm-verify-section/IndirectlyVerifiedDetails.tsx index 30bf71cd8..2351196a4 100644 --- a/src/lib/components/wasm-verify-section/IndirectlyVerifiedDetails.tsx +++ b/src/lib/components/wasm-verify-section/IndirectlyVerifiedDetails.tsx @@ -61,13 +61,13 @@ export const IndirectlyVerifiedDetails = ({ } + showCopyOnHover />{" "} which has the same code hash with other verified codes. diff --git a/src/lib/components/wasm-verify-section/NotVerifiedDetails.tsx b/src/lib/components/wasm-verify-section/NotVerifiedDetails.tsx index 0c6cdf16b..50edd649c 100644 --- a/src/lib/components/wasm-verify-section/NotVerifiedDetails.tsx +++ b/src/lib/components/wasm-verify-section/NotVerifiedDetails.tsx @@ -1,5 +1,6 @@ import { Text } from "@chakra-ui/react"; +import { ExplorerLink } from "../ExplorerLink"; import { useMobile } from "lib/app-provider"; import { WasmVerifySubmitModal } from "lib/components/modal"; import type { BechAddr32 } from "lib/types"; @@ -25,9 +26,11 @@ export const NotVerifiedDetails = ({ {contractAddress ? ( <> This contract is an instance of code ID{" "} - - {codeId} - {" "} + {" "} which has not been verified. ) : ( From b533e56341fcf620827c5656ecb9b012076883e0 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 8 Aug 2024 15:00:05 +0700 Subject: [PATCH 07/27] feat: handle verified schema on details pages --- src/lib/components/ContractSelectSection.tsx | 10 +- .../json-schema/AttachSchemaCard.tsx | 6 +- .../section/SchemaInputNotExist.tsx | 2 +- .../section/SchemaInputSection.tsx | 2 +- .../json-schema/upload/UploadSchema.tsx | 6 +- .../upload/UploadSchemaSection.tsx | 5 +- .../json-schema/view/ViewSchemaModal.tsx | 8 +- src/lib/components/table/codes/CodesTable.tsx | 8 +- .../code-local-schema/SchemaPanel.tsx | 21 -- .../components/code-local-schema/index.tsx | 117 ---------- .../code-schema-section/CodeSchemaTabs.tsx | 79 +++++++ .../code-schema-section/SchemaPanel.tsx | 45 ++++ .../components/code-schema-section/index.tsx | 80 +++++++ src/lib/pages/code-details/index.tsx | 19 +- .../components/CommandSection.tsx | 201 ------------------ .../ContractVerificationSection.tsx | 4 +- .../command-section/CommandSectionHeader.tsx | 105 +++++++++ .../command-section/ContractCmdGroup.tsx | 63 ++++++ .../components/command-section/index.tsx | 73 +++++++ src/lib/pages/contract-details/index.tsx | 15 +- .../execute-area/schema-execute/index.tsx | 2 +- .../query-area/schema-query/index.tsx | 2 +- src/lib/pages/upload/completed.tsx | 8 +- src/lib/services/verification/wasm/index.ts | 34 ++- 24 files changed, 506 insertions(+), 409 deletions(-) delete mode 100644 src/lib/pages/code-details/components/code-local-schema/SchemaPanel.tsx delete mode 100644 src/lib/pages/code-details/components/code-local-schema/index.tsx create mode 100644 src/lib/pages/code-details/components/code-schema-section/CodeSchemaTabs.tsx create mode 100644 src/lib/pages/code-details/components/code-schema-section/SchemaPanel.tsx create mode 100644 src/lib/pages/code-details/components/code-schema-section/index.tsx delete mode 100644 src/lib/pages/contract-details/components/CommandSection.tsx create mode 100644 src/lib/pages/contract-details/components/command-section/CommandSectionHeader.tsx create mode 100644 src/lib/pages/contract-details/components/command-section/ContractCmdGroup.tsx create mode 100644 src/lib/pages/contract-details/components/command-section/index.tsx diff --git a/src/lib/components/ContractSelectSection.tsx b/src/lib/components/ContractSelectSection.tsx index e061681f5..f7525b5cb 100644 --- a/src/lib/components/ContractSelectSection.tsx +++ b/src/lib/components/ContractSelectSection.tsx @@ -178,10 +178,10 @@ export const ContractSelectSection = observer( onError: () => reset(defaultValues), }); - const { data: derivedWasmVerifyInfo } = useDerivedWasmVerifyInfo( - codeId, - codeHash - ); + const { + data: derivedWasmVerifyInfo, + isLoading: isDerivedWasmVerifyInfoLoading, + } = useDerivedWasmVerifyInfo(codeId, codeHash); useEffect(() => { if (!contractLocalInfo) { @@ -201,7 +201,7 @@ export const ContractSelectSection = observer( return ( <> - {isFetching && } + {(isFetching || isDerivedWasmVerifyInfoLoading) && } ; + localSchema: Option; openModal: () => void; } @@ -20,7 +20,7 @@ export const AttachSchemaCard = ({ attached, codeId, codeHash, - schema, + localSchema, openModal, }: AttachSchemaCardProps) => { const handleAttach = useCallback(() => { @@ -63,7 +63,7 @@ export const AttachSchemaCard = ({ JSON Schema attached - + diff --git a/src/lib/components/json-schema/section/SchemaInputNotExist.tsx b/src/lib/components/json-schema/section/SchemaInputNotExist.tsx index 5fd401f43..8d2d8168b 100644 --- a/src/lib/components/json-schema/section/SchemaInputNotExist.tsx +++ b/src/lib/components/json-schema/section/SchemaInputNotExist.tsx @@ -54,7 +54,7 @@ export const SchemaInputNotExist = ({ - + diff --git a/src/lib/components/json-schema/upload/UploadSchema.tsx b/src/lib/components/json-schema/upload/UploadSchema.tsx index 9dd7a5834..a82721eb0 100644 --- a/src/lib/components/json-schema/upload/UploadSchema.tsx +++ b/src/lib/components/json-schema/upload/UploadSchema.tsx @@ -7,7 +7,7 @@ import type { CodeSchema, Option } from "lib/types"; interface UploadSchemaContentInterface { attached: boolean; - schema: Option; + localSchema: Option; codeId: number; codeHash: string; triggerElement?: ReactNode; @@ -15,7 +15,7 @@ interface UploadSchemaContentInterface { export const UploadSchema = ({ attached, - schema, + localSchema, codeId, codeHash, triggerElement, @@ -37,7 +37,7 @@ export const UploadSchema = ({ attached={attached} codeId={codeId} codeHash={codeHash} - schema={schema} + localSchema={localSchema} openModal={onOpen} /> )} diff --git a/src/lib/components/json-schema/upload/UploadSchemaSection.tsx b/src/lib/components/json-schema/upload/UploadSchemaSection.tsx index af068c059..df83a5e7a 100644 --- a/src/lib/components/json-schema/upload/UploadSchemaSection.tsx +++ b/src/lib/components/json-schema/upload/UploadSchemaSection.tsx @@ -2,19 +2,16 @@ import { Flex, Text } from "@chakra-ui/react"; import { ConnectingLine } from "../../ConnectingLine"; import { CustomIcon } from "../../icon"; -import type { CodeSchema, Option } from "lib/types"; import { UploadSchema } from "./UploadSchema"; interface UploadSchemaSectionProps { - schema?: Option; codeId: number; codeHash: string; title?: string | JSX.Element; } export const UploadSchemaSection = ({ - schema, codeId, codeHash, title = `You haven't attached the JSON Schema for code ${codeId} yet`, @@ -65,7 +62,7 @@ export const UploadSchemaSection = ({ /> diff --git a/src/lib/components/json-schema/view/ViewSchemaModal.tsx b/src/lib/components/json-schema/view/ViewSchemaModal.tsx index de0cb918b..3eb609465 100644 --- a/src/lib/components/json-schema/view/ViewSchemaModal.tsx +++ b/src/lib/components/json-schema/view/ViewSchemaModal.tsx @@ -45,7 +45,7 @@ const StyledTabPanel = chakra(TabPanel, { interface ViewSchemaModalProps { codeId: number; - jsonSchema: Option; + localSchema: Option; isIcon?: boolean; } @@ -60,7 +60,7 @@ const ALL_TABS = ["full schema", ...SchemaMsgTabList]; export const ViewSchemaModal = ({ codeId, - jsonSchema, + localSchema, isIcon = false, }: ViewSchemaModalProps) => { const { isOpen, onClose, onOpen } = useDisclosure(); @@ -138,12 +138,12 @@ export const ViewSchemaModal = ({ - + {SchemaMsgTabList.map((schemaProperty) => ( diff --git a/src/lib/components/table/codes/CodesTable.tsx b/src/lib/components/table/codes/CodesTable.tsx index b6dd5b4a5..22446eebc 100644 --- a/src/lib/components/table/codes/CodesTable.tsx +++ b/src/lib/components/table/codes/CodesTable.tsx @@ -27,12 +27,10 @@ export const CodesTable = ({ showCw2andContracts = true, }: CodesTableProps) => { const isMobile = useMobile(); - const { data: wasmVerifyInfos } = useWasmVerifyInfos( - codes?.map((code) => code.id) ?? [], - !!codes - ); + const { data: wasmVerifyInfos, isLoading: isWasmVerifyInfosLoading } = + useWasmVerifyInfos(codes?.map((code) => code.id) ?? [], !!codes); - if (isLoading) return ; + if (isLoading || isWasmVerifyInfosLoading) return ; if (!codes) return ; if (!codes.length) return emptyState; diff --git a/src/lib/pages/code-details/components/code-local-schema/SchemaPanel.tsx b/src/lib/pages/code-details/components/code-local-schema/SchemaPanel.tsx deleted file mode 100644 index ef83fa331..000000000 --- a/src/lib/pages/code-details/components/code-local-schema/SchemaPanel.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import JsonReadOnly from "lib/components/json/JsonReadOnly"; -import { UploadSchemaSection } from "lib/components/json-schema"; -import type { Nullable, Option } from "lib/types"; -import { jsonPrettify } from "lib/utils"; - -interface SchemaPanelProps { - codeId: number; - codeHash: string; - schema: Option>; -} - -export const SchemaPanel = ({ codeId, codeHash, schema }: SchemaPanelProps) => - schema === undefined ? ( - - ) : ( - - ); diff --git a/src/lib/pages/code-details/components/code-local-schema/index.tsx b/src/lib/pages/code-details/components/code-local-schema/index.tsx deleted file mode 100644 index 2738794a2..000000000 --- a/src/lib/pages/code-details/components/code-local-schema/index.tsx +++ /dev/null @@ -1,117 +0,0 @@ -import { - chakra, - Flex, - Heading, - TabList, - TabPanel, - TabPanels, - Tabs, - Text, - useDisclosure, -} from "@chakra-ui/react"; -import { capitalize } from "lodash"; - -import { CustomTab } from "lib/components/CustomTab"; -import { EditSchemaButtons, JsonSchemaModal } from "lib/components/json-schema"; -import { SchemaProperties } from "lib/types"; -import type { CodeSchema, Option } from "lib/types"; - -import { SchemaPanel } from "./SchemaPanel"; - -const StyledCustomTab = chakra(CustomTab, { - baseStyle: { - border: "unset", - borderRadius: "4px", - _selected: { bgColor: "gray.800" }, - }, -}); - -const StyledTabPanel = chakra(TabPanel, { - baseStyle: { - p: 0, - }, -}); - -interface CodeLocalSchemaSectionProps { - codeId: number; - codeHash: string; - jsonSchema: Option; -} - -const SchemaMsgTabList = [ - SchemaProperties.INSTANTIATE as "instantiate", - SchemaProperties.EXECUTE as "execute", - SchemaProperties.QUERY as "query", - SchemaProperties.MIGRATE as "migrate", -]; - -export const CodeLocalSchemaSection = ({ - codeId, - codeHash, - jsonSchema, -}: CodeLocalSchemaSectionProps) => { - const { isOpen, onClose, onOpen } = useDisclosure(); - - return ( - <> - - - JSON Schema - - {Boolean(jsonSchema) && ( - - )} - - - Uploaded JSON schemas are stored locally on your device. - - - - Full Schema - {SchemaMsgTabList.map((schemaProperty) => ( - - {capitalize(schemaProperty)}Msg - - ))} - - - - - - {SchemaMsgTabList.map((schemaProperty) => ( - - - - ))} - - - - - ); -}; diff --git a/src/lib/pages/code-details/components/code-schema-section/CodeSchemaTabs.tsx b/src/lib/pages/code-details/components/code-schema-section/CodeSchemaTabs.tsx new file mode 100644 index 000000000..e414b80bd --- /dev/null +++ b/src/lib/pages/code-details/components/code-schema-section/CodeSchemaTabs.tsx @@ -0,0 +1,79 @@ +import { chakra, TabList, TabPanel, TabPanels, Tabs } from "@chakra-ui/react"; +import { capitalize } from "lodash"; + +import { CustomTab } from "lib/components/CustomTab"; +import type { CodeSchema, Nullish, Option } from "lib/types"; +import { SchemaProperties } from "lib/types"; + +import { SchemaPanel } from "./SchemaPanel"; + +const StyledCustomTab = chakra(CustomTab, { + baseStyle: { + border: "unset", + borderRadius: "4px", + _selected: { bgColor: "gray.800" }, + }, +}); + +const StyledTabPanel = chakra(TabPanel, { + baseStyle: { + p: 0, + }, +}); + +const SchemaMsgTabList = [ + SchemaProperties.INSTANTIATE as "instantiate", + SchemaProperties.EXECUTE as "execute", + SchemaProperties.QUERY as "query", + SchemaProperties.MIGRATE as "migrate", +]; + +interface CodeSchemaTabsProps { + codeId: number; + codeHash: string; + verifiedSchema: Nullish; + localSchema: Option; +} + +export const CodeSchemaTabs = ({ + codeId, + codeHash, + verifiedSchema, + localSchema, +}: CodeSchemaTabsProps) => { + const schema = verifiedSchema ?? localSchema; + const hasSchema = Boolean(schema); + return ( + + + Full Schema + {SchemaMsgTabList.map((schemaProperty) => ( + + {capitalize(schemaProperty)}Msg + + ))} + + + + + + {SchemaMsgTabList.map((schemaProperty) => ( + + + + ))} + + + ); +}; diff --git a/src/lib/pages/code-details/components/code-schema-section/SchemaPanel.tsx b/src/lib/pages/code-details/components/code-schema-section/SchemaPanel.tsx new file mode 100644 index 000000000..a82c544bb --- /dev/null +++ b/src/lib/pages/code-details/components/code-schema-section/SchemaPanel.tsx @@ -0,0 +1,45 @@ +import { Flex } from "@chakra-ui/react"; +import { capitalize } from "lodash"; + +import JsonReadOnly from "lib/components/json/JsonReadOnly"; +import { UploadSchemaSection } from "lib/components/json-schema"; +import { EmptyState } from "lib/components/state"; +import type { Nullable, Option } from "lib/types"; +import { jsonPrettify } from "lib/utils"; + +interface SchemaPanelProps { + codeId: number; + codeHash: string; + jsonSchema: Option>; + hasSchema: boolean; + schemaProperty?: string; +} + +export const SchemaPanel = ({ + codeId, + codeHash, + jsonSchema, + hasSchema, + schemaProperty, +}: SchemaPanelProps) => { + if (jsonSchema === undefined) + return hasSchema ? ( + + + + ) : ( + + ); + + return ( + + ); +}; diff --git a/src/lib/pages/code-details/components/code-schema-section/index.tsx b/src/lib/pages/code-details/components/code-schema-section/index.tsx new file mode 100644 index 000000000..4ecd99a51 --- /dev/null +++ b/src/lib/pages/code-details/components/code-schema-section/index.tsx @@ -0,0 +1,80 @@ +import { Flex, Heading, Text, useDisclosure } from "@chakra-ui/react"; + +import { EditSchemaButtons, JsonSchemaModal } from "lib/components/json-schema"; +import { UserDocsLink } from "lib/components/UserDocsLink"; +import { WasmVerifyStatus } from "lib/types"; +import type { CodeSchema, Nullish, Option, WasmVerifyInfo } from "lib/types"; +import { getWasmVerifyStatus } from "lib/utils"; + +import { CodeSchemaTabs } from "./CodeSchemaTabs"; + +interface CodeSchemaSectionProps { + codeId: number; + codeHash: string; + localSchema: Option; + wasmVerifyInfo: Nullish; +} + +export const CodeSchemaSection = ({ + codeId, + codeHash, + localSchema, + wasmVerifyInfo, +}: CodeSchemaSectionProps) => { + const { isOpen, onClose, onOpen } = useDisclosure(); + + const wasmVerifyStatus = getWasmVerifyStatus(wasmVerifyInfo); + const hasVerifiedSchema = Boolean(wasmVerifyInfo?.schema); + const attachedLocalSchema = Boolean(localSchema); + return ( + <> + + + JSON Schema + + {!hasVerifiedSchema && attachedLocalSchema && ( + + )} + + + {hasVerifiedSchema + ? `The schema is provided as the code has been ${wasmVerifyStatus !== WasmVerifyStatus.VERIFIED && "indirectly"} verified.` + : "Uploaded JSON schemas are stored locally on your device."} + + + {!hasVerifiedSchema && ( + <> + + + + )} + + ); +}; diff --git a/src/lib/pages/code-details/index.tsx b/src/lib/pages/code-details/index.tsx index a909627ec..94cd18cf5 100644 --- a/src/lib/pages/code-details/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -28,7 +28,7 @@ import { CodeInfoSection, CodeTopInfo, } from "./components/code-info"; -import { CodeLocalSchemaSection } from "./components/code-local-schema"; +import { CodeSchemaSection } from "./components/code-schema-section"; import { CodeVerificationSection } from "./components/CodeVerificationSection"; import { useCodeDataLcd } from "./data"; import { TabIndex, zCodeDetailsQueryParams } from "./types"; @@ -45,11 +45,11 @@ const InvalidCode = () => ; const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { const isMobile = useMobile(); const { isFullTier } = useTierConfig(); + const { currentChainId } = useCelatoneApp(); const navigate = useInternalNavigate(); const { getSchemaByCodeHash } = useSchemaStore(); - const { currentChainId } = useCelatoneApp(); const resApi = useCodeData(codeId, isFullTier); const resLcd = useCodeDataLcd(codeId, !isFullTier); const { data, isLoading } = isFullTier ? resApi : resLcd; @@ -81,7 +81,8 @@ const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { if (!data.info) return ; const { info: code, projectInfo, publicInfo } = data; - const jsonSchema = getSchemaByCodeHash(code.hash); + const localSchema = getSchemaByCodeHash(code.hash); + const attached = Boolean(derivedWasmVerifyInfo?.schema ?? localSchema); return ( <> @@ -122,7 +123,7 @@ const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { { /> - - diff --git a/src/lib/pages/contract-details/components/CommandSection.tsx b/src/lib/pages/contract-details/components/CommandSection.tsx deleted file mode 100644 index 523c56935..000000000 --- a/src/lib/pages/contract-details/components/CommandSection.tsx +++ /dev/null @@ -1,201 +0,0 @@ -import { - Button, - ButtonGroup, - Flex, - Heading, - Spinner, - Tag, - Text, - useDisclosure, -} from "@chakra-ui/react"; -import { observer } from "mobx-react-lite"; - -import { useInternalNavigate } from "lib/app-provider"; -import { ContractCmdButton } from "lib/components/ContractCmdButton"; -import { CustomIcon } from "lib/components/icon"; -import { - EditSchemaButtons, - JsonSchemaModal, - ViewSchemaModal, -} from "lib/components/json-schema"; -import { Tooltip } from "lib/components/Tooltip"; -import { useExecuteCmds } from "lib/hooks"; -import { useSchemaStore } from "lib/providers/store"; -import { useContractQueryMsgsLcd } from "lib/services/wasm/contract"; -import type { BechAddr32 } from "lib/types"; -import { encode, jsonPrettify } from "lib/utils"; - -interface RenderCmdsProps { - isFetching: boolean; - cmds: [string, string][]; - contractAddress: BechAddr32; - type: string; -} - -interface CommandSectionProps { - contractAddress: BechAddr32; - codeHash: string; - codeId: number; -} - -const RenderCmds = ({ - isFetching, - cmds, - contractAddress, - type, -}: RenderCmdsProps) => { - const navigate = useInternalNavigate(); - - if (isFetching) { - return ; - } - if (cmds.length) { - return ( - button": { - marginInlineStart: "0 !important", - marginInlineEnd: "1", - }, - }} - > - {cmds.sort().map(([cmd, msg]) => ( - { - navigate({ - pathname: `/interact-contract`, - query: { - selectedType: type, - contract: contractAddress, - msg: encode(jsonPrettify(msg)), - }, - }); - }} - /> - ))} - - ); - } - return ( - - No messages available - - ); -}; - -export const CommandSection = observer( - ({ contractAddress, codeHash, codeId }: CommandSectionProps) => { - const { isOpen, onClose, onOpen } = useDisclosure(); - - const { getSchemaByCodeHash } = useSchemaStore(); - const jsonSchema = getSchemaByCodeHash(codeHash); - const attached = Boolean(jsonSchema); - - const { isFetching: isQueryCmdsFetching, data: queryCmds = [] } = - useContractQueryMsgsLcd(contractAddress); - const { isFetching: isExecuteCmdsFetching, execCmds } = - useExecuteCmds(contractAddress); - - return ( - - - - Available command shortcuts - - {attached ? ( - - - - Attached Schema to Code ID {codeId} - - - - - ) : ( - - - - )} - - - - - Query Shortcuts - - - - - - Execute Shortcuts - - - - - - - ); - } -); diff --git a/src/lib/pages/contract-details/components/ContractVerificationSection.tsx b/src/lib/pages/contract-details/components/ContractVerificationSection.tsx index 8276254fd..4d575e8b7 100644 --- a/src/lib/pages/contract-details/components/ContractVerificationSection.tsx +++ b/src/lib/pages/contract-details/components/ContractVerificationSection.tsx @@ -5,17 +5,17 @@ import { WasmVerifySection } from "lib/components/wasm-verify-section"; import type { BechAddr32, Nullish, WasmVerifyInfo } from "lib/types"; interface ContractVerificationSectionProps { + contractAddress: BechAddr32; codeId: number; codeHash: string; wasmVerifyInfo: Nullish; - contractAddress: BechAddr32; } export const ContractVerificationSection = ({ + contractAddress, codeHash, codeId, wasmVerifyInfo, - contractAddress, }: ContractVerificationSectionProps) => ( ; +} + +export const CommandSectionHeader = observer( + ({ codeId, codeHash, wasmVerifyInfo }: CommandSectionHeaderProps) => { + const { getSchemaByCodeHash } = useSchemaStore(); + const { isOpen, onClose, onOpen } = useDisclosure(); + + const status = getWasmVerifyStatus(wasmVerifyInfo); + if ( + status === WasmVerifyStatus.VERIFIED || + status === WasmVerifyStatus.INDIRECTLY_VERIFIED + ) + return ( + + + + Verified command shortcuts + + + ); + + const localSchema = getSchemaByCodeHash(codeHash); + const attached = Boolean(localSchema); + return ( + + + Available command shortcuts + + {localSchema ? ( + + + + Attached Schema to Code ID {codeId} + + + + + ) : ( + + + + )} + + + ); + } +); diff --git a/src/lib/pages/contract-details/components/command-section/ContractCmdGroup.tsx b/src/lib/pages/contract-details/components/command-section/ContractCmdGroup.tsx new file mode 100644 index 000000000..fe37f06db --- /dev/null +++ b/src/lib/pages/contract-details/components/command-section/ContractCmdGroup.tsx @@ -0,0 +1,63 @@ +import { ButtonGroup, Spinner, Text } from "@chakra-ui/react"; + +import { useInternalNavigate } from "lib/app-provider"; +import { ContractCmdButton } from "lib/components/ContractCmdButton"; +import type { BechAddr32 } from "lib/types"; +import { jsonPrettify, libEncode } from "lib/utils"; + +interface ContractCmdGroupProps { + isFetching: boolean; + cmds: [string, string][]; + contractAddress: BechAddr32; + type: string; +} + +export const ContractCmdGroup = ({ + isFetching, + cmds, + contractAddress, + type, +}: ContractCmdGroupProps) => { + const navigate = useInternalNavigate(); + + if (isFetching) { + return ; + } + if (cmds.length) { + return ( + button": { + marginInlineStart: "0 !important", + marginInlineEnd: "1", + }, + }} + > + {cmds.sort().map(([cmd, msg]) => ( + { + navigate({ + pathname: `/interact-contract`, + query: { + selectedType: type, + contract: contractAddress, + msg: libEncode(jsonPrettify(msg)), + }, + }); + }} + /> + ))} + + ); + } + return ( + + No messages available + + ); +}; diff --git a/src/lib/pages/contract-details/components/command-section/index.tsx b/src/lib/pages/contract-details/components/command-section/index.tsx new file mode 100644 index 000000000..aa9ebe253 --- /dev/null +++ b/src/lib/pages/contract-details/components/command-section/index.tsx @@ -0,0 +1,73 @@ +import { Flex, Text } from "@chakra-ui/react"; + +import { useExecuteCmds } from "lib/hooks"; +import { useContractQueryMsgsLcd } from "lib/services/wasm/contract"; +import type { BechAddr32, Nullish, WasmVerifyInfo } from "lib/types"; + +import { CommandSectionHeader } from "./CommandSectionHeader"; +import { ContractCmdGroup } from "./ContractCmdGroup"; + +interface CommandSectionProps { + contractAddress: BechAddr32; + codeHash: string; + codeId: number; + wasmVerifyInfo: Nullish; +} + +export const CommandSection = ({ + contractAddress, + ...props +}: CommandSectionProps) => { + const { isFetching: isQueryCmdsFetching, data: queryCmds = [] } = + useContractQueryMsgsLcd(contractAddress); + const { isFetching: isExecuteCmdsFetching, execCmds } = + useExecuteCmds(contractAddress); + + return ( + + + + + + Query Shortcuts + + + + + + Execute Shortcuts + + + + + + ); +}; diff --git a/src/lib/pages/contract-details/index.tsx b/src/lib/pages/contract-details/index.tsx index baad2b575..32c3da16f 100644 --- a/src/lib/pages/contract-details/index.tsx +++ b/src/lib/pages/contract-details/index.tsx @@ -35,7 +35,7 @@ import { useDerivedWasmVerifyInfo } from "lib/services/verification/wasm"; import type { BechAddr32 } from "lib/types"; import { jsonPrettify, truncate } from "lib/utils"; -import { CommandSection } from "./components/CommandSection"; +import { CommandSection } from "./components/command-section"; import { ContractDesc } from "./components/contract-description"; import { ContractStates } from "./components/contract-states"; import { ContractTop } from "./components/ContractTop"; @@ -76,7 +76,7 @@ const ContractDetailsBody = observer( const { isTotalBondedLoading, totalBonded } = useAccountDelegationInfos(contractAddress); - const { data: relatedWasmVerifyInfo } = useDerivedWasmVerifyInfo( + const { data: derivedWasmVerifyInfo } = useDerivedWasmVerifyInfo( contractData?.contract.codeId, contractData?.contract.codeHash ); @@ -121,7 +121,7 @@ const ContractDetailsBody = observer( publicInfo={publicInfo} contract={contract} contractLocalInfo={contractLocalInfo} - wasmVerifyInfo={relatedWasmVerifyInfo} + wasmVerifyInfo={derivedWasmVerifyInfo} /> )} diff --git a/src/lib/components/json-schema/section/SchemaInputSection.tsx b/src/lib/components/json-schema/section/SchemaInputSection.tsx index 37465a282..01f174a09 100644 --- a/src/lib/components/json-schema/section/SchemaInputSection.tsx +++ b/src/lib/components/json-schema/section/SchemaInputSection.tsx @@ -107,10 +107,19 @@ export const SchemaInputSection = observer( : "You are using a locally attached JSON Schema"} - - + + {!verifiedSchema && ( + + )} )} diff --git a/src/lib/components/json-schema/upload/UploadSchema.tsx b/src/lib/components/json-schema/upload/UploadSchema.tsx index a82721eb0..d77c0c902 100644 --- a/src/lib/components/json-schema/upload/UploadSchema.tsx +++ b/src/lib/components/json-schema/upload/UploadSchema.tsx @@ -25,6 +25,7 @@ export const UploadSchema = ({ <> {triggerElement ? ( { e.stopPropagation(); onOpen(); diff --git a/src/lib/components/json-schema/view/ViewSchemaModal.tsx b/src/lib/components/json-schema/view/ViewSchemaModal.tsx index 3eb609465..9b0c97c1b 100644 --- a/src/lib/components/json-schema/view/ViewSchemaModal.tsx +++ b/src/lib/components/json-schema/view/ViewSchemaModal.tsx @@ -45,7 +45,7 @@ const StyledTabPanel = chakra(TabPanel, { interface ViewSchemaModalProps { codeId: number; - localSchema: Option; + schema: Option; isIcon?: boolean; } @@ -60,7 +60,7 @@ const ALL_TABS = ["full schema", ...SchemaMsgTabList]; export const ViewSchemaModal = ({ codeId, - localSchema, + schema, isIcon = false, }: ViewSchemaModalProps) => { const { isOpen, onClose, onOpen } = useDisclosure(); @@ -138,12 +138,12 @@ export const ViewSchemaModal = ({ - + {SchemaMsgTabList.map((schemaProperty) => ( diff --git a/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitCompleted.tsx b/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitCompleted.tsx index 34311831f..5f54edf9e 100644 --- a/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitCompleted.tsx +++ b/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitCompleted.tsx @@ -1,23 +1,41 @@ -import { Flex, Heading, ModalBody, Text } from "@chakra-ui/react"; +import { + Button, + Flex, + Heading, + ModalBody, + ModalCloseButton, + Text, +} from "@chakra-ui/react"; import { CustomIcon } from "lib/components/icon"; -export const WasmVerifySubmitCompleted = () => ( - - - - Submitted Verification! - - Your code verification request has been submitted. Verification details - will be available shortly... - - - +interface WasmVerifySubmitCompletedProps { + onClose: () => void; +} + +export const WasmVerifySubmitCompleted = ({ + onClose, +}: WasmVerifySubmitCompletedProps) => ( + <> + + + + + + Submitted Verification! + + Your code verification request has been submitted. Verification + details will be available shortly... + + + + + + ); diff --git a/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitFailed.tsx b/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitFailed.tsx index ddcc18fc7..695cc3e40 100644 --- a/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitFailed.tsx +++ b/src/lib/components/modal/wasm-verify-submit/WasmVerifySubmitFailed.tsx @@ -22,7 +22,7 @@ export const WasmVerifySubmitFailed = ({ <> - + ; wasmVerifyStatus: WasmVerifyStatus; relatedVerifiedCodes?: number[]; contractAddress?: BechAddr32; @@ -44,7 +44,7 @@ export const WasmVerifySubmitForm = ({ isLoading, }: WasmVerifySubmitFormProps) => { const { currentChainId } = useCelatoneApp(); - const rustOptimizerVersions = useRustOptimizerVersions(); + const wasmOptimizerVersions = useWasmOptimizerVersions(); const { control, @@ -158,18 +158,20 @@ export const WasmVerifySubmitForm = ({ )} - - - Code Hash: - - - + {codeHash && ( + + + Code Hash: + + + + )}