From adc7c5eac3189b398a5e373e5ea7b3a229f4f2d8 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Tue, 14 May 2024 11:45:42 +0700 Subject: [PATCH 1/9] fix: refactor code by codeid lcd --- src/lib/app-provider/env.ts | 5 +- src/lib/components/modal/code/SaveNewCode.tsx | 62 ++++---- src/lib/components/select-code/CodeSelect.tsx | 17 +-- .../select-code/CodeSelectSection.tsx | 4 +- .../components/code-info/CodeInfoSection.tsx | 4 +- src/lib/pages/instantiate/instantiate.tsx | 24 ++-- src/lib/pages/interact-contract/index.tsx | 8 +- .../migrate/components/MigrateContract.tsx | 24 ++-- src/lib/services/types/wasm/code.ts | 134 ++++++++---------- src/lib/services/wasm/code/index.ts | 26 ++-- src/lib/services/wasm/code/lcd.ts | 16 +-- 11 files changed, 153 insertions(+), 171 deletions(-) diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index ed1d840ed..09c03ec1a 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -10,9 +10,7 @@ export enum CELATONE_QUERY_KEYS { // TABLE ACCOUNT_TABLE_COUNTS = "CELATONE_QUERY_ACCOUNT_TABLE_COUNTS", CONTRACT_TABLE_COUNTS = "CELATONE_QUERY_CONTRACT_TABLE_COUNTS", - // CONTRACT,CODE LCD - CODE_INFO = "CELATONE_QUERY_CODE_INFO", - CODE_INFO_LCD = "CELATONE_QUERY_CODE_INFO_LCD", + // CONTRACT CONTRACT_LCD = "CELATONE_QUERY_CONTRACT_LCD", CONTRACT_QUERY_MSGS = "CELATONE_QUERY_CONTRACT_QUERY_MSGS", CONTRACT_QUERY_LCD = "CELATONE_QUERY_CONTRACT_QUERY_LCD", @@ -34,6 +32,7 @@ export enum CELATONE_QUERY_KEYS { CODES_BY_WALLET_ADDRESS = "CELATONE_QUERY_CODES_BY_WALLET_ADDRESS", CODES_BY_IDS = "CELATONE_QUERY_CODES_BY_IDS", CODE_DATA = "CELATONE_QUERY_CODE_DATA", + CODE_DATA_LCD = "CELATONE_QUERY_CODE_DATA_LCD", // CONTRACT GQL CONTRACTS = "CELATONE_QUERY_CONTRACTS", CONTRACT_DATA = "CELATONE_QUERY_CONTRACT_DATA", diff --git a/src/lib/components/modal/code/SaveNewCode.tsx b/src/lib/components/modal/code/SaveNewCode.tsx index c9ae908f8..888db03be 100644 --- a/src/lib/components/modal/code/SaveNewCode.tsx +++ b/src/lib/components/modal/code/SaveNewCode.tsx @@ -10,9 +10,13 @@ import { NumberInput, TextInput } from "lib/components/forms"; import { CustomIcon } from "lib/components/icon"; import { useGetMaxLengthError } from "lib/hooks"; import { useCodeStore } from "lib/providers/store"; -import { useCodeInfoLcd } from "lib/services/wasm/code"; +import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; import type { BechAddr } from "lib/types"; -import { getNameAndDescriptionDefault, getPermissionHelper } from "lib/utils"; +import { + getNameAndDescriptionDefault, + getPermissionHelper, + isId, +} from "lib/utils"; interface SaveNewCodeModalProps { buttonProps: ButtonProps; @@ -55,30 +59,33 @@ export function SaveNewCodeModal({ buttonProps }: SaveNewCodeModalProps) { const { isCodeIdSaved, saveNewCode, updateCodeInfo, getCodeLocalInfo } = useCodeStore(); - const { refetch, isFetching, isRefetching } = useCodeInfoLcd(codeId, { - enabled: false, - retry: false, - cacheTime: 0, - onSuccess(data) { - const { message, messageColor } = getPermissionHelper( - address, - data.codeInfo.instantiatePermission.permission, - data.codeInfo.instantiatePermission.addresses - ); - setCodeIdStatus({ - state: "success", - message: `${message} (${data.codeInfo.instantiatePermission.permission})`, - messageColor, - }); - setUploader(data.codeInfo.creator); - setUploaderStatus({ state: "success" }); - }, - onError() { - setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); - setUploader("Not Found"); - setUploaderStatus({ state: "error" }); - }, - }); + const { refetch, isFetching, isRefetching } = useCodeByCodeIdLcd( + Number(codeId), + { + enabled: false, + retry: false, + cacheTime: 0, + onSuccess(data) { + const { message, messageColor } = getPermissionHelper( + address, + data.instantiatePermission, + data.permissionAddresses + ); + setCodeIdStatus({ + state: "success", + message: `${message} (${data.instantiatePermission})`, + messageColor, + }); + setUploader(data.uploader); + setUploaderStatus({ state: "success" }); + }, + onError() { + setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); + setUploader("Not Found"); + setUploaderStatus({ state: "error" }); + }, + } + ); /* CALLBACK */ const reset = () => { @@ -132,7 +139,8 @@ export function SaveNewCodeModal({ buttonProps }: SaveNewCodeModalProps) { }); } else { const timer = setTimeout(() => { - refetch(); + if (isId(codeId)) refetch(); + else setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); }, 500); return () => clearTimeout(timer); diff --git a/src/lib/components/select-code/CodeSelect.tsx b/src/lib/components/select-code/CodeSelect.tsx index 4c9b9ae98..d90a1936c 100644 --- a/src/lib/components/select-code/CodeSelect.tsx +++ b/src/lib/components/select-code/CodeSelect.tsx @@ -6,8 +6,8 @@ import { PermissionChip } from "../PermissionChip"; import type { FormStatus } from "lib/components/forms"; import { UploadIcon } from "lib/components/icon"; import { useCodeStore } from "lib/providers/store"; -import type { CodeInfoResponseLcd } from "lib/services/types"; -import { useCodeInfoLcd } from "lib/services/wasm/code"; +import type { Code } from "lib/services/types"; +import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; import { AccessConfigPermission } from "lib/types"; import { isId } from "lib/utils"; @@ -15,7 +15,7 @@ import { CodeSelectDrawerButton } from "./CodeSelectDrawerButton"; interface CodeSelectProps extends Omit { onCodeSelect: (code: string) => void; - setCodeHash: (data: CodeInfoResponseLcd) => void; + setCodeHash: (data: Code) => void; codeId: string; status: FormStatus; } @@ -29,9 +29,9 @@ export const CodeSelect = ({ }: CodeSelectProps) => { const { getCodeLocalInfo } = useCodeStore(); const name = getCodeLocalInfo(Number(codeId))?.name; - const { data: codeInfo } = useCodeInfoLcd(codeId, { - onSuccess: setCodeHash, + const { data } = useCodeByCodeIdLcd(Number(codeId), { enabled: isId(codeId), + onSuccess: setCodeHash, }); const isError = status.state === "error"; @@ -66,12 +66,9 @@ export const CodeSelect = ({ diff --git a/src/lib/components/select-code/CodeSelectSection.tsx b/src/lib/components/select-code/CodeSelectSection.tsx index 62059459e..7704cf137 100644 --- a/src/lib/components/select-code/CodeSelectSection.tsx +++ b/src/lib/components/select-code/CodeSelectSection.tsx @@ -5,7 +5,7 @@ import type { Control, FieldPath, FieldValues } from "react-hook-form"; import { AmpEvent, track } from "lib/amplitude"; import { ControllerInput } from "lib/components/forms"; import type { FormStatus } from "lib/components/forms"; -import type { CodeInfoResponseLcd } from "lib/services/types"; +import type { Code } from "lib/services/types"; import type { Option } from "lib/types"; import { CodeSelect } from "./CodeSelect"; @@ -16,7 +16,7 @@ interface CodeSelectSectionProps { control: Control; error: Option; onCodeSelect: (codeId: string) => void; - setCodeHash: (data: CodeInfoResponseLcd) => void; + setCodeHash: (data: Code) => void; status: FormStatus; } 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 5f6739537..4d024602c 100644 --- a/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx +++ b/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx @@ -33,13 +33,13 @@ const getMethodSpecificRender = ( transaction: Option ): { methodRender: JSX.Element; storedBlockRender: JSX.Element } => { if (proposal) { - const { height, created, proposalId } = proposal; + const { id, height, created } = proposal; return { methodRender: ( diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 6bede5336..3595ab0ab 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -48,8 +48,8 @@ import { UserDocsLink } from "lib/components/UserDocsLink"; import WasmPageContainer from "lib/components/WasmPageContainer"; import { useTxBroadcast } from "lib/hooks"; import { useSchemaStore } from "lib/providers/store"; -import type { CodeInfoResponseLcd } from "lib/services/types"; -import { useCodeInfoLcd } from "lib/services/wasm/code"; +import type { Code } from "lib/services/types"; +import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; import type { BechAddr, BechAddr20, ComposedMsg } from "lib/types"; import { MsgType } from "lib/types"; import { @@ -193,15 +193,18 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { }, }); - const { refetch } = useCodeInfoLcd(codeId, { + const { refetch } = useCodeByCodeIdLcd(Number(codeId), { enabled: false, retry: false, cacheTime: 0, onSuccess(data) { - const permission = data.codeInfo.instantiatePermission; - setValue("codeHash", data.codeInfo.dataHash.toLowerCase()); + setValue("codeHash", data.hash.toLowerCase()); if ( - resolvePermission(address, permission.permission, permission.addresses) + resolvePermission( + address, + data.instantiatePermission, + data.permissionAddresses + ) ) setStatus({ state: "success" }); else { @@ -323,7 +326,8 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { if (codeId.length) { setStatus({ state: "loading" }); const timer = setTimeout(() => { - refetch(); + if (isId(codeId)) refetch(); + else setStatus({ state: "error", message: "Invalid Code ID" }); }, 500); return () => clearTimeout(timer); } @@ -412,9 +416,9 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { setValue("codeId", code); resetMsgInputSchema(); }} - setCodeHash={(data: CodeInfoResponseLcd) => { - setValue("codeHash", data.codeInfo.dataHash.toLowerCase()); - }} + setCodeHash={(data: Code) => + setValue("codeHash", data.hash.toLowerCase()) + } codeId={codeId} />
diff --git a/src/lib/pages/interact-contract/index.tsx b/src/lib/pages/interact-contract/index.tsx index 90bfe4bff..85c8ff458 100644 --- a/src/lib/pages/interact-contract/index.tsx +++ b/src/lib/pages/interact-contract/index.tsx @@ -13,7 +13,7 @@ import { ContractSelectSection } from "lib/components/ContractSelectSection"; import PageContainer from "lib/components/PageContainer"; import { InvalidState } from "lib/components/state"; import { UserDocsLink } from "lib/components/UserDocsLink"; -import { useCodeInfoLcd } from "lib/services/wasm/code"; +import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; import type { BechAddr32, Coin } from "lib/types"; import { ContractInteractionTabs } from "lib/types"; import { jsonPrettify, jsonValidate, libDecode } from "lib/utils"; @@ -48,7 +48,7 @@ const InteractContractBody = ({ // ------------------------------------------// // ---------------DEPENDENCIES---------------// // ------------------------------------------// - const { data: code } = useCodeInfoLcd(codeId?.toString() ?? "", { + const { data: code } = useCodeByCodeIdLcd(codeId ?? 0, { enabled: !isUndefined(codeId), }); @@ -153,7 +153,7 @@ const InteractContractBody = ({ contractAddress={contractAddress} initialMsg={initialMsg} codeId={codeId} - codeHash={code?.codeInfo.dataHash} + codeHash={code?.hash} /> } executeContent={ @@ -162,7 +162,7 @@ const InteractContractBody = ({ initialMsg={initialMsg} initialFunds={initialFunds} codeId={codeId} - codeHash={code?.codeInfo.dataHash} + codeHash={code?.hash} /> } /> diff --git a/src/lib/pages/migrate/components/MigrateContract.tsx b/src/lib/pages/migrate/components/MigrateContract.tsx index 023c33efd..fb433fb07 100644 --- a/src/lib/pages/migrate/components/MigrateContract.tsx +++ b/src/lib/pages/migrate/components/MigrateContract.tsx @@ -27,8 +27,8 @@ import { import { CodeSelectSection } from "lib/components/select-code"; import { useTxBroadcast } from "lib/hooks"; import { useSchemaStore } from "lib/providers/store"; -import type { CodeInfoResponseLcd } from "lib/services/types"; -import { useCodeInfoLcd } from "lib/services/wasm/code"; +import type { Code } from "lib/services/types"; +import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; import type { BechAddr32, ComposedMsg } from "lib/types"; import { MsgType } from "lib/types"; import { composeMsg, isId, jsonValidate, resolvePermission } from "lib/utils"; @@ -120,15 +120,18 @@ export const MigrateContract = ({ }, }); - const { refetch } = useCodeInfoLcd(codeId, { + const { refetch } = useCodeByCodeIdLcd(Number(codeId), { enabled: false, retry: false, cacheTime: 0, onSuccess(data) { - const permission = data.codeInfo.instantiatePermission; - setValue("codeHash", data.codeInfo.dataHash.toLowerCase()); + setValue("codeHash", data.hash.toLowerCase()); if ( - resolvePermission(address, permission.permission, permission.addresses) + resolvePermission( + address, + data.instantiatePermission, + data.permissionAddresses + ) ) setStatus({ state: "success" }); else { @@ -199,7 +202,8 @@ export const MigrateContract = ({ if (codeId.length) { setStatus({ state: "loading" }); const timer = setTimeout(() => { - refetch(); + if (isId(codeId)) refetch(); + else setStatus({ state: "error", message: "Invalid Code ID" }); }, 500); return () => clearTimeout(timer); } @@ -251,9 +255,9 @@ export const MigrateContract = ({ setValue("codeId", code); resetMsgInputSchema(); }} - setCodeHash={(data: CodeInfoResponseLcd) => { - setValue("codeHash", data.codeInfo.dataHash.toLowerCase()); - }} + setCodeHash={(data: Code) => + setValue("codeHash", data.hash.toLowerCase()) + } codeId={codeId} /> diff --git a/src/lib/services/types/wasm/code.ts b/src/lib/services/types/wasm/code.ts index 719f7d282..c2a7d9201 100644 --- a/src/lib/services/types/wasm/code.ts +++ b/src/lib/services/types/wasm/code.ts @@ -7,36 +7,35 @@ import { zPagination, zProjectInfo, zPublicCodeInfo, + zUtcDate, } from "lib/types"; -import { parseDate, parseTxHash, snakeToCamel } from "lib/utils"; +import { parseTxHash, snakeToCamel } from "lib/utils"; -export const zCodeInfoResponseLcd = z +const zCodesResponseItem = z .object({ - code_info: z.object({ - code_id: z.string(), - creator: zBechAddr, - data_hash: z.string(), - instantiate_permission: z.object({ - permission: z.nativeEnum(AccessConfigPermission), - address: zBechAddr.optional(), - addresses: z.array(zBechAddr).default([]), - }), - }), + id: z.number().nonnegative(), + cw2_contract: z.string().nullable(), + cw2_version: z.string().nullable(), + uploader: zBechAddr, + contract_count: z.number().nonnegative(), + instantiate_permission: z.nativeEnum(AccessConfigPermission), + permission_addresses: z.array(zBechAddr), }) - .transform(({ code_info: { instantiate_permission, ...rest } }) => ({ - codeInfo: { - ...snakeToCamel(rest), - instantiatePermission: { - permission: instantiate_permission.permission, - addresses: - instantiate_permission.address && - instantiate_permission.address !== "" - ? [instantiate_permission.address] - : instantiate_permission.addresses, - }, - }, + .transform((val) => ({ + id: val.id, + cw2Contract: val.cw2_contract, + cw2Version: val.cw2_version, + uploader: val.uploader, + contractCount: val.contract_count, + instantiatePermission: val.instantiate_permission, + permissionAddresses: val.permission_addresses, })); -export type CodeInfoResponseLcd = z.infer; + +export const zCodesResponse = z.object({ + items: z.array(zCodesResponseItem), + total: z.number().nonnegative(), +}); +export type CodesResponse = z.infer; const zCodesResponseItemLcd = z .object({ @@ -61,33 +60,6 @@ export const zCodesResponseLcd = z.object({ code_infos: z.array(zCodesResponseItemLcd), pagination: zPagination, }); -export type CodesResponseLcd = z.infer; - -const zCodesResponseItem = z - .object({ - id: z.number().nonnegative(), - cw2_contract: z.string().nullable(), - cw2_version: z.string().nullable(), - uploader: zBechAddr, - contract_count: z.number().nonnegative(), - instantiate_permission: z.nativeEnum(AccessConfigPermission), - permission_addresses: z.array(zBechAddr), - }) - .transform((val) => ({ - id: val.id, - cw2Contract: val.cw2_contract, - cw2Version: val.cw2_version, - uploader: val.uploader, - contractCount: val.contract_count, - instantiatePermission: val.instantiate_permission, - permissionAddresses: val.permission_addresses, - })); - -export const zCodesResponse = z.object({ - items: z.array(zCodesResponseItem), - total: z.number().nonnegative(), -}); -export type CodesResponse = z.infer; const zCode = z .object({ @@ -101,42 +73,22 @@ const zCode = z .object({ id: z.number().positive(), height: z.number().positive(), - created: z.string(), + created: zUtcDate, }) .nullable(), transaction: z .object({ height: z.number(), hash: z.string(), - created: z.string(), + created: zUtcDate, }) .nullable(), uploader: zBechAddr, }) .transform((val) => ({ - codeId: val.code_id, - cw2Contract: val.cw2_contract, - cw2Version: val.cw2_version, + ...snakeToCamel(val), hash: parseTxHash(val.hash), - instantiatePermission: val.instantiate_permission, - permissionAddresses: val.permission_addresses, - proposal: val.proposal - ? { - proposalId: val.proposal.id, - height: val.proposal.height, - created: parseDate(val.proposal.created), - } - : undefined, - transaction: val.transaction - ? { - height: val.transaction.height, - hash: parseTxHash(val.transaction.hash), - created: parseDate(val.transaction.created), - } - : undefined, - uploader: val.uploader, })); - export type Code = z.infer; export const zCodeData = z @@ -147,3 +99,35 @@ export const zCodeData = z }) .transform(snakeToCamel); export type CodeData = z.infer; + +export const zCodeInfoResponseLcd = z + .object({ + code_info: z.object({ + code_id: z.coerce.number(), + creator: zBechAddr, + data_hash: z.string(), + instantiate_permission: z.object({ + permission: z.nativeEnum(AccessConfigPermission), + address: zBechAddr.optional(), + addresses: z.array(zBechAddr).default([]), + }), + }), + }) + .transform( + ({ + code_info: { code_id, creator, data_hash, instantiate_permission }, + }) => ({ + codeId: code_id, + cw2Contract: null, + cw2Version: null, + hash: parseTxHash(data_hash), + instantiatePermission: instantiate_permission.permission, + permissionAddresses: + instantiate_permission.address && instantiate_permission.address !== "" + ? [instantiate_permission.address] + : instantiate_permission.addresses, + proposal: null, + transaction: null, + uploader: creator, + }) + ); diff --git a/src/lib/services/wasm/code/index.ts b/src/lib/services/wasm/code/index.ts index 9a58131fa..d38467588 100644 --- a/src/lib/services/wasm/code/index.ts +++ b/src/lib/services/wasm/code/index.ts @@ -7,16 +7,11 @@ import { useGovConfig, useLcdEndpoint, } from "lib/app-provider"; -import type { - CodeData, - CodeInfoResponseLcd, - CodesResponse, -} from "lib/services/types"; +import type { Code, CodeData, CodesResponse } from "lib/services/types"; import type { BechAddr, BechAddr20, Option } from "lib/types"; -import { isId } from "lib/utils"; import { getCodeDataByCodeId, getCodes, getCodesByAddress } from "./api"; -import { getCodeIdInfoLcd, getCodesLcd } from "./lcd"; +import { getCodeByCodeIdLcd, getCodesLcd } from "./lcd"; export const useCodes = ( limit: number, @@ -62,20 +57,15 @@ export const useCodeDataByCodeId = (codeId: number, enabled = true) => { ); }; -export const useCodeInfoLcd = ( - codeId: string, - options?: Omit, "queryKey"> +export const useCodeByCodeIdLcd = ( + codeId: number, + options?: Omit, "queryKey"> ) => { const endpoint = useBaseApiRoute("rest"); - const queryFn = async () => { - if (!isId(codeId)) throw new Error("Invalid code ID"); - return getCodeIdInfoLcd(endpoint, Number(codeId)); - }; - - return useQuery( - [CELATONE_QUERY_KEYS.CODE_INFO_LCD, endpoint, codeId], - queryFn, + return useQuery( + [CELATONE_QUERY_KEYS.CODE_DATA_LCD, endpoint, codeId], + async () => getCodeByCodeIdLcd(endpoint, codeId), options ); }; diff --git a/src/lib/services/wasm/code/lcd.ts b/src/lib/services/wasm/code/lcd.ts index 0706b17ce..0995aab94 100644 --- a/src/lib/services/wasm/code/lcd.ts +++ b/src/lib/services/wasm/code/lcd.ts @@ -1,22 +1,13 @@ import axios from "axios"; -import type { CodeInfoResponseLcd, CodesResponseLcd } from "lib/services/types"; import { zCodeInfoResponseLcd, zCodesResponseLcd } from "lib/services/types"; import type { Option } from "lib/types"; import { parseWithError } from "lib/utils"; -export const getCodeIdInfoLcd = async ( - endpoint: string, - id: number -): Promise => - axios - .get(`${endpoint}/cosmwasm/wasm/v1/code/${id}`) - .then(({ data }) => parseWithError(zCodeInfoResponseLcd, data)); - export const getCodesLcd = async ( endpoint: string, paginationKey: Option -): Promise => +) => axios .get(`${endpoint}/cosmwasm/wasm/v1/code`, { params: { @@ -26,3 +17,8 @@ export const getCodesLcd = async ( }, }) .then(({ data }) => parseWithError(zCodesResponseLcd, data)); + +export const getCodeByCodeIdLcd = async (endpoint: string, codeId: number) => + axios + .get(`${endpoint}/cosmwasm/wasm/v1/code/${codeId}`) + .then(({ data }) => parseWithError(zCodeInfoResponseLcd, data)); From 77f423503459005a3fa3a44a0bd3bcf6effdd7c5 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 15 May 2024 11:22:12 +0700 Subject: [PATCH 2/9] fix: add code lcd services --- CHANGELOG.md | 1 + src/lib/components/modal/code/SaveNewCode.tsx | 53 +++++++++---------- src/lib/components/select-code/CodeSelect.tsx | 4 +- src/lib/pages/code-details/index.tsx | 4 +- src/lib/pages/instantiate/instantiate.tsx | 4 +- src/lib/pages/interact-contract/index.tsx | 4 +- .../migrate/components/MigrateContract.tsx | 4 +- src/lib/services/searchService.ts | 4 +- src/lib/services/wasm/code/api.ts | 2 +- src/lib/services/wasm/code/index.ts | 12 ++--- src/lib/services/wasm/code/lcd.ts | 2 +- 11 files changed, 46 insertions(+), 48 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bc2bea634..953d94faa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#929](https://github.com/alleslabs/celatone-frontend/pull/929) Support lite version for code details page - [#925](https://github.com/alleslabs/celatone-frontend/pull/925) Move contracts service to new folder structure - [#919](https://github.com/alleslabs/celatone-frontend/pull/919) Remove singleStakingDenom config and use from lcd instead - [#918](https://github.com/alleslabs/celatone-frontend/pull/918) Support lite version for delegation informations diff --git a/src/lib/components/modal/code/SaveNewCode.tsx b/src/lib/components/modal/code/SaveNewCode.tsx index 888db03be..ca0c79b76 100644 --- a/src/lib/components/modal/code/SaveNewCode.tsx +++ b/src/lib/components/modal/code/SaveNewCode.tsx @@ -10,7 +10,7 @@ import { NumberInput, TextInput } from "lib/components/forms"; import { CustomIcon } from "lib/components/icon"; import { useGetMaxLengthError } from "lib/hooks"; import { useCodeStore } from "lib/providers/store"; -import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; +import { useCodeLcd } from "lib/services/wasm/code"; import type { BechAddr } from "lib/types"; import { getNameAndDescriptionDefault, @@ -59,33 +59,30 @@ export function SaveNewCodeModal({ buttonProps }: SaveNewCodeModalProps) { const { isCodeIdSaved, saveNewCode, updateCodeInfo, getCodeLocalInfo } = useCodeStore(); - const { refetch, isFetching, isRefetching } = useCodeByCodeIdLcd( - Number(codeId), - { - enabled: false, - retry: false, - cacheTime: 0, - onSuccess(data) { - const { message, messageColor } = getPermissionHelper( - address, - data.instantiatePermission, - data.permissionAddresses - ); - setCodeIdStatus({ - state: "success", - message: `${message} (${data.instantiatePermission})`, - messageColor, - }); - setUploader(data.uploader); - setUploaderStatus({ state: "success" }); - }, - onError() { - setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); - setUploader("Not Found"); - setUploaderStatus({ state: "error" }); - }, - } - ); + const { refetch, isFetching, isRefetching } = useCodeLcd(Number(codeId), { + enabled: false, + retry: false, + cacheTime: 0, + onSuccess(data) { + const { message, messageColor } = getPermissionHelper( + address, + data.instantiatePermission, + data.permissionAddresses + ); + setCodeIdStatus({ + state: "success", + message: `${message} (${data.instantiatePermission})`, + messageColor, + }); + setUploader(data.uploader); + 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/components/select-code/CodeSelect.tsx b/src/lib/components/select-code/CodeSelect.tsx index d90a1936c..55267502a 100644 --- a/src/lib/components/select-code/CodeSelect.tsx +++ b/src/lib/components/select-code/CodeSelect.tsx @@ -7,7 +7,7 @@ import type { FormStatus } from "lib/components/forms"; import { UploadIcon } from "lib/components/icon"; import { useCodeStore } from "lib/providers/store"; import type { Code } from "lib/services/types"; -import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; +import { useCodeLcd } from "lib/services/wasm/code"; import { AccessConfigPermission } from "lib/types"; import { isId } from "lib/utils"; @@ -29,7 +29,7 @@ export const CodeSelect = ({ }: CodeSelectProps) => { const { getCodeLocalInfo } = useCodeStore(); const name = getCodeLocalInfo(Number(codeId))?.name; - const { data } = useCodeByCodeIdLcd(Number(codeId), { + const { data } = useCodeLcd(Number(codeId), { enabled: isId(codeId), onSuccess: setCodeHash, }); diff --git a/src/lib/pages/code-details/index.tsx b/src/lib/pages/code-details/index.tsx index 0175316f2..d0598126f 100644 --- a/src/lib/pages/code-details/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -16,7 +16,7 @@ import PageContainer from "lib/components/PageContainer"; import { ErrorFetching, InvalidState } from "lib/components/state"; import { UserDocsLink } from "lib/components/UserDocsLink"; import { useSchemaStore } from "lib/providers/store"; -import { useCodeDataByCodeId } from "lib/services/wasm/code"; +import { useCodeData } from "lib/services/wasm/code"; import { CodeContractsTable, CodeInfoSection } from "./components/code-info"; import { CodeTopInfo } from "./components/code-info/CodeTopInfo"; @@ -40,7 +40,7 @@ const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { const { getSchemaByCodeHash } = useSchemaStore(); const { currentChainId } = useCelatoneApp(); - const { data, isLoading } = useCodeDataByCodeId(codeId); + const { data, isLoading } = useCodeData(codeId); useEffect(() => { if (router.isReady) track(AmpEvent.TO_CODE_DETAILS, { tab }); diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 3595ab0ab..6562c27b4 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -49,7 +49,7 @@ import WasmPageContainer from "lib/components/WasmPageContainer"; import { useTxBroadcast } from "lib/hooks"; import { useSchemaStore } from "lib/providers/store"; import type { Code } from "lib/services/types"; -import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; +import { useCodeLcd } from "lib/services/wasm/code"; import type { BechAddr, BechAddr20, ComposedMsg } from "lib/types"; import { MsgType } from "lib/types"; import { @@ -193,7 +193,7 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { }, }); - const { refetch } = useCodeByCodeIdLcd(Number(codeId), { + const { refetch } = useCodeLcd(Number(codeId), { enabled: false, retry: false, cacheTime: 0, diff --git a/src/lib/pages/interact-contract/index.tsx b/src/lib/pages/interact-contract/index.tsx index 85c8ff458..8a2b9019b 100644 --- a/src/lib/pages/interact-contract/index.tsx +++ b/src/lib/pages/interact-contract/index.tsx @@ -13,7 +13,7 @@ import { ContractSelectSection } from "lib/components/ContractSelectSection"; import PageContainer from "lib/components/PageContainer"; import { InvalidState } from "lib/components/state"; import { UserDocsLink } from "lib/components/UserDocsLink"; -import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; +import { useCodeLcd } from "lib/services/wasm/code"; import type { BechAddr32, Coin } from "lib/types"; import { ContractInteractionTabs } from "lib/types"; import { jsonPrettify, jsonValidate, libDecode } from "lib/utils"; @@ -48,7 +48,7 @@ const InteractContractBody = ({ // ------------------------------------------// // ---------------DEPENDENCIES---------------// // ------------------------------------------// - const { data: code } = useCodeByCodeIdLcd(codeId ?? 0, { + const { data: code } = useCodeLcd(codeId ?? 0, { enabled: !isUndefined(codeId), }); diff --git a/src/lib/pages/migrate/components/MigrateContract.tsx b/src/lib/pages/migrate/components/MigrateContract.tsx index fb433fb07..a40bcf74a 100644 --- a/src/lib/pages/migrate/components/MigrateContract.tsx +++ b/src/lib/pages/migrate/components/MigrateContract.tsx @@ -28,7 +28,7 @@ import { CodeSelectSection } from "lib/components/select-code"; import { useTxBroadcast } from "lib/hooks"; import { useSchemaStore } from "lib/providers/store"; import type { Code } from "lib/services/types"; -import { useCodeByCodeIdLcd } from "lib/services/wasm/code"; +import { useCodeLcd } from "lib/services/wasm/code"; import type { BechAddr32, ComposedMsg } from "lib/types"; import { MsgType } from "lib/types"; import { composeMsg, isId, jsonValidate, resolvePermission } from "lib/utils"; @@ -120,7 +120,7 @@ export const MigrateContract = ({ }, }); - const { refetch } = useCodeByCodeIdLcd(Number(codeId), { + const { refetch } = useCodeLcd(Number(codeId), { enabled: false, retry: false, cacheTime: 0, diff --git a/src/lib/services/searchService.ts b/src/lib/services/searchService.ts index 83baea950..e86d3948f 100644 --- a/src/lib/services/searchService.ts +++ b/src/lib/services/searchService.ts @@ -24,7 +24,7 @@ import { usePoolByPoolId } from "./poolService"; import { useProposalData } from "./proposalService"; import { useTxData } from "./tx"; import { useValidatorData } from "./validator"; -import { useCodeDataByCodeId } from "./wasm/code"; +import { useCodeData } from "./wasm/code"; import { useContractLcd } from "./wasm/contract"; export type SearchResultType = @@ -117,7 +117,7 @@ export const useSearchHandler = ( }, [isAddr, contractData, icnsAddressData]); // Code - const { data: codeData, isFetching: codeFetching } = useCodeDataByCodeId( + const { data: codeData, isFetching: codeFetching } = useCodeData( Number(debouncedKeyword), isWasm && isId(debouncedKeyword) ); diff --git a/src/lib/services/wasm/code/api.ts b/src/lib/services/wasm/code/api.ts index 7dfbf986e..1ff3fd76a 100644 --- a/src/lib/services/wasm/code/api.ts +++ b/src/lib/services/wasm/code/api.ts @@ -38,7 +38,7 @@ export const getCodesByAddress = async ( }) .then(({ data }) => zCodesResponse.parse(data)); -export const getCodeDataByCodeId = async ( +export const getCodeData = async ( endpoint: string, codeId: number, isGov: boolean diff --git a/src/lib/services/wasm/code/index.ts b/src/lib/services/wasm/code/index.ts index d38467588..e62f50b62 100644 --- a/src/lib/services/wasm/code/index.ts +++ b/src/lib/services/wasm/code/index.ts @@ -10,8 +10,8 @@ import { import type { Code, CodeData, CodesResponse } from "lib/services/types"; import type { BechAddr, BechAddr20, Option } from "lib/types"; -import { getCodeDataByCodeId, getCodes, getCodesByAddress } from "./api"; -import { getCodeByCodeIdLcd, getCodesLcd } from "./lcd"; +import { getCodeData, getCodes, getCodesByAddress } from "./api"; +import { getCodeLcd, getCodesLcd } from "./lcd"; export const useCodes = ( limit: number, @@ -42,13 +42,13 @@ export const useCodesLcd = () => { ); }; -export const useCodeDataByCodeId = (codeId: number, enabled = true) => { +export const useCodeData = (codeId: number, enabled = true) => { const { enabled: isGov } = useGovConfig({ shouldRedirect: false }); const endpoint = useBaseApiRoute("codes"); return useQuery( [CELATONE_QUERY_KEYS.CODE_DATA, endpoint, codeId, isGov], - async () => getCodeDataByCodeId(endpoint, codeId, isGov), + async () => getCodeData(endpoint, codeId, isGov), { retry: 1, refetchOnWindowFocus: false, @@ -57,7 +57,7 @@ export const useCodeDataByCodeId = (codeId: number, enabled = true) => { ); }; -export const useCodeByCodeIdLcd = ( +export const useCodeLcd = ( codeId: number, options?: Omit, "queryKey"> ) => { @@ -65,7 +65,7 @@ export const useCodeByCodeIdLcd = ( return useQuery( [CELATONE_QUERY_KEYS.CODE_DATA_LCD, endpoint, codeId], - async () => getCodeByCodeIdLcd(endpoint, codeId), + async () => getCodeLcd(endpoint, codeId), options ); }; diff --git a/src/lib/services/wasm/code/lcd.ts b/src/lib/services/wasm/code/lcd.ts index 0995aab94..a4ab515fa 100644 --- a/src/lib/services/wasm/code/lcd.ts +++ b/src/lib/services/wasm/code/lcd.ts @@ -18,7 +18,7 @@ export const getCodesLcd = async ( }) .then(({ data }) => parseWithError(zCodesResponseLcd, data)); -export const getCodeByCodeIdLcd = async (endpoint: string, codeId: number) => +export const getCodeLcd = async (endpoint: string, codeId: number) => axios .get(`${endpoint}/cosmwasm/wasm/v1/code/${codeId}`) .then(({ data }) => parseWithError(zCodeInfoResponseLcd, data)); From 7a1b79c2d695d40c8d6a701b0b430dbb82dbb4aa Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 15 May 2024 15:02:13 +0700 Subject: [PATCH 3/9] fix: code detail top --- src/lib/components/LabelText.tsx | 2 +- src/lib/components/modal/code/SaveNewCode.tsx | 4 +- .../code-info/CodeInfoLabelText.tsx | 14 ++++ .../components/code-info/CodeInfoSection.tsx | 67 ++++++++++--------- .../components/code-info/CodeTopInfo.tsx | 34 +++++----- src/lib/pages/code-details/data.ts | 18 +++++ src/lib/pages/code-details/index.tsx | 19 ++++-- src/lib/pages/instantiate/instantiate.tsx | 4 +- .../migrate/components/MigrateContract.tsx | 4 +- src/lib/services/searchService.ts | 8 ++- src/lib/services/types/wasm/code.ts | 2 +- src/lib/services/wasm/code/index.ts | 8 ++- 12 files changed, 116 insertions(+), 68 deletions(-) create mode 100644 src/lib/pages/code-details/components/code-info/CodeInfoLabelText.tsx diff --git a/src/lib/components/LabelText.tsx b/src/lib/components/LabelText.tsx index 4817f71cd..84624790f 100644 --- a/src/lib/components/LabelText.tsx +++ b/src/lib/components/LabelText.tsx @@ -3,7 +3,7 @@ import { Flex, Text } from "@chakra-ui/react"; import { TooltipInfo } from "./Tooltip"; -interface LabelTextProps extends FlexProps { +export interface LabelTextProps extends FlexProps { label: string; labelWeight?: number; labelColor?: string; diff --git a/src/lib/components/modal/code/SaveNewCode.tsx b/src/lib/components/modal/code/SaveNewCode.tsx index ca0c79b76..4f7b8e121 100644 --- a/src/lib/components/modal/code/SaveNewCode.tsx +++ b/src/lib/components/modal/code/SaveNewCode.tsx @@ -63,7 +63,7 @@ export function SaveNewCodeModal({ buttonProps }: SaveNewCodeModalProps) { enabled: false, retry: false, cacheTime: 0, - onSuccess(data) { + onSuccess: (data) => { const { message, messageColor } = getPermissionHelper( address, data.instantiatePermission, @@ -77,7 +77,7 @@ export function SaveNewCodeModal({ buttonProps }: SaveNewCodeModalProps) { setUploader(data.uploader); setUploaderStatus({ state: "success" }); }, - onError() { + onError: () => { setCodeIdStatus({ state: "error", message: "Invalid Code ID" }); setUploader("Not Found"); setUploaderStatus({ state: "error" }); diff --git a/src/lib/pages/code-details/components/code-info/CodeInfoLabelText.tsx b/src/lib/pages/code-details/components/code-info/CodeInfoLabelText.tsx new file mode 100644 index 000000000..69d02871f --- /dev/null +++ b/src/lib/pages/code-details/components/code-info/CodeInfoLabelText.tsx @@ -0,0 +1,14 @@ +import { useTierConfig } from "lib/app-provider"; +import type { LabelTextProps } from "lib/components/LabelText"; +import { LabelText } from "lib/components/LabelText"; + +export const CodeInfoLabelText = (props: LabelTextProps) => { + const isFullTier = useTierConfig() === "full"; + return ( + + ); +}; 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 4d024602c..f2d1f51d0 100644 --- a/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx +++ b/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx @@ -2,7 +2,6 @@ import { Box, Button, Flex, - Grid, Heading, Text, useDisclosure, @@ -10,17 +9,18 @@ import { import { useCallback } from "react"; import { AmpEvent, track } from "lib/amplitude"; -import { useGetAddressType, useMobile } from "lib/app-provider"; +import { useGetAddressType, useMobile, useTierConfig } from "lib/app-provider"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { CustomIcon } from "lib/components/icon"; import { JsonSchemaModal } from "lib/components/json-schema"; -import { LabelText } from "lib/components/LabelText"; import { PermissionChip } from "lib/components/PermissionChip"; import { ViewPermissionAddresses } from "lib/components/ViewPermissionAddresses"; import type { Code } from "lib/services/types"; import type { Option } from "lib/types"; import { dateFromNow, formatUTC, getAddressTypeText } from "lib/utils"; +import { CodeInfoLabelText } from "./CodeInfoLabelText"; + interface CodeInfoSectionProps { code: Code; chainId: string; @@ -36,13 +36,13 @@ const getMethodSpecificRender = ( const { id, height, created } = proposal; return { methodRender: ( - + - + ), storedBlockRender: height && created ? ( @@ -69,9 +69,9 @@ const getMethodSpecificRender = ( const { hash, height, created } = transaction; return { methodRender: ( - + - + ), storedBlockRender: height && created ? ( @@ -100,7 +100,7 @@ const getMethodSpecificRender = ( * @todo Add genesis conditioning when the view table is available */ return { - methodRender: N/A, + methodRender: N/A, storedBlockRender: N/A, }; }; @@ -111,6 +111,8 @@ export const CodeInfoSection = ({ attached, toJsonSchemaTab, }: CodeInfoSectionProps) => { + const isFullTier = useTierConfig() === "full"; + const { isOpen, onClose, onOpen } = useDisclosure(); const getAddressType = useGetAddressType(); const { @@ -145,16 +147,9 @@ export const CodeInfoSection = ({ Code Info - - {chainId} - + + {chainId} + - - {methodRender} - + + {isFullTier && methodRender} + - - - - {storedBlockRender} - - + + {isFullTier && ( + + + {storedBlockRender} + + + )} {!isMobile && ( - +
-
+ )} -
+
); }; diff --git a/src/lib/pages/code-details/components/code-info/CodeTopInfo.tsx b/src/lib/pages/code-details/components/code-info/CodeTopInfo.tsx index f12421b47..a7ccc42dd 100644 --- a/src/lib/pages/code-details/components/code-info/CodeTopInfo.tsx +++ b/src/lib/pages/code-details/components/code-info/CodeTopInfo.tsx @@ -1,7 +1,7 @@ import { Flex, Heading, Image, Text } from "@chakra-ui/react"; import { CTASection } from "../CTASection"; -import { useMobile } from "lib/app-provider"; +import { useMobile, useTierConfig } from "lib/app-provider"; import { Breadcrumb } from "lib/components/Breadcrumb"; import { CopyLink } from "lib/components/CopyLink"; import { CustomIcon } from "lib/components/icon"; @@ -26,6 +26,8 @@ export const CodeTopInfo = ({ projectInfo, publicInfo, }: CodeTopInfoProps) => { + const isFullTier = useTierConfig() === "full"; + const { getCodeLocalInfo } = useCodeStore(); const localCodeInfo = getCodeLocalInfo(codeId); @@ -109,21 +111,23 @@ export const CodeTopInfo = ({ type="code_hash" /> - - - CW2 Info: - - - {cw2Info ?? "N/A"} - - + + CW2 Info: + + + {cw2Info ?? "N/A"} + + + )} {publicInfo && } diff --git a/src/lib/pages/code-details/data.ts b/src/lib/pages/code-details/data.ts index fed9022aa..16d9febd9 100644 --- a/src/lib/pages/code-details/data.ts +++ b/src/lib/pages/code-details/data.ts @@ -2,9 +2,27 @@ import type { UseQueryOptions } from "@tanstack/react-query"; import { useContractStore } from "lib/providers/store"; import type { ContractsResponse } from "lib/services/types"; +import { useCodeLcd } from "lib/services/wasm/code"; import { useContractsByCodeId } from "lib/services/wasm/contract"; import type { ContractInfo, Option } from "lib/types"; +export const useCodeDataLcd = (codeId: number, enabled: boolean) => { + const { data, isLoading } = useCodeLcd(codeId, { + enabled, + }); + + return { + data: data + ? { + info: data, + projectInfo: null, + publicInfo: null, + } + : undefined, + isLoading, + }; +}; + export const useCodeContracts = ( codeId: number, limit: number, diff --git a/src/lib/pages/code-details/index.tsx b/src/lib/pages/code-details/index.tsx index d0598126f..f9660c921 100644 --- a/src/lib/pages/code-details/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -8,6 +8,7 @@ import { useCelatoneApp, useInternalNavigate, useMobile, + useTierConfig, useWasmConfig, } from "lib/app-provider"; import { CustomTab } from "lib/components/CustomTab"; @@ -21,6 +22,7 @@ import { useCodeData } from "lib/services/wasm/code"; import { CodeContractsTable, CodeInfoSection } from "./components/code-info"; import { CodeTopInfo } from "./components/code-info/CodeTopInfo"; import { CodeSchemaSection } from "./components/json-schema/CodeSchemaSection"; +import { useCodeDataLcd } from "./data"; import { TabIndex, zCodeDetailsQueryParams } from "./types"; const codeTabId = "codeDetailsTab"; @@ -34,18 +36,15 @@ const InvalidCode = () => ; const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { const isMobile = useMobile(); + const isFullTier = useTierConfig() === "full"; - const router = useRouter(); const navigate = useInternalNavigate(); const { getSchemaByCodeHash } = useSchemaStore(); const { currentChainId } = useCelatoneApp(); - const { data, isLoading } = useCodeData(codeId); - - useEffect(() => { - if (router.isReady) track(AmpEvent.TO_CODE_DETAILS, { tab }); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [router.isReady]); + const resApi = useCodeData(codeId, isFullTier); + const resLcd = useCodeDataLcd(codeId, !isFullTier); + const { data, isLoading } = isFullTier ? resApi : resLcd; const handleTabChange = useCallback( (nextTab: TabIndex) => () => { @@ -138,6 +137,12 @@ const CodeDetails = observer(() => { const router = useRouter(); const validated = zCodeDetailsQueryParams.safeParse(router.query); + useEffect(() => { + if (router.isReady && validated.success) + track(AmpEvent.TO_CODE_DETAILS, { tab: validated.data.tab }); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [router.isReady]); + return ( {validated.success ? ( diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 6562c27b4..6c30935cf 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -197,7 +197,7 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { enabled: false, retry: false, cacheTime: 0, - onSuccess(data) { + onSuccess: (data) => { setValue("codeHash", data.hash.toLowerCase()); if ( resolvePermission( @@ -215,7 +215,7 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { }); } }, - onError() { + onError: () => { setStatus({ state: "error", message: "This code ID does not exist" }); setSimulateError(""); }, diff --git a/src/lib/pages/migrate/components/MigrateContract.tsx b/src/lib/pages/migrate/components/MigrateContract.tsx index a40bcf74a..fce3a1530 100644 --- a/src/lib/pages/migrate/components/MigrateContract.tsx +++ b/src/lib/pages/migrate/components/MigrateContract.tsx @@ -124,7 +124,7 @@ export const MigrateContract = ({ enabled: false, retry: false, cacheTime: 0, - onSuccess(data) { + onSuccess: (data) => { setValue("codeHash", data.hash.toLowerCase()); if ( resolvePermission( @@ -143,7 +143,7 @@ export const MigrateContract = ({ setSimulateError(""); } }, - onError() { + onError: () => { setStatus({ state: "error", message: "This code ID does not exist" }); setSimulateError(""); }, diff --git a/src/lib/services/searchService.ts b/src/lib/services/searchService.ts index e86d3948f..353ef8d75 100644 --- a/src/lib/services/searchService.ts +++ b/src/lib/services/searchService.ts @@ -24,7 +24,7 @@ import { usePoolByPoolId } from "./poolService"; import { useProposalData } from "./proposalService"; import { useTxData } from "./tx"; import { useValidatorData } from "./validator"; -import { useCodeData } from "./wasm/code"; +import { useCodeLcd } from "./wasm/code"; import { useContractLcd } from "./wasm/contract"; export type SearchResultType = @@ -117,9 +117,11 @@ export const useSearchHandler = ( }, [isAddr, contractData, icnsAddressData]); // Code - const { data: codeData, isFetching: codeFetching } = useCodeData( + const { data: codeData, isFetching: codeFetching } = useCodeLcd( Number(debouncedKeyword), - isWasm && isId(debouncedKeyword) + { + enabled: isWasm && isId(debouncedKeyword), + } ); // Tx diff --git a/src/lib/services/types/wasm/code.ts b/src/lib/services/types/wasm/code.ts index c2a7d9201..d2468be90 100644 --- a/src/lib/services/types/wasm/code.ts +++ b/src/lib/services/types/wasm/code.ts @@ -79,7 +79,7 @@ const zCode = z transaction: z .object({ height: z.number(), - hash: z.string(), + hash: z.string().transform((val) => parseTxHash(val).toUpperCase()), created: zUtcDate, }) .nullable(), diff --git a/src/lib/services/wasm/code/index.ts b/src/lib/services/wasm/code/index.ts index e62f50b62..b7753a386 100644 --- a/src/lib/services/wasm/code/index.ts +++ b/src/lib/services/wasm/code/index.ts @@ -61,12 +61,16 @@ export const useCodeLcd = ( codeId: number, options?: Omit, "queryKey"> ) => { - const endpoint = useBaseApiRoute("rest"); + const endpoint = useLcdEndpoint(); return useQuery( [CELATONE_QUERY_KEYS.CODE_DATA_LCD, endpoint, codeId], async () => getCodeLcd(endpoint, codeId), - options + { + retry: 1, + refetchOnWindowFocus: false, + ...options, + } ); }; From 82de5d236d01f67e6c447692489fdd0d6d9bc840 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Wed, 15 May 2024 16:24:18 +0700 Subject: [PATCH 4/9] fix: add border --- src/lib/pages/code-details/index.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/pages/code-details/index.tsx b/src/lib/pages/code-details/index.tsx index f9660c921..42d5ddb56 100644 --- a/src/lib/pages/code-details/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -82,7 +82,11 @@ const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { index={Object.values(TabIndex).indexOf(tab)} isLazy lazyBehavior="keepMounted" - my={{ base: 0, md: 8 }} + my={8} + borderTop={{ + base: "1px solid var(--chakra-colors-gray-700)", + md: "none", + }} > {!isMobile && ( Date: Wed, 15 May 2024 16:33:31 +0700 Subject: [PATCH 5/9] fix: reorder query key --- src/lib/app-provider/env.ts | 13 ++++++------- src/lib/services/contractStateService.ts | 2 +- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index 09c03ec1a..487185ca4 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -10,12 +10,6 @@ export enum CELATONE_QUERY_KEYS { // TABLE ACCOUNT_TABLE_COUNTS = "CELATONE_QUERY_ACCOUNT_TABLE_COUNTS", CONTRACT_TABLE_COUNTS = "CELATONE_QUERY_CONTRACT_TABLE_COUNTS", - // CONTRACT - CONTRACT_LCD = "CELATONE_QUERY_CONTRACT_LCD", - CONTRACT_QUERY_MSGS = "CELATONE_QUERY_CONTRACT_QUERY_MSGS", - CONTRACT_QUERY_LCD = "CELATONE_QUERY_CONTRACT_QUERY_LCD", - CONTRACT_STATE = "CELATONE_QUERY_CONTRACT_STATE", - CONTRACTS_BY_CODE_ID = "CELATONE_QUERY_CONTRACTS_BY_CODE_ID", // ACCOUNT ACCOUNT_DATA = "CELATONE_QUERY_ACCOUNT_DATA", ACCOUNT_TYPE = "CELATONE_QUERY_ACCOUNT_TYPE", @@ -33,9 +27,14 @@ export enum CELATONE_QUERY_KEYS { CODES_BY_IDS = "CELATONE_QUERY_CODES_BY_IDS", CODE_DATA = "CELATONE_QUERY_CODE_DATA", CODE_DATA_LCD = "CELATONE_QUERY_CODE_DATA_LCD", - // CONTRACT GQL + // CONTRACT CONTRACTS = "CELATONE_QUERY_CONTRACTS", CONTRACT_DATA = "CELATONE_QUERY_CONTRACT_DATA", + CONTRACT_LCD = "CELATONE_QUERY_CONTRACT_LCD", + CONTRACT_QUERY_MSGS = "CELATONE_QUERY_CONTRACT_QUERY_MSGS", + CONTRACT_QUERY_LCD = "CELATONE_QUERY_CONTRACT_QUERY_LCD", + CONTRACT_STATES = "CELATONE_QUERY_CONTRACT_STATES", + CONTRACTS_BY_CODE_ID = "CELATONE_QUERY_CONTRACTS_BY_CODE_ID", CONTRACTS_BY_ADMIN = "CELATONE_QUERY_CONTRACT_BY_ADMIN", INSTANTIATED_CONTRACTS_BY_ADDRESS = "CELATONE_QUERY_INSTANTIATED_CONTRACTS_BY_ADDRESS", ADMIN_CONTRACTS_BY_ADDRESS = "CELATONE_QUERY_ADMIN_CONTRACTS_BY_ADDRESS", diff --git a/src/lib/services/contractStateService.ts b/src/lib/services/contractStateService.ts index c938e4a6e..174e6cc5a 100644 --- a/src/lib/services/contractStateService.ts +++ b/src/lib/services/contractStateService.ts @@ -13,7 +13,7 @@ export const useContractStates = ( return useInfiniteQuery( [ - CELATONE_QUERY_KEYS.CONTRACT_STATE, + CELATONE_QUERY_KEYS.CONTRACT_STATES, baseEndpoint, contractAddress, numStatesToLoad, From f256cc2c01c119b92279f5fb1ceb2b0eb16c0851 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 16 May 2024 10:17:43 +0700 Subject: [PATCH 6/9] fix: code lite contracts --- CHANGELOG.md | 1 + src/lib/app-provider/env.ts | 1 + src/lib/components/AlertPaginationLcd.tsx | 9 +++ .../table/contracts/ContractNameCell.tsx | 6 +- .../table/contracts/ContractsTable.tsx | 23 ++++--- .../table/contracts/ContractsTableHeader.tsx | 16 +++-- .../contracts/ContractsTableMobileCard.tsx | 44 +++++++------ .../table/contracts/ContractsTableRow.tsx | 29 ++++++--- .../table/contracts/ContractsTableRowCTA.tsx | 65 +++++++++---------- .../components/code-info/index.ts | 3 +- ...tsTable.tsx => CodeContractsTableFull.tsx} | 6 +- .../table/CodeContractsTableLite.tsx | 55 ++++++++++++++++ src/lib/pages/code-details/data.ts | 20 +++++- src/lib/pages/code-details/index.tsx | 12 +++- .../codes/components/RecentCodesTableLite.tsx | 11 +--- .../components/RecentContractsTable.tsx | 2 +- src/lib/services/types/wasm/contract.ts | 24 +++++++ src/lib/services/wasm/contract/index.ts | 23 ++++++- src/lib/services/wasm/contract/lcd.ts | 22 ++++++- 19 files changed, 268 insertions(+), 104 deletions(-) create mode 100644 src/lib/components/AlertPaginationLcd.tsx rename src/lib/pages/code-details/components/code-info/table/{CodeContractsTable.tsx => CodeContractsTableFull.tsx} (93%) create mode 100644 src/lib/pages/code-details/components/code-info/table/CodeContractsTableLite.tsx diff --git a/CHANGELOG.md b/CHANGELOG.md index 953d94faa..be4aaa053 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features +- [#929](https://github.com/alleslabs/celatone-frontend/pull/929) Support lite version for code details contract list - [#929](https://github.com/alleslabs/celatone-frontend/pull/929) Support lite version for code details page - [#925](https://github.com/alleslabs/celatone-frontend/pull/925) Move contracts service to new folder structure - [#919](https://github.com/alleslabs/celatone-frontend/pull/919) Remove singleStakingDenom config and use from lcd instead diff --git a/src/lib/app-provider/env.ts b/src/lib/app-provider/env.ts index 487185ca4..67bb40b6e 100644 --- a/src/lib/app-provider/env.ts +++ b/src/lib/app-provider/env.ts @@ -35,6 +35,7 @@ export enum CELATONE_QUERY_KEYS { CONTRACT_QUERY_LCD = "CELATONE_QUERY_CONTRACT_QUERY_LCD", CONTRACT_STATES = "CELATONE_QUERY_CONTRACT_STATES", CONTRACTS_BY_CODE_ID = "CELATONE_QUERY_CONTRACTS_BY_CODE_ID", + CONTRACTS_BY_CODE_ID_LCD = "CELATONE_QUERY_CONTRACTS_BY_CODE_ID_LCD", CONTRACTS_BY_ADMIN = "CELATONE_QUERY_CONTRACT_BY_ADMIN", INSTANTIATED_CONTRACTS_BY_ADDRESS = "CELATONE_QUERY_INSTANTIATED_CONTRACTS_BY_ADDRESS", ADMIN_CONTRACTS_BY_ADDRESS = "CELATONE_QUERY_ADMIN_CONTRACTS_BY_ADDRESS", diff --git a/src/lib/components/AlertPaginationLcd.tsx b/src/lib/components/AlertPaginationLcd.tsx new file mode 100644 index 000000000..548926c52 --- /dev/null +++ b/src/lib/components/AlertPaginationLcd.tsx @@ -0,0 +1,9 @@ +import { Alert, AlertDescription } from "@chakra-ui/react"; + +export const AlertPaginationLcd = () => ( + + + Error fetching data from LCD. Please try again later. + + +); diff --git a/src/lib/components/table/contracts/ContractNameCell.tsx b/src/lib/components/table/contracts/ContractNameCell.tsx index 59476482d..aca12459f 100644 --- a/src/lib/components/table/contracts/ContractNameCell.tsx +++ b/src/lib/components/table/contracts/ContractNameCell.tsx @@ -25,7 +25,11 @@ export const ContractNameCell = ({ return ( 0 + ? contractLocalInfo.label + : "Untitled" + } maxLength={constants.maxContractNameLength} tooltip={contractLocalInfo.description} isReadOnly={isReadOnly} diff --git a/src/lib/components/table/contracts/ContractsTable.tsx b/src/lib/components/table/contracts/ContractsTable.tsx index 7379b20fc..d0f46ff12 100644 --- a/src/lib/components/table/contracts/ContractsTable.tsx +++ b/src/lib/components/table/contracts/ContractsTable.tsx @@ -13,9 +13,10 @@ interface ContractsTableProps { isLoading: boolean; emptyState: JSX.Element; onRowSelect: (contract: BechAddr32) => void; + showTag?: boolean; + showLastUpdate?: boolean; isReadOnly?: boolean; withCTA?: CTAInfo; - withoutTag?: boolean; } export const ContractsTable = ({ @@ -23,9 +24,10 @@ export const ContractsTable = ({ isLoading, emptyState, onRowSelect, + showTag = true, + showLastUpdate = true, isReadOnly = false, withCTA, - withoutTag, }: ContractsTableProps) => { const isMobile = useMobile(); @@ -34,13 +36,11 @@ export const ContractsTable = ({ let templateColumns: string; if (isReadOnly) - templateColumns = - "minmax(160px, 300px) minmax(300px, 3fr) minmax(200px, 2fr) 1fr"; - else if (withoutTag) - templateColumns = "160px minmax(300px, 3fr) 250px 300px 80px"; + templateColumns = `minmax(160px, 300px) minmax(300px, 3fr) minmax(200px, 2fr)${showLastUpdate ? " 1fr" : ""}`; + else if (!showTag) + templateColumns = `160px minmax(300px, 3fr)${showLastUpdate ? " 250px 300px" : ""} 80px`; else - templateColumns = - "160px minmax(300px, 3fr) minmax(200px, 2fr) 150px 260px 80px"; + templateColumns = `160px minmax(300px, 3fr) minmax(200px, 2fr)${showLastUpdate ? " 150px 260px" : ""} 80px`; return isMobile ? ( @@ -55,6 +55,7 @@ export const ContractsTable = ({ } contractInfo={contractInfo} onRowSelect={onRowSelect} + showLastUpdate={showLastUpdate} /> ))} @@ -62,9 +63,10 @@ export const ContractsTable = ({ {contracts.map((contractInfo) => ( ))} diff --git a/src/lib/components/table/contracts/ContractsTableHeader.tsx b/src/lib/components/table/contracts/ContractsTableHeader.tsx index f1e98cf38..d3b6fa074 100644 --- a/src/lib/components/table/contracts/ContractsTableHeader.tsx +++ b/src/lib/components/table/contracts/ContractsTableHeader.tsx @@ -7,23 +7,29 @@ import type { CTAInfo } from "./ContractsTableRowCTA"; export const ContractsTableHeader = ({ templateColumns, + showTag, + showLastUpdate, isReadOnly, withCTA, - withoutTag, }: { templateColumns: GridProps["templateColumns"]; + showTag: boolean; + showLastUpdate: boolean; isReadOnly: boolean; withCTA?: CTAInfo; - withoutTag?: boolean; }) => ( Contract Address Contract Name - {!withoutTag && Tags} - Instantiator + {showTag && Tags} + {showLastUpdate && Instantiator} {!isReadOnly && ( <> - {withCTA ? : Timestamp} + {showLastUpdate && ( + <> + {withCTA ? : Timestamp} + + )} )} diff --git a/src/lib/components/table/contracts/ContractsTableMobileCard.tsx b/src/lib/components/table/contracts/ContractsTableMobileCard.tsx index 217b204f3..d9f05f715 100644 --- a/src/lib/components/table/contracts/ContractsTableMobileCard.tsx +++ b/src/lib/components/table/contracts/ContractsTableMobileCard.tsx @@ -17,6 +17,7 @@ import { ContractInstantiatorCell } from "./ContractInstantiatorCell"; interface ContractsTableMobileCardProps { contractInfo: ContractInfo; onRowSelect: (contract: BechAddr32) => void; + showLastUpdate: boolean; } const InstantiatorRemark = ({ @@ -44,6 +45,7 @@ const InstantiatorRemark = ({ export const ContractsTableMobileCard = ({ contractInfo, onRowSelect, + showLastUpdate, }: ContractsTableMobileCardProps) => ( onRowSelect(contractInfo.contractAddress)} @@ -57,26 +59,28 @@ export const ContractsTableMobileCard = ({ } middleContent={ - -
- - - {contractInfo.name ?? contractInfo.label} - -
-
- - -
-
+ showLastUpdate && ( + +
+ + + {contractInfo.name ?? contractInfo.label} + +
+
+ + +
+
+ ) } bottomContent={ contractInfo.latestUpdated ? ( diff --git a/src/lib/components/table/contracts/ContractsTableRow.tsx b/src/lib/components/table/contracts/ContractsTableRow.tsx index 234bfd070..45a129547 100644 --- a/src/lib/components/table/contracts/ContractsTableRow.tsx +++ b/src/lib/components/table/contracts/ContractsTableRow.tsx @@ -14,18 +14,20 @@ interface ContractsTableRowProps { contractInfo: ContractInfo; templateColumns: string; onRowSelect: (contract: BechAddr32) => void; + showTag: boolean; + showLastUpdate: boolean; isReadOnly: boolean; withCTA?: CTAInfo; - withoutTag?: boolean; } export const ContractsTableRow = ({ contractInfo, templateColumns, onRowSelect, + showTag, + showLastUpdate, isReadOnly, withCTA, - withoutTag, }: ContractsTableRowProps) => ( - {!withoutTag && ( + {showTag && ( )} - - - + + {showLastUpdate && ( + + + + )} {!isReadOnly && ( - + )} ); diff --git a/src/lib/components/table/contracts/ContractsTableRowCTA.tsx b/src/lib/components/table/contracts/ContractsTableRowCTA.tsx index d8abcc3ab..ec74600a6 100644 --- a/src/lib/components/table/contracts/ContractsTableRowCTA.tsx +++ b/src/lib/components/table/contracts/ContractsTableRowCTA.tsx @@ -13,11 +13,7 @@ import { } from "@chakra-ui/react"; import { TableRow } from "../tableComponents"; -import { - useCurrentChain, - useInternalNavigate, - useMobile, -} from "lib/app-provider"; +import { useCurrentChain, useInternalNavigate } from "lib/app-provider"; import { AppLink } from "lib/components/AppLink"; import { CustomIcon } from "lib/components/icon"; import { @@ -27,8 +23,8 @@ import { RemoveContractModal, SaveContractDetailsModal, } from "lib/components/modal"; -import { ContractInteractionTabs } from "lib/types"; import type { ContractInfo, LVPair, Option } from "lib/types"; +import { ContractInteractionTabs } from "lib/types"; import { dateFromNow, formatUTC } from "lib/utils"; const StyledIconButton = chakra(IconButton, { @@ -59,7 +55,6 @@ export const ContractsTableRowCTA = ({ const navigate = useInternalNavigate(); const isAdmin = !!address && address === contractInfo.admin; - const isMobile = useMobile(); return withCTA ? ( <> @@ -201,35 +196,33 @@ export const ContractsTableRowCTA = ({ )} - {!isMobile && ( - - e.stopPropagation()}> - {contractInfo.lists ? ( - } - variant="ghost-primary" - /> - } - /> - ) : ( - } - variant="ghost-gray" - /> - } - /> - )} - - - )} + + e.stopPropagation()}> + {contractInfo.lists ? ( + } + variant="ghost-primary" + /> + } + /> + ) : ( + } + variant="ghost-gray" + /> + } + /> + )} + + ); }; diff --git a/src/lib/pages/code-details/components/code-info/index.ts b/src/lib/pages/code-details/components/code-info/index.ts index 96efbbba3..91355801b 100644 --- a/src/lib/pages/code-details/components/code-info/index.ts +++ b/src/lib/pages/code-details/components/code-info/index.ts @@ -1,2 +1,3 @@ -export * from "./table/CodeContractsTable"; +export * from "./table/CodeContractsTableFull"; +export * from "./table/CodeContractsTableLite"; export * from "./CodeInfoSection"; diff --git a/src/lib/pages/code-details/components/code-info/table/CodeContractsTable.tsx b/src/lib/pages/code-details/components/code-info/table/CodeContractsTableFull.tsx similarity index 93% rename from src/lib/pages/code-details/components/code-info/table/CodeContractsTable.tsx rename to src/lib/pages/code-details/components/code-info/table/CodeContractsTableFull.tsx index 431b0825e..c075de875 100644 --- a/src/lib/pages/code-details/components/code-info/table/CodeContractsTable.tsx +++ b/src/lib/pages/code-details/components/code-info/table/CodeContractsTableFull.tsx @@ -9,12 +9,12 @@ import type { BechAddr32 } from "lib/types"; import { NoContracts } from "./NoContracts"; -interface CodeContractsTableProps { +interface CodeContractsTableFullProps { codeId: number; } -export const CodeContractsTable = observer( - ({ codeId }: CodeContractsTableProps) => { +export const CodeContractsTableFull = observer( + ({ codeId }: CodeContractsTableFullProps) => { const navigate = useInternalNavigate(); const onRowSelect = (contract: BechAddr32) => navigate({ diff --git a/src/lib/pages/code-details/components/code-info/table/CodeContractsTableLite.tsx b/src/lib/pages/code-details/components/code-info/table/CodeContractsTableLite.tsx new file mode 100644 index 000000000..001131742 --- /dev/null +++ b/src/lib/pages/code-details/components/code-info/table/CodeContractsTableLite.tsx @@ -0,0 +1,55 @@ +import { observer } from "mobx-react-lite"; + +import { useInternalNavigate } from "lib/app-provider"; +import { AlertPaginationLcd } from "lib/components/AlertPaginationLcd"; +import { LoadNext } from "lib/components/LoadNext"; +import { ContractsTable, TableTitle } from "lib/components/table"; +import { useCodeContractsLcd } from "lib/pages/code-details/data"; +import type { BechAddr32 } from "lib/types"; + +import { NoContracts } from "./NoContracts"; + +interface CodeContractsTableLiteProps { + codeId: number; +} + +export const CodeContractsTableLite = observer( + ({ codeId }: CodeContractsTableLiteProps) => { + const navigate = useInternalNavigate(); + const { + data, + error, + fetchNextPage, + hasNextPage, + isLoading, + isFetchingNextPage, + } = useCodeContractsLcd(codeId); + + const onRowSelect = (contract: BechAddr32) => + navigate({ + pathname: "/contracts/[contract]", + query: { contract }, + }); + + return ( + <> + {data && !!error && } + + } + onRowSelect={onRowSelect} + showLastUpdate={false} + /> + {hasNextPage && ( + + )} + + ); + } +); diff --git a/src/lib/pages/code-details/data.ts b/src/lib/pages/code-details/data.ts index 16d9febd9..35428717d 100644 --- a/src/lib/pages/code-details/data.ts +++ b/src/lib/pages/code-details/data.ts @@ -3,7 +3,10 @@ import type { UseQueryOptions } from "@tanstack/react-query"; import { useContractStore } from "lib/providers/store"; import type { ContractsResponse } from "lib/services/types"; import { useCodeLcd } from "lib/services/wasm/code"; -import { useContractsByCodeId } from "lib/services/wasm/contract"; +import { + useContractsByCodeId, + useContractsByCodeIdLcd, +} from "lib/services/wasm/contract"; import type { ContractInfo, Option } from "lib/types"; export const useCodeDataLcd = (codeId: number, enabled: boolean) => { @@ -52,3 +55,18 @@ export const useCodeContracts = ( isLoading, }; }; + +export const useCodeContractsLcd = (codeId: number) => { + const { getContractLocalInfo } = useContractStore(); + const { data, ...rest } = useContractsByCodeIdLcd(codeId); + + return { + data: data?.pages.flatMap((page) => + page.contracts.map((contract) => ({ + ...contract, + ...getContractLocalInfo(contract.contractAddress), + })) + ), + ...rest, + }; +}; diff --git a/src/lib/pages/code-details/index.tsx b/src/lib/pages/code-details/index.tsx index 42d5ddb56..4e765f96c 100644 --- a/src/lib/pages/code-details/index.tsx +++ b/src/lib/pages/code-details/index.tsx @@ -19,7 +19,11 @@ import { UserDocsLink } from "lib/components/UserDocsLink"; import { useSchemaStore } from "lib/providers/store"; import { useCodeData } from "lib/services/wasm/code"; -import { CodeContractsTable, CodeInfoSection } from "./components/code-info"; +import { + CodeContractsTableFull, + CodeContractsTableLite, + CodeInfoSection, +} from "./components/code-info"; import { CodeTopInfo } from "./components/code-info/CodeTopInfo"; import { CodeSchemaSection } from "./components/json-schema/CodeSchemaSection"; import { useCodeDataLcd } from "./data"; @@ -111,7 +115,11 @@ const CodeDetailsBody = observer(({ codeId, tab }: CodeDetailsBodyProps) => { attached={!!jsonSchema} toJsonSchemaTab={handleTabChange(TabIndex.JsonSchema)} /> - + {isFullTier ? ( + + ) : ( + + )} { const navigate = useInternalNavigate(); - const { data, error, @@ -27,13 +26,7 @@ export const RecentCodesTableLite = observer(() => { return ( <> - {data && !!error && ( - - - Error fetching data from LCD. Please refresh to try again. - - - )} + {data && !!error && } { ) } onRowSelect={onRowSelect} - withoutTag + showTag={false} /> {data && data.total > 10 && ( ; +const zContractsResponseItemLcd = zBechAddr32.transform( + (val) => ({ + contractAddress: val, + label: "", + admin: undefined, + instantiator: undefined, + latestUpdated: undefined, + latestUpdater: undefined, + remark: undefined, + }) +); + +export const zContractsResponseLcd = z + .object({ + contracts: z.array(zContractsResponseItemLcd).default([]), // by code id case + contract_addresses: z.array(zContractsResponseItemLcd).optional(), + pagination: zPagination, + }) + .transform((val) => ({ + contracts: val.contract_addresses ?? val.contracts, + pagination: val.pagination, + })); + export const zContract = z .object({ address: zBechAddr32, diff --git a/src/lib/services/wasm/contract/index.ts b/src/lib/services/wasm/contract/index.ts index c3ded8dd2..3b60d4d98 100644 --- a/src/lib/services/wasm/contract/index.ts +++ b/src/lib/services/wasm/contract/index.ts @@ -1,5 +1,5 @@ import type { UseQueryOptions, UseQueryResult } from "@tanstack/react-query"; -import { useQuery } from "@tanstack/react-query"; +import { useInfiniteQuery, useQuery } from "@tanstack/react-query"; import { CELATONE_QUERY_KEYS, @@ -26,7 +26,11 @@ import { getInstantiatedContractsByAddress, getMigrationHistoriesByContractAddress, } from "./api"; -import { getContractLcd, getContractQueryLcd } from "./lcd"; +import { + getContractLcd, + getContractQueryLcd, + getContractsByCodeIdLcd, +} from "./lcd"; export const useContracts = ( limit: number, @@ -176,7 +180,7 @@ export const useContractsByCodeId = ( const endpoint = useBaseApiRoute("codes"); return useQuery( - [CELATONE_QUERY_KEYS.CONTRACTS_BY_CODE_ID, endpoint, limit, offset], + [CELATONE_QUERY_KEYS.CONTRACTS_BY_CODE_ID, endpoint, codeId, limit, offset], async () => getContractsByCodeId(endpoint, codeId, limit, offset), { retry: 1, @@ -186,6 +190,19 @@ export const useContractsByCodeId = ( ); }; +export const useContractsByCodeIdLcd = (codeId: number) => { + const endpoint = useLcdEndpoint(); + + return useInfiniteQuery( + [CELATONE_QUERY_KEYS.CONTRACTS_BY_CODE_ID_LCD, endpoint, codeId], + ({ pageParam }) => getContractsByCodeIdLcd(endpoint, codeId, pageParam), + { + getNextPageParam: (lastPage) => lastPage.pagination.nextKey ?? undefined, + refetchOnWindowFocus: false, + } + ); +}; + export const useContractQueryLcd = ( contractAddress: BechAddr32, msg: string, diff --git a/src/lib/services/wasm/contract/lcd.ts b/src/lib/services/wasm/contract/lcd.ts index 5f8be4db0..738e3f818 100644 --- a/src/lib/services/wasm/contract/lcd.ts +++ b/src/lib/services/wasm/contract/lcd.ts @@ -1,7 +1,7 @@ import axios from "axios"; -import { zContractLcd } from "lib/services/types"; -import type { BechAddr32, JsonDataType } from "lib/types"; +import { zContractLcd, zContractsResponseLcd } from "lib/services/types"; +import type { BechAddr32, JsonDataType, Option } from "lib/types"; import { encode, parseWithError } from "lib/utils"; export const getContractQueryLcd = ( @@ -19,3 +19,21 @@ export const getContractLcd = (endpoint: string, contractAddress: BechAddr32) => axios( `${endpoint}/cosmwasm/wasm/v1/contract/${encodeURI(contractAddress)}` ).then(({ data }) => parseWithError(zContractLcd, data)); + +export const getContractsByCodeIdLcd = ( + endpoint: string, + codeId: number, + paginationKey: Option +) => + axios + .get( + `${endpoint}/cosmwasm/wasm/v1/code/${encodeURIComponent(codeId)}/contracts`, + { + params: { + "pagination.limit": 10, + "pagination.reverse": true, + "pagination.key": paginationKey, + }, + } + ) + .then(({ data }) => parseWithError(zContractsResponseLcd, data)); From a8cc8b361682a569409906f3a65877b221804f18 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 16 May 2024 10:20:29 +0700 Subject: [PATCH 7/9] fix: changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be4aaa053..775c8edc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,7 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features -- [#929](https://github.com/alleslabs/celatone-frontend/pull/929) Support lite version for code details contract list +- [#933](https://github.com/alleslabs/celatone-frontend/pull/933) Support lite version for code details contract list - [#929](https://github.com/alleslabs/celatone-frontend/pull/929) Support lite version for code details page - [#925](https://github.com/alleslabs/celatone-frontend/pull/925) Move contracts service to new folder structure - [#919](https://github.com/alleslabs/celatone-frontend/pull/919) Remove singleStakingDenom config and use from lcd instead From 2389c5ea754c28473b961d52d3fabf24913521e0 Mon Sep 17 00:00:00 2001 From: songwongtp <16089160+songwongtp@users.noreply.github.com> Date: Thu, 16 May 2024 14:05:55 +0700 Subject: [PATCH 8/9] fix: acceptance test --- .../code-details/components/code-info/CodeInfoSection.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) 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 f2d1f51d0..b39e21f09 100644 --- a/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx +++ b/src/lib/pages/code-details/components/code-info/CodeInfoSection.tsx @@ -147,10 +147,14 @@ export const CodeInfoSection = ({ Code Info - + {chainId} - + Date: Thu, 16 May 2024 18:30:29 +0700 Subject: [PATCH 9/9] fix: comments --- src/lib/services/types/wasm/code.ts | 2 +- src/lib/services/wasm/code/lcd.ts | 2 +- src/lib/stores/contract.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/services/types/wasm/code.ts b/src/lib/services/types/wasm/code.ts index d2468be90..5f9ca83ed 100644 --- a/src/lib/services/types/wasm/code.ts +++ b/src/lib/services/types/wasm/code.ts @@ -120,7 +120,7 @@ export const zCodeInfoResponseLcd = z codeId: code_id, cw2Contract: null, cw2Version: null, - hash: parseTxHash(data_hash), + hash: data_hash, instantiatePermission: instantiate_permission.permission, permissionAddresses: instantiate_permission.address && instantiate_permission.address !== "" diff --git a/src/lib/services/wasm/code/lcd.ts b/src/lib/services/wasm/code/lcd.ts index a4ab515fa..aeb79599c 100644 --- a/src/lib/services/wasm/code/lcd.ts +++ b/src/lib/services/wasm/code/lcd.ts @@ -20,5 +20,5 @@ export const getCodesLcd = async ( export const getCodeLcd = async (endpoint: string, codeId: number) => axios - .get(`${endpoint}/cosmwasm/wasm/v1/code/${codeId}`) + .get(`${endpoint}/cosmwasm/wasm/v1/code/${encodeURIComponent(codeId)}`) .then(({ data }) => parseWithError(zCodeInfoResponseLcd, data)); diff --git a/src/lib/stores/contract.ts b/src/lib/stores/contract.ts index 7ba2aeaf6..0af5a843e 100644 --- a/src/lib/stores/contract.ts +++ b/src/lib/stores/contract.ts @@ -15,7 +15,7 @@ import { formatSlugName, getCurrentDate, getTagsDefault } from "lib/utils"; export interface ContractLocalInfo { contractAddress: BechAddr32; instantiator: Option; - label: string; + label: string; // NOTE: if empty means no label provided name?: string; description?: string; tags?: string[];