From 0f3167971555b811f43d1c431b844f88bdf6368c Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Tue, 26 Dec 2023 20:58:17 +0700 Subject: [PATCH 1/5] feat: api v1 contract info --- CHANGELOG.md | 1 + src/lib/app-provider/env.ts | 4 +- src/lib/app-provider/hooks/useBaseApiRoute.ts | 3 - src/lib/app-provider/tx/clearAdmin.ts | 2 +- src/lib/components/button/AdminButton.tsx | 4 +- .../json-schema/AttachSchemaCard.tsx | 2 +- .../components/json-schema/AttachStatus.tsx | 2 +- .../json-schema/EditSchemaButtons.tsx | 2 +- .../json-schema/JsonSchemaModal.tsx | 2 +- .../components/json-schema/UploadTemplate.tsx | 4 +- .../section/SchemaInputSection.tsx | 2 +- .../json-schema/upload/UploadSchema.tsx | 2 +- .../upload/UploadSchemaSection.tsx | 2 +- .../json-schema/view/ViewSchemaModal.tsx | 2 +- .../json-schema/view/ViewSchemaPanel.tsx | 70 ++++---- .../components/modal/RemoveSchemaModal.tsx | 2 +- src/lib/components/modal/code/SaveNewCode.tsx | 69 +++---- src/lib/model/code.ts | 17 +- .../components/AccountHeader.tsx | 32 ++-- src/lib/pages/account-details/index.tsx | 16 +- .../components/code-info/CodeInfoSection.tsx | 2 +- .../json-schema/CodeSchemaSection.tsx | 2 +- .../components/json-schema/SchemaPanel.tsx | 2 +- src/lib/pages/code-details/index.tsx | 2 +- .../components/CommandSection.tsx | 6 +- .../components/ContractTop.tsx | 103 +++++------ .../components/InstantiateInfo.tsx | 123 ++++--------- .../contract-details/components/JsonInfo.tsx | 9 +- .../contract-description/UserContractDesc.tsx | 71 ++++---- .../components/contract-description/index.tsx | 22 +-- src/lib/pages/contract-details/data.ts | 86 +-------- src/lib/pages/contract-details/index.tsx | 70 ++++---- src/lib/pages/contract-details/types.ts | 38 +--- .../pages/execute/components/ExecuteArea.tsx | 60 ++++--- .../components/schema-execute/index.tsx | 2 +- src/lib/pages/execute/index.tsx | 4 +- src/lib/pages/instantiate/instantiate.tsx | 20 ++- .../migrate/components/MigrateContract.tsx | 18 +- src/lib/pages/query/components/QueryArea.tsx | 58 +++--- .../pages/query/components/SchemaQuery.tsx | 2 +- src/lib/pages/query/index.tsx | 4 +- src/lib/pages/upload/completed.tsx | 2 +- src/lib/query/contract.ts | 40 ----- src/lib/services/account.ts | 18 +- src/lib/services/accountService.ts | 8 +- src/lib/services/code.ts | 10 +- src/lib/services/codeService.ts | 9 +- src/lib/services/contract.ts | 169 ++++++++++++------ src/lib/services/contractService.ts | 87 +++------ src/lib/services/publicProjectService.ts | 33 ---- src/lib/types/projects.ts | 16 +- src/lib/utils/cw2.ts | 6 +- 52 files changed, 556 insertions(+), 786 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81a871f7f..b1cf4d07b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Improvements +- [#702](https://github.com/alleslabs/celatone-frontend/pull/702) api v1 - contract info - [#697](https://github.com/alleslabs/celatone-frontend/pull/697) api v1 - contract tables (migrations and related proposals) - [#696](https://github.com/alleslabs/celatone-frontend/pull/696) api v1 - block details - [#695](https://github.com/alleslabs/celatone-frontend/pull/695) api v1 - contract states diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index 95163c888..84c80ccff 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -13,7 +13,6 @@ export enum CELATONE_QUERY_KEYS { // CONTRACT,CODE LCD CODE_INFO = "CELATONE_QUERY_CODE_INFO", CONTRACT_DETAIL_BY_CONTRACT_ADDRESS = "CELATONE_QUERY_CONTRACT_DETAIL_BY_CONTRACT_ADDRESS", - CONTRACT_CW2_INFO = "CELATONE_QUERY_CONTRACT_CW2_INFO", CONTRACT_INFO = "CELATONE_QUERY_CONTRACT_INFO", CONTRACT_QUERY_CMDS = "CELATONE_QUERY_CONTRACT_QUERY_CMDS", CONTRACT_QUERY = "CELATONE_QUERY_CONTRACT_QUERY", @@ -35,8 +34,8 @@ export enum CELATONE_QUERY_KEYS { CODE_DATA_BY_ID = "CELATONE_QUERY_CODE_DATA_BY_ID", // CONTRACT GQL CONTRACTS = "CELATONE_QUERY_CONTRACTS", + CONTRACT_DATA = "CELATONE_QUERY_CONTRACT_DATA", CONTRACTS_BY_ADMIN = "CELATONE_QUERY_CONTRACT_BY_ADMIN", - CONTRACT_INSTANTIATE_DETAIL = "CELATONE_QUERY_CONTRACT_INSTANTIATE_DETAIL", INSTANTIATED_CONTRACTS_BY_ADDRESS = "CELATONE_QUERY_INSTANTIATED_CONTRACTS_BY_ADDRESS", ADMIN_CONTRACTS_BY_ADDRESS = "CELATONE_QUERY_ADMIN_CONTRACTS_BY_ADDRESS", INSTANTIATED_COUNT_BY_WALLET_ADDRESS = "CELATONE_QUERY_INSTANTIATED_COUNT_BY_WALLET_ADDRESS", @@ -64,7 +63,6 @@ export enum CELATONE_QUERY_KEYS { // PUBLIC PROJECT PUBLIC_PROJECTS = "CELATONE_QUERY_PUBLIC_PROJECTS", PUBLIC_PROJECT_BY_SLUG = "CELATONE_QUERY_PUBLIC_PROJECT_BY_SLUG", - PUBLIC_PROJECT_BY_CONTRACT_ADDRESS = "CELATONE_QUERY_PUBLIC_PROJECT_BY_CONTRACT_ADDRESS", PUBLIC_PROJECT_BY_CODE_ID = "CELATONE_QUERY_PUBLIC_PROJECT_BY_CODE_ID", PUBLIC_PROJECT_BY_WALLET_ADDRESS = "CELATONE_QUERY_PUBLIC_PROJECT_BY_WALLET_ADDRESS", PUBLIC_PROJECT_BY_MODULE_PATH = "CELATONE_QUERY_PUBLIC_PROJECT_BY_MODULE_PATH", diff --git a/src/lib/app-provider/hooks/useBaseApiRoute.ts b/src/lib/app-provider/hooks/useBaseApiRoute.ts index 0c701c328..89ec60101 100644 --- a/src/lib/app-provider/hooks/useBaseApiRoute.ts +++ b/src/lib/app-provider/hooks/useBaseApiRoute.ts @@ -11,7 +11,6 @@ export const useBaseApiRoute = ( | "blocks" | "contracts" | "projects" - | "project_contracts" | "codes" | "legacy.accounts" | "rest" @@ -48,8 +47,6 @@ export const useBaseApiRoute = ( return `${api}/v1/${chain}/${currentChainId}/contracts`; case "projects": return `${api}/projects/${chain}/${currentChainId}`; - case "project_contracts": - return `${api}/contracts/${chain}/${currentChainId}`; case "codes": return `${api}/codes/${chain}/${currentChainId}`; case "legacy.accounts": diff --git a/src/lib/app-provider/tx/clearAdmin.ts b/src/lib/app-provider/tx/clearAdmin.ts index 2881a260a..6306a8b63 100644 --- a/src/lib/app-provider/tx/clearAdmin.ts +++ b/src/lib/app-provider/tx/clearAdmin.ts @@ -43,7 +43,7 @@ export const useClearAdminTx = (contractAddress: ContractAddr) => { queryKey: [CELATONE_QUERY_KEYS.ADMINS_BY_CONTRACTS], }), queryClient.invalidateQueries({ - queryKey: [CELATONE_QUERY_KEYS.CONTRACT_INSTANTIATE_DETAIL], + queryKey: [CELATONE_QUERY_KEYS.CONTRACT_DATA], }), ]); }, diff --git a/src/lib/components/button/AdminButton.tsx b/src/lib/components/button/AdminButton.tsx index 77ce763c7..1f60e2ce9 100644 --- a/src/lib/components/button/AdminButton.tsx +++ b/src/lib/components/button/AdminButton.tsx @@ -4,11 +4,11 @@ import { CustomIcon } from "../icon"; import { ClearAdminModal } from "../modal/contract/ClearAdmin"; import { Tooltip } from "../Tooltip"; import { useCurrentChain, useInternalNavigate } from "lib/app-provider"; -import type { Addr, ContractAddr, Option } from "lib/types"; +import type { Addr, ContractAddr, Nullable } from "lib/types"; interface AdminButtonProps { contractAddress: ContractAddr; - admin: Option; + admin: Nullable; } export const AdminButton = ({ contractAddress, admin }: AdminButtonProps) => { diff --git a/src/lib/components/json-schema/AttachSchemaCard.tsx b/src/lib/components/json-schema/AttachSchemaCard.tsx index 0b4dfe83f..34303bdd4 100644 --- a/src/lib/components/json-schema/AttachSchemaCard.tsx +++ b/src/lib/components/json-schema/AttachSchemaCard.tsx @@ -11,7 +11,7 @@ import { ViewSchemaModal } from "./view/ViewSchemaModal"; interface AttachSchemaCardProps { attached: boolean; - codeId: string; + codeId: number; codeHash: string; schema: Option; openModal: () => void; diff --git a/src/lib/components/json-schema/AttachStatus.tsx b/src/lib/components/json-schema/AttachStatus.tsx index 99ca6394f..4edea0bcd 100644 --- a/src/lib/components/json-schema/AttachStatus.tsx +++ b/src/lib/components/json-schema/AttachStatus.tsx @@ -4,7 +4,7 @@ import { ConnectingLine } from "../ConnectingLine"; import { CustomIcon } from "../icon"; interface AttachStatusProps { - codeId: string; + codeId: number; isReattach?: boolean; } export const AttachStatus = ({ diff --git a/src/lib/components/json-schema/EditSchemaButtons.tsx b/src/lib/components/json-schema/EditSchemaButtons.tsx index fe7f70f47..4756c8cc5 100644 --- a/src/lib/components/json-schema/EditSchemaButtons.tsx +++ b/src/lib/components/json-schema/EditSchemaButtons.tsx @@ -7,7 +7,7 @@ import { Tooltip } from "../Tooltip"; import { AmpEvent, track } from "lib/amplitude"; interface EditSchemaButtonsProps { - codeId: string; + codeId: number; codeHash: string; openModal: () => void; } diff --git a/src/lib/components/json-schema/JsonSchemaModal.tsx b/src/lib/components/json-schema/JsonSchemaModal.tsx index 7aa9176d6..29d561f45 100644 --- a/src/lib/components/json-schema/JsonSchemaModal.tsx +++ b/src/lib/components/json-schema/JsonSchemaModal.tsx @@ -14,7 +14,7 @@ import { AttachStatus } from "./AttachStatus"; import { UploadTemplate } from "./UploadTemplate"; interface JsonSchemaModalProps { - codeId: string; + codeId: number; codeHash: string; isOpen: boolean; isReattach?: boolean; diff --git a/src/lib/components/json-schema/UploadTemplate.tsx b/src/lib/components/json-schema/UploadTemplate.tsx index aee383888..b8a3d4822 100644 --- a/src/lib/components/json-schema/UploadTemplate.tsx +++ b/src/lib/components/json-schema/UploadTemplate.tsx @@ -187,7 +187,7 @@ const MethodRender = ({ interface UploadTemplateInterface { codeHash: string; - codeId: string; + codeId: number; isReattach: boolean; closeDrawer: () => void; onSchemaSave?: () => void; @@ -249,7 +249,7 @@ export const UploadTemplate = ({ error: schemaValidateError, }); } - saveNewSchema(codeHash, codeId, JSON.parse(schemaString)); + saveNewSchema(codeHash, codeId.toString(), JSON.parse(schemaString)); track(AmpEvent.ACTION_ATTACH_JSON, { method, isReattach }); toast({ title: `Attached JSON Schema`, diff --git a/src/lib/components/json-schema/section/SchemaInputSection.tsx b/src/lib/components/json-schema/section/SchemaInputSection.tsx index b6f3aeae5..43bba5263 100644 --- a/src/lib/components/json-schema/section/SchemaInputSection.tsx +++ b/src/lib/components/json-schema/section/SchemaInputSection.tsx @@ -16,7 +16,7 @@ import type { Option } from "lib/types"; interface SchemaSectionProps { type: "migrate" | "instantiate"; codeHash: string; - codeId: string; + codeId: number; jsonSchema: Option; initialFormData?: Record; handleChange: (data: unknown, errors: RJSFValidationError[]) => void; diff --git a/src/lib/components/json-schema/upload/UploadSchema.tsx b/src/lib/components/json-schema/upload/UploadSchema.tsx index 6fcd80af9..dafc060e4 100644 --- a/src/lib/components/json-schema/upload/UploadSchema.tsx +++ b/src/lib/components/json-schema/upload/UploadSchema.tsx @@ -8,7 +8,7 @@ import type { Option } from "lib/types"; interface UploadSchemaContentInterface { attached: boolean; schema: Option; - codeId: string; + codeId: number; codeHash: string; } diff --git a/src/lib/components/json-schema/upload/UploadSchemaSection.tsx b/src/lib/components/json-schema/upload/UploadSchemaSection.tsx index 24163f8cc..b4d6d9fda 100644 --- a/src/lib/components/json-schema/upload/UploadSchemaSection.tsx +++ b/src/lib/components/json-schema/upload/UploadSchemaSection.tsx @@ -9,7 +9,7 @@ import { UploadSchema } from "./UploadSchema"; interface UploadSchemaSectionProps { schema?: Option; - codeId: string; + codeId: number; codeHash: string; title?: string | JSX.Element; } diff --git a/src/lib/components/json-schema/view/ViewSchemaModal.tsx b/src/lib/components/json-schema/view/ViewSchemaModal.tsx index 7efa8b201..b0f2036aa 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: string; + codeId: number; jsonSchema: Option; isIcon?: boolean; } diff --git a/src/lib/components/json-schema/view/ViewSchemaPanel.tsx b/src/lib/components/json-schema/view/ViewSchemaPanel.tsx index adee4695a..cac247937 100644 --- a/src/lib/components/json-schema/view/ViewSchemaPanel.tsx +++ b/src/lib/components/json-schema/view/ViewSchemaPanel.tsx @@ -7,45 +7,43 @@ import { jsonPrettify } from "lib/utils"; interface ViewSchemaPanelProps { jsonSchema: Option>; - codeId: string; + codeId: number; } export const ViewSchemaPanel = ({ jsonSchema, codeId, -}: ViewSchemaPanelProps) => { - return ( - <> - {jsonSchema === undefined ? ( - ( + <> + {jsonSchema === undefined ? ( + + + You haven't attached the JSON Schema for{" "} + + code {codeId} yet + + - - You haven't attached the JSON Schema for{" "} - - code {codeId} yet - - - Please attach schema in Code Detail page - - - ) : ( - - )} - - ); -}; + Please attach schema in Code Detail page + + + ) : ( + + )} + +); diff --git a/src/lib/components/modal/RemoveSchemaModal.tsx b/src/lib/components/modal/RemoveSchemaModal.tsx index 57f57181d..fe35eafcb 100644 --- a/src/lib/components/modal/RemoveSchemaModal.tsx +++ b/src/lib/components/modal/RemoveSchemaModal.tsx @@ -8,7 +8,7 @@ import { useSchemaStore } from "lib/providers/store"; import { ActionModal } from "./ActionModal"; interface RemoveSchemaModalProps { - codeId: string; + codeId: number; codeHash: string; trigger: ReactNode; } diff --git a/src/lib/components/modal/code/SaveNewCode.tsx b/src/lib/components/modal/code/SaveNewCode.tsx index 8c0fa7af9..38719f842 100644 --- a/src/lib/components/modal/code/SaveNewCode.tsx +++ b/src/lib/components/modal/code/SaveNewCode.tsx @@ -1,22 +1,16 @@ import type { ButtonProps } from "@chakra-ui/react"; import { Button, useToast, FormControl } from "@chakra-ui/react"; -import { useQuery } from "@tanstack/react-query"; import { useEffect, useMemo, useState } from "react"; import { ActionModal } from "../ActionModal"; import { AmpEvent, track } from "lib/amplitude"; -import { - CELATONE_QUERY_KEYS, - useBaseApiRoute, - useCelatoneApp, - useCurrentChain, -} from "lib/app-provider"; +import { useCelatoneApp, useCurrentChain } from "lib/app-provider"; import type { FormStatus } from "lib/components/forms"; import { TextInput, NumberInput } from "lib/components/forms"; import { CustomIcon } from "lib/components/icon"; import { useGetMaxLengthError } from "lib/hooks"; import { useCodeStore } from "lib/providers/store"; -import { getCodeIdInfo } from "lib/services/code"; +import { useLCDCodeInfo } from "lib/services/codeService"; import type { Addr, HumanAddr } from "lib/types"; import { getNameAndDescriptionDefault, getPermissionHelper } from "lib/utils"; @@ -60,38 +54,33 @@ export function SaveNewCodeModal({ buttonProps }: SaveNewCodeModalProps) { const toast = useToast(); const { isCodeIdSaved, saveNewCode, updateCodeInfo, getCodeLocalInfo } = useCodeStore(); - const lcdEndpoint = useBaseApiRoute("rest"); - - const { refetch, isFetching, isRefetching } = useQuery( - [CELATONE_QUERY_KEYS.CODE_INFO, lcdEndpoint, codeId], - async () => getCodeIdInfo(lcdEndpoint, codeId), - { - enabled: false, - retry: false, - cacheTime: 0, - onSuccess(data) { - const { message, messageColor } = getPermissionHelper( - address as HumanAddr, - data.code_info.instantiate_permission.permission, - data.code_info.instantiate_permission.address - ? [data.code_info.instantiate_permission.address] - : data.code_info.instantiate_permission.addresses - ); - setCodeIdStatus({ - state: "success", - message: `${message} (${data.code_info.instantiate_permission.permission})`, - messageColor, - }); - setUploader(data.code_info.creator); - setUploaderStatus({ state: "success" }); - }, - onError() { - setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); - setUploader("Not Found"); - setUploaderStatus({ state: "error" }); - }, - } - ); + + const { refetch, isFetching, isRefetching } = useLCDCodeInfo(codeId, { + enabled: false, + retry: false, + cacheTime: 0, + onSuccess(data) { + const { message, messageColor } = getPermissionHelper( + address as HumanAddr, + data.code_info.instantiate_permission.permission, + data.code_info.instantiate_permission.address + ? [data.code_info.instantiate_permission.address] + : data.code_info.instantiate_permission.addresses + ); + setCodeIdStatus({ + state: "success", + message: `${message} (${data.code_info.instantiate_permission.permission})`, + messageColor, + }); + setUploader(data.code_info.creator); + setUploaderStatus({ state: "success" }); + }, + onError() { + setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); + setUploader("Not Found"); + setUploaderStatus({ state: "error" }); + }, + }); /* CALLBACK */ const reset = () => { diff --git a/src/lib/model/code.ts b/src/lib/model/code.ts index 54cadbeb4..a3fddde46 100644 --- a/src/lib/model/code.ts +++ b/src/lib/model/code.ts @@ -1,12 +1,6 @@ -import { useQuery } from "@tanstack/react-query"; import { useMemo } from "react"; -import { - CELATONE_QUERY_KEYS, - useBaseApiRoute, - useCelatoneApp, - useCurrentChain, -} from "lib/app-provider"; +import { useCelatoneApp, useCurrentChain } from "lib/app-provider"; import type { PermissionFilterValue } from "lib/hooks"; import { useUserKey, @@ -14,11 +8,11 @@ import { useCodeSearchFilter, } from "lib/hooks"; import { useCodeStore } from "lib/providers/store"; -import { getCodeIdInfo } from "lib/services/code"; import { useCodeDataByCodeId, useCodeListByCodeIds, useCodeListByWalletAddress, + useLCDCodeInfo, } from "lib/services/codeService"; import { usePublicProjectByCodeId, @@ -51,7 +45,6 @@ export interface CodeDataState { export const useCodeData = (codeId: string): CodeDataState => { const { currentChainId } = useCelatoneApp(); - const lcdEndpoint = useBaseApiRoute("rest"); const { data: codeInfo, isLoading } = useCodeDataByCodeId({ codeId }); const { data: publicCodeInfo } = usePublicProjectByCodeId(codeId); @@ -62,11 +55,7 @@ export const useCodeData = (codeId: string): CodeDataState => { data: lcdCode, isLoading: isLcdCodeLoading, error: isLcdCodeError, - } = useQuery( - [CELATONE_QUERY_KEYS.CODE_INFO, lcdEndpoint, codeId], - async () => getCodeIdInfo(lcdEndpoint, codeId), - { enabled: Boolean(lcdEndpoint) && Boolean(codeId), retry: false } - ); + } = useLCDCodeInfo(codeId); return { isLoading, diff --git a/src/lib/pages/account-details/components/AccountHeader.tsx b/src/lib/pages/account-details/components/AccountHeader.tsx index fe447b925..6f86b362e 100644 --- a/src/lib/pages/account-details/components/AccountHeader.tsx +++ b/src/lib/pages/account-details/components/AccountHeader.tsx @@ -11,19 +11,19 @@ import { } from "lib/components/modal"; import { PrimaryNameMark } from "lib/components/PrimaryNameMark"; import { useAccountStore } from "lib/providers/store"; -import type { AccountInfo } from "lib/services/account"; +import type { AccountData } from "lib/services/account"; import type { HexAddr, HumanAddr, Option } from "lib/types"; import { TotalAccountValue } from "./TotalAccountValue"; interface AccounHeaderProps { - accountInfo: Option; + accountData: Option; accountAddress: HumanAddr; hexAddress: HexAddr; } export const AccountHeader = observer( - ({ accountInfo, accountAddress, hexAddress }: AccounHeaderProps) => { + ({ accountData, accountAddress, hexAddress }: AccounHeaderProps) => { const move = useMoveConfig({ shouldRedirect: false }); const { isAccountSaved, getAccountLocalInfo } = useAccountStore(); @@ -31,8 +31,8 @@ export const AccountHeader = observer( const accountLocalInfo = getAccountLocalInfo(accountAddress); const displayName = accountLocalInfo?.name ?? - accountInfo?.publicInfo?.name ?? - (accountInfo?.icns?.primary_name || "Account Details"); + accountData?.publicInfo?.name ?? + (accountData?.icns?.primary_name || "Account Details"); const isMobile = useMobile(); @@ -45,17 +45,17 @@ export const AccountHeader = observer( - {accountInfo?.projectInfo?.logo || - accountInfo?.icns?.primary_name ? ( + {accountData?.projectInfo?.logo || + accountData?.icns?.primary_name ? ( { )} - {accountInfo?.icns && ( + {accountData?.icns && ( Registered ICNS names: - {accountInfo.icns.names.map((name) => ( + {accountData.icns.names.map((name) => ( - {name === accountInfo.icns?.primary_name && ( + {name === accountData.icns?.primary_name && ( )} diff --git a/src/lib/pages/account-details/index.tsx b/src/lib/pages/account-details/index.tsx index f444111c8..6f1038ee1 100644 --- a/src/lib/pages/account-details/index.tsx +++ b/src/lib/pages/account-details/index.tsx @@ -25,7 +25,7 @@ import { CustomIcon } from "lib/components/icon"; import PageContainer from "lib/components/PageContainer"; import { InvalidState } from "lib/components/state"; import { useFormatAddresses } from "lib/hooks/useFormatAddresses"; -import { useAccountInfo } from "lib/services/accountService"; +import { useAccountData } from "lib/services/accountService"; import { useModulesByAddress } from "lib/services/move/moduleService"; import { useResourcesByAddress } from "lib/services/move/resourceService"; import type { Addr, HexAddr, HumanAddr, Option } from "lib/types"; @@ -82,7 +82,7 @@ const AccountDetailsBody = ({ // ------------------------------------------// // ------------------QUERIES-----------------// // ------------------------------------------// - const { data: accountInfo } = useAccountInfo(accountAddress); + const { data: accountData } = useAccountData(accountAddress); const { tableCounts, @@ -119,13 +119,13 @@ const AccountDetailsBody = ({ return ( <> - {accountInfo?.projectInfo && accountInfo?.publicInfo && ( + {accountData?.projectInfo && accountData?.publicInfo && ( )} @@ -252,7 +252,7 @@ const AccountDetailsBody = ({ gap={{ base: 4, md: 6 }} mt={{ base: 0, md: 8 }} > - {accountInfo?.publicInfo?.description && ( + {accountData?.publicInfo?.description && ( - {accountInfo.publicInfo.description} + {accountData.publicInfo.description} )} diff --git a/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx b/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx index 484053b02..a528283a6 100644 --- a/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx +++ b/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx @@ -215,7 +215,7 @@ export const CodeInfoSection = ({ diff --git a/src/lib/pages/code-details/components/json-schema/CodeSchemaSection.tsx b/src/lib/pages/code-details/components/json-schema/CodeSchemaSection.tsx index 9fc4f0a59..939f3ca80 100644 --- a/src/lib/pages/code-details/components/json-schema/CodeSchemaSection.tsx +++ b/src/lib/pages/code-details/components/json-schema/CodeSchemaSection.tsx @@ -36,7 +36,7 @@ const StyledTabPanel = chakra(TabPanel, { }); interface CodeSchemaSectionProps { - codeId: string; + codeId: number; codeHash: Option; isCodeHashLoading: boolean; jsonSchema: Option; diff --git a/src/lib/pages/code-details/components/json-schema/SchemaPanel.tsx b/src/lib/pages/code-details/components/json-schema/SchemaPanel.tsx index c42725129..ef83fa331 100644 --- a/src/lib/pages/code-details/components/json-schema/SchemaPanel.tsx +++ b/src/lib/pages/code-details/components/json-schema/SchemaPanel.tsx @@ -4,7 +4,7 @@ import type { Nullable, Option } from "lib/types"; import { jsonPrettify } from "lib/utils"; interface SchemaPanelProps { - codeId: string; + codeId: number; codeHash: string; schema: Option>; } diff --git a/src/lib/pages/code-details/index.tsx b/src/lib/pages/code-details/index.tsx index 58a6f7428..cf1318629 100644 --- a/src/lib/pages/code-details/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -128,7 +128,7 @@ const CodeDetailsBody = observer( ); diff --git a/src/lib/pages/contract-details/components/ContractTop.tsx b/src/lib/pages/contract-details/components/ContractTop.tsx index 34881c3ec..6ac4e09a1 100644 --- a/src/lib/pages/contract-details/components/ContractTop.tsx +++ b/src/lib/pages/contract-details/components/ContractTop.tsx @@ -7,7 +7,6 @@ import { Image, } from "@chakra-ui/react"; -import type { ContractData } from "../types"; import { useInternalNavigate, useMobile } from "lib/app-provider"; import { Breadcrumb } from "lib/components/Breadcrumb"; import { AdminButton } from "lib/components/button"; @@ -19,38 +18,45 @@ import { EditContractDetailsModal, SaveContractDetailsModal, } from "lib/components/modal"; -import type { ContractAddr } from "lib/types"; +import type { Contract } from "lib/services/contract"; +import type { ContractLocalInfo } from "lib/stores/contract"; +import type { + ContractAddr, + Nullable, + Option, + ProjectInfo, + PublicContractInfo, +} from "lib/types"; import { truncate } from "lib/utils"; interface ContractTopProps { contractAddress: ContractAddr; - contractLocalInfo: ContractData["contractLocalInfo"]; - publicProject: ContractData["publicProject"]; - contractDetail: ContractData["contractDetail"]; - rawContractResponse: ContractData["rawContractResponse"]; + + projectInfo: Nullable; + publicInfo: Nullable; + contract: Contract; + contractLocalInfo: Option; } export const ContractTop = ({ contractAddress, + projectInfo, + publicInfo, + contract, contractLocalInfo, - publicProject, - contractDetail, - rawContractResponse, }: ContractTopProps) => { - const navigate = useInternalNavigate(); const isMobile = useMobile(); + const navigate = useInternalNavigate(); + const displayName = - contractLocalInfo?.name || - publicProject.publicInfo?.name || - contractDetail?.label; + contractLocalInfo?.name || publicInfo?.name || contract.label; + const projectName = projectInfo?.name; - const publicName = publicProject.publicDetail?.name; const goToQuery = () => { navigate({ pathname: "/query", query: { ...(contractAddress && { contract: contractAddress }) }, }); }; - const goToExecute = () => { navigate({ pathname: "/execute", @@ -81,27 +87,25 @@ export const ContractTop = ({ /> ); } - if (contractDetail) { - return ( - } - /> - } - /> - ); - } - return null; + + return ( + } + /> + } + /> + ); }; return ( @@ -109,12 +113,12 @@ export const ContractTop = ({ - {publicProject.publicDetail?.logo && ( + {projectInfo && ( {publicProject.publicDetail.name} @@ -188,11 +192,10 @@ export const ContractTop = ({ Label: - {contractDetail?.label ?? - rawContractResponse?.contract_info.label} + {contract.label} - {publicProject.publicInfo?.name && ( + {publicInfo?.name && ( - {publicProject.publicInfo?.name} + {publicInfo.name} )} - {publicProject.publicInfo?.github && ( - - )} + {publicInfo?.github && } )} diff --git a/src/lib/pages/contract-details/components/InstantiateInfo.tsx b/src/lib/pages/contract-details/components/InstantiateInfo.tsx index 337940f4f..9abc41aff 100644 --- a/src/lib/pages/contract-details/components/InstantiateInfo.tsx +++ b/src/lib/pages/contract-details/components/InstantiateInfo.tsx @@ -1,27 +1,19 @@ import { Box, chakra, Divider, Flex, Text } from "@chakra-ui/react"; -import type { ContractData } from "../types"; -import { useGetAddressType } from "lib/app-provider"; +import { useCurrentChain, useGetAddressType } from "lib/app-provider"; import { Copier } from "lib/components/copy"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { LabelText } from "lib/components/LabelText"; -import { Loading } from "lib/components/Loading"; -import type { Option } from "lib/types"; -import { formatUTC, dateFromNow } from "lib/utils"; +import type { Contract, ContractRest } from "lib/services/contract"; +import type { CodeLocalInfo } from "lib/stores/code"; +import type { Nullable, Option } from "lib/types"; +import { formatUTC, dateFromNow, getCw2Info } from "lib/utils"; import { getAddressTypeText } from "lib/utils/address"; interface InstantiateInfoProps { - chainId: ContractData["chainId"]; - codeLocalInfo: ContractData["codeLocalInfo"]; - contractDetail: ContractData["contractDetail"]; - contractCw2Info: ContractData["contractCw2Info"]; - initTxHash: ContractData["initTxHash"]; - initProposalId: ContractData["initProposalId"]; - initProposalTitle: ContractData["initProposalTitle"]; - createdHeight: ContractData["createdHeight"]; - createdTime: ContractData["createdTime"]; - rawContractResponse: ContractData["rawContractResponse"]; - isLoading: boolean; + contract: Contract; + contractRest: Nullable; + codeLocalInfo: Option; } const Container = chakra(Flex, { @@ -60,12 +52,7 @@ const InitRender = ({ initProposalTitle, initProposalId, createdHeight, -}: { - initTxHash: ContractData["initTxHash"]; - initProposalTitle: ContractData["initProposalTitle"]; - initProposalId: ContractData["initProposalId"]; - createdHeight: Option; -}) => { +}: Contract) => { if (initTxHash) { return ( @@ -107,39 +94,18 @@ const InitRender = ({ }; export const InstantiateInfo = ({ - chainId, + contract, + contractRest, codeLocalInfo, - contractDetail, - contractCw2Info, - initTxHash, - initProposalId, - initProposalTitle, - createdHeight, - createdTime, - rawContractResponse, - isLoading, }: InstantiateInfoProps) => { const getAddressType = useGetAddressType(); + const { + chain: { chain_id: chainId }, + } = useCurrentChain(); - if (isLoading) - return ( - - - - ); - - if (!contractDetail) { - return ( - - - Error fetching data - - - ); - } - - const instantiatorType = getAddressType(contractDetail.instantiator); - const adminType = getAddressType(contractDetail.admin); + const instantiatorType = getAddressType(contract.instantiator); + const adminType = getAddressType(contract.admin ?? undefined); + const cw2 = getCw2Info(contract.cw2Contract, contract.cw2Version); return ( @@ -150,7 +116,7 @@ export const InstantiateInfo = ({ @@ -158,9 +124,9 @@ export const InstantiateInfo = ({ - {contractCw2Info ? ( + {cw2 ? ( - {contractCw2Info.contract} ({contractCw2Info.version}) + {cw2} ) : ( @@ -168,7 +134,7 @@ export const InstantiateInfo = ({ )} - {contractDetail.admin ? ( + {contract.admin ? ( @@ -190,23 +156,19 @@ export const InstantiateInfo = ({ )} - {createdHeight !== undefined ? ( - - - - ) : ( - N/A - )} + + + - + - {rawContractResponse?.contract_info.ibc_port_id && ( + {contractRest?.contract_info.ibc_port_id && ( - + )} diff --git a/src/lib/pages/contract-details/components/JsonInfo.tsx b/src/lib/pages/contract-details/components/JsonInfo.tsx index 5b3e85018..f0cd2d87a 100644 --- a/src/lib/pages/contract-details/components/JsonInfo.tsx +++ b/src/lib/pages/contract-details/components/JsonInfo.tsx @@ -3,19 +3,16 @@ import { useState } from "react"; import { CustomIcon } from "lib/components/icon"; import JsonReadOnly from "lib/components/json/JsonReadOnly"; -import { Loading } from "lib/components/Loading"; interface JsonInfoProps { header: string; jsonString: string; - isLoading: boolean; defaultExpand?: boolean; } export const JsonInfo = ({ header, jsonString, - isLoading, defaultExpand = false, }: JsonInfoProps) => { const [expand, setExpand] = useState(defaultExpand); @@ -45,11 +42,7 @@ export const JsonInfo = ({
- {isLoading ? ( - - ) : ( - - )} +
); diff --git a/src/lib/pages/contract-details/components/contract-description/UserContractDesc.tsx b/src/lib/pages/contract-details/components/contract-description/UserContractDesc.tsx index 3b0fbb357..60a786236 100644 --- a/src/lib/pages/contract-details/components/contract-description/UserContractDesc.tsx +++ b/src/lib/pages/contract-details/components/contract-description/UserContractDesc.tsx @@ -1,22 +1,24 @@ -import { Box, Button, Flex, Text } from "@chakra-ui/react"; +import { Button, Flex, Text } from "@chakra-ui/react"; import { useMemo, useState } from "react"; import Linkify from "react-linkify"; import { useClampText } from "use-clamp-text"; -import type { ContractData } from "../../types"; import { ShowMoreButton } from "lib/components/button"; import { CustomIcon } from "lib/components/icon"; import { EditContractDetailsModal } from "lib/components/modal"; +import type { Contract } from "lib/services/contract"; +import type { ContractLocalInfo } from "lib/stores/contract"; +import type { Nullable, Option, PublicContractInfo } from "lib/types"; interface UserContractDescProps { - contractDetail: ContractData["contractDetail"]; - contractLocalInfo: ContractData["contractLocalInfo"]; - publicProject: ContractData["publicProject"]; + publicInfo: Nullable; + contract: Contract; + contractLocalInfo: Option; } export const UserContractDesc = ({ - contractDetail, + publicInfo, + contract, contractLocalInfo, - publicProject, }: UserContractDescProps) => { const [showMore, setShowMore] = useState(false); @@ -25,36 +27,9 @@ export const UserContractDesc = ({ const [ref, { noClamp, clampedText, key }] = useClampText({ text: description || "No Contract description", ellipsis: "...", - lines: publicProject.publicInfo?.description ? 4 : 2, + lines: publicInfo?.description ? 4 : 2, }); - const renderEditContractButton = () => { - if (!contractDetail) return null; - return ( - } - > - {description ? "Edit" : "Add Description"} - - } - /> - ); - }; - const displayDescription = useMemo(() => { if (!description) { return "No Contract Description"; @@ -76,9 +51,29 @@ export const UserContractDesc = ({ Your Contract Description - - {renderEditContractButton()} - + } + display="none" + _groupHover={{ display: "flex" }} + > + {description ? "Edit" : "Add Description"} + + } + />
; + contract: Contract; + contractLocalInfo: Option; } export const ContractDesc = ({ - contractDetail, + publicInfo, + contract, contractLocalInfo, - publicProject, }: ContractDescProps) => { const isMobile = useMobile(); @@ -27,19 +29,19 @@ export const ContractDesc = ({ borderBottom={{ base: "0px", md: "1px solid" }} borderBottomColor={{ base: "transparent", md: "gray.700" }} > - {publicProject.publicInfo?.description && ( + {publicInfo?.description && ( } /> )} {!isMobile && ( )} diff --git a/src/lib/pages/contract-details/data.ts b/src/lib/pages/contract-details/data.ts index 10198afa0..2ef987b2d 100644 --- a/src/lib/pages/contract-details/data.ts +++ b/src/lib/pages/contract-details/data.ts @@ -1,99 +1,25 @@ -import { useQuery } from "@tanstack/react-query"; - -import { - CELATONE_QUERY_KEYS, - useBaseApiRoute, - useCelatoneApp, -} from "lib/app-provider"; import { useCodeStore, useContractStore } from "lib/providers/store"; -import { useAssetInfos } from "lib/services/assetService"; -import { useBalances } from "lib/services/balanceService"; -import { queryContract, queryContractCw2Info } from "lib/services/contract"; import { - useContractDetailByContractAddress, - useInstantiateDetailByContractQuery, + useContractDataByContractAddress, useMigrationHistoriesByContractAddress, } from "lib/services/contractService"; -import { - usePublicProjectByContractAddress, - usePublicProjectBySlug, -} from "lib/services/publicProjectService"; import type { ContractAddr, ContractMigrationHistory } from "lib/types"; -import { coinToTokenWithValue, compareTokenWithValues } from "lib/utils"; -import type { ContractData } from "./types"; - -export const useContractData = ( - contractAddress: ContractAddr -): ContractData => { - const { currentChainId } = useCelatoneApp(); +export const useContractData = (contractAddress: ContractAddr) => { const { getCodeLocalInfo } = useCodeStore(); const { getContractLocalInfo } = useContractStore(); - const lcdEndpoint = useBaseApiRoute("rest"); - - const { data: contractDetail, isLoading: isContractDetailLoading } = - useContractDetailByContractAddress(contractAddress); - const { data: assetInfos, isLoading: isAssetInfosLoading } = useAssetInfos({ - withPrices: true, - }); - const { data: contractBalances, isLoading: isContractBalancesLoading } = - useBalances(contractAddress); - const balances = contractBalances - ?.map(({ denom, amount }) => - coinToTokenWithValue(denom, amount, assetInfos) - ) - .sort(compareTokenWithValues); + const result = useContractDataByContractAddress(contractAddress); - const { data: publicInfo } = - usePublicProjectByContractAddress(contractAddress); - const { data: publicInfoBySlug } = usePublicProjectBySlug(publicInfo?.slug); - - const { data: contractCw2Info, isLoading: isContractCw2InfoLoading } = - useQuery( - [CELATONE_QUERY_KEYS.CONTRACT_CW2_INFO, lcdEndpoint, contractAddress], - async () => queryContractCw2Info(lcdEndpoint, contractAddress), - { enabled: Boolean(contractAddress), retry: false } - ); - - const codeLocalInfo = contractDetail - ? getCodeLocalInfo(Number(contractDetail.codeId)) + const codeLocalInfo = result.data?.contract + ? getCodeLocalInfo(Number(result.data.contract.codeId)) : undefined; const contractLocalInfo = getContractLocalInfo(contractAddress); - const { data: instantiateDetail, isLoading: isInstantiateDetailLoading } = - useInstantiateDetailByContractQuery(contractAddress); - - const { data: rawContractResponse, isLoading: isRawContractResponseLoading } = - useQuery( - [CELATONE_QUERY_KEYS.CONTRACT_INFO, lcdEndpoint, contractAddress], - async () => queryContract(lcdEndpoint, contractAddress), - { enabled: Boolean(contractAddress), retry: false } - ); - return { - chainId: currentChainId, codeLocalInfo, contractLocalInfo, - contractDetail, - isContractDetailLoading, - publicProject: { - publicInfo, - publicDetail: publicInfoBySlug?.details, - }, - balances, - isBalancesLoading: isAssetInfosLoading || isContractBalancesLoading, - contractCw2Info, - isContractCw2InfoLoading, - initMsg: instantiateDetail?.initMsg, - initTxHash: instantiateDetail?.initTxHash, - initProposalId: instantiateDetail?.initProposalId, - initProposalTitle: instantiateDetail?.initProposalTitle, - createdHeight: instantiateDetail?.createdHeight, - createdTime: instantiateDetail?.createdTime, - isInstantiateDetailLoading, - rawContractResponse, - isRawContractResponseLoading, + ...result, }; }; diff --git a/src/lib/pages/contract-details/index.tsx b/src/lib/pages/contract-details/index.tsx index 80c5bbb3f..4b0f105fb 100644 --- a/src/lib/pages/contract-details/index.tsx +++ b/src/lib/pages/contract-details/index.tsx @@ -47,13 +47,17 @@ interface ContractDetailsBodyProps { const ContractDetailsBody = observer( ({ contractAddress, tab }: ContractDetailsBodyProps) => { const isMobile = useMobile(); - const router = useRouter(); const navigate = useInternalNavigate(); // ------------------------------------------// // ------------------QUERIES-----------------// // ------------------------------------------// - const contractData = useContractData(contractAddress); + const { + codeLocalInfo, + contractLocalInfo, + data: contractData, + isLoading, + } = useContractData(contractAddress); // ------------------------------------------// // -----------------CALLBACKS----------------// @@ -75,27 +79,20 @@ const ContractDetailsBody = observer( }, [contractAddress, tab, navigate] ); - useEffect(() => { - if (router.isReady && (!tab || !Object.values(TabIndex).includes(tab))) { - navigate({ - replace: true, - pathname: "/contracts/[contractAddress]/[tab]", - query: { - contractAddress, - tab: TabIndex.Overview, - }, - options: { - shallow: true, - }, - }); - } - }, [router.isReady, tab, contractAddress, navigate]); - if (contractData.isContractDetailLoading) return ; - if (!contractData.contractDetail) return ; + if (isLoading) return ; + if (!contractData?.contract) return ; + + const { projectInfo, publicInfo, contract, contractRest } = contractData; return ( <> - + {/* Contract Description Section */} - + {/* Tokens Section */} {/* Instantiate/Contract Info Section */} @@ -157,12 +158,9 @@ const ContractDetailsBody = observer( )}