diff --git a/CHANGELOG.md b/CHANGELOG.md index d5c62d848..ce89143f1 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 +- [#46](https://github.com/alleslabs/celatone-frontend/pull/46) Wireup instantiate info - [#55](https://github.com/alleslabs/celatone-frontend/pull/55) Add "Add To List / Edit" button to edit offchain details on query and execute pages - [#44](https://github.com/alleslabs/celatone-frontend/pull/44) Render query cmds shortcut in contract detail page - [#38](https://github.com/alleslabs/celatone-frontend/pull/38) Show execute msg cmds when wallet is not connected diff --git a/src/lib/components/LabelText.tsx b/src/lib/components/LabelText.tsx index d67f2c0fc..406744921 100644 --- a/src/lib/components/LabelText.tsx +++ b/src/lib/components/LabelText.tsx @@ -3,10 +3,16 @@ import { Flex, Text } from "@chakra-ui/react"; interface LabelTextProps { label: string; children: string | JSX.Element; - helperText?: string; + helperText1?: string; + helperText2?: string; } -export const LabelText = ({ label, children, helperText }: LabelTextProps) => { +export const LabelText = ({ + label, + children, + helperText1, + helperText2, +}: LabelTextProps) => { return ( @@ -17,9 +23,14 @@ export const LabelText = ({ label, children, helperText }: LabelTextProps) => { ) : ( children )} - {helperText && ( + {helperText1 && ( - {helperText} + {helperText1} + + )} + {helperText2 && ( + + {helperText2} )} diff --git a/src/lib/hooks/index.ts b/src/lib/hooks/index.ts index bc955d10c..5df74f1b9 100644 --- a/src/lib/hooks/index.ts +++ b/src/lib/hooks/index.ts @@ -4,3 +4,4 @@ export * from "./useToast"; export * from "./useEndpoint"; export * from "./useUserKey"; export * from "./useDummyWallet"; +export * from "./useAddressType"; diff --git a/src/lib/hooks/useAddressType.ts b/src/lib/hooks/useAddressType.ts new file mode 100644 index 000000000..b1e3cf08a --- /dev/null +++ b/src/lib/hooks/useAddressType.ts @@ -0,0 +1,29 @@ +import { useWallet } from "@cosmos-kit/react"; +import { useCallback } from "react"; + +export type AddressReturnType = + | "user_address" + | "contract_address" + | "invalid_address"; + +const addressLengthMap: { + [key: string]: { [length: number]: AddressReturnType }; +} = { + osmosis: { + 43: "user_address", + 63: "contract_address", + }, + osmosistestnet: { + 43: "user_address", + 63: "contract_address", + }, +}; + +export const useGetAddressType = () => { + const { currentChainName } = useWallet(); + return useCallback( + (address: string): AddressReturnType => + addressLengthMap[currentChainName]?.[address.length] ?? "invalid_address", + [currentChainName] + ); +}; diff --git a/src/lib/model/contract.ts b/src/lib/model/contract.ts index a270c1522..c5aac4512 100644 --- a/src/lib/model/contract.ts +++ b/src/lib/model/contract.ts @@ -25,7 +25,7 @@ import type { ContractInfo, ContractListInfo } from "lib/stores/contract"; import type { ContractAddr, HumanAddr } from "lib/types"; import { formatSlugName } from "lib/utils"; -interface ContractDetail { +export interface ContractDetail { chainId: string; codeInfo: CodeLocalInfo | undefined; contractInfo: ContractInfo | undefined; @@ -33,9 +33,9 @@ interface ContractDetail { publicInfo: PublicInfo | undefined; balances: Coin[]; initMsg: string; - initTxHash?: string; - initProposalTitle?: string; - initProposalId?: number; + initTxHash: string | undefined; + initProposalTitle: string | undefined; + initProposalId: number | undefined; } export const useInstantiatedByMe = (enable: boolean): ContractListInfo => { diff --git a/src/lib/pages/contract-details/components/InstantiateInfo.tsx b/src/lib/pages/contract-details/components/InstantiateInfo.tsx index ab05d5711..de7c5f46a 100644 --- a/src/lib/pages/contract-details/components/InstantiateInfo.tsx +++ b/src/lib/pages/contract-details/components/InstantiateInfo.tsx @@ -1,30 +1,132 @@ -import { Flex, Heading } from "@chakra-ui/react"; +import { Flex, Heading, Text } from "@chakra-ui/react"; import { ExplorerLink } from "lib/components/ExplorerLink"; import { LabelText } from "lib/components/LabelText"; +import type { AddressReturnType } from "lib/hooks"; +import { useGetAddressType } from "lib/hooks"; +import type { ContractDetail } from "lib/model/contract"; +import { formatUTC, dateFromNow } from "lib/utils"; + +const getAddressTypeText = (addressType: AddressReturnType) => { + switch (addressType) { + case "contract_address": + return "(Contract Address)"; + case "user_address": + return "(Wallet Address)"; + default: + return "(Invalid Address)"; + } +}; + +interface InstantiateInfoProps { + contractDetail: ContractDetail; +} + +export const InstantiateInfo = ({ contractDetail }: InstantiateInfoProps) => { + const getAddressType = useGetAddressType(); + + const renderDataFound = () => { + if (contractDetail?.instantiateInfo) { + const instantiatorType = getAddressType( + contractDetail.instantiateInfo.instantiator + ); + return ( + <> + {contractDetail.chainId} + + {contractDetail.instantiateInfo && + (contractDetail.instantiateInfo.createdHeight !== -1 ? ( + + + + ) : ( + N/A + ))} + + + + + + + + + + {contractDetail.initProposalId ? ( + + + + ) : ( + + + + )} + + {contractDetail.instantiateInfo.admin && ( + + + + )} + + {contractDetail.instantiateInfo.ibcPortId && ( + + {contractDetail.instantiateInfo.ibcPortId} + + )} + + ); + } + + return ( + + Error fetching data + + ); + }; -export const InstantiateInfo = () => { - /** - * @todos - * - Make an interface - * - All these are mockups, Wireup with real data and map render LabelText - */ return ( - + Instantiate Info - phoenix-1 - - - - - wasm.terra1te47jv6pg272n8unq490nvhh5m43v5n5kxfgrztly2tmkmqxzw8qphrjx2 - + {renderDataFound()} ); }; diff --git a/src/lib/pages/contract-details/index.tsx b/src/lib/pages/contract-details/index.tsx index 7b03d3c3f..93fdd8fdc 100644 --- a/src/lib/pages/contract-details/index.tsx +++ b/src/lib/pages/contract-details/index.tsx @@ -17,6 +17,8 @@ import { BackButton } from "lib/components/button/BackButton"; import { CustomTab } from "lib/components/CustomTab"; import { ExplorerLink } from "lib/components/ExplorerLink"; import PageContainer from "lib/components/PageContainer"; +import { useContractDetail } from "lib/model/contract"; +import type { ContractAddr } from "lib/types"; import { getFirstQueryParam } from "lib/utils"; import { CommandSection } from "./components/CommandSection"; @@ -30,6 +32,10 @@ const ContractDetails = () => { * @todos add contract address validation function here */ const contractAddress = getFirstQueryParam(router.query.contractAddress); + const contractDetail = useContractDetail(contractAddress as ContractAddr); + + // TODO - Wait for design + if (!contractDetail) return null; return ( @@ -103,7 +109,7 @@ const ContractDetails = () => { {/* Instantiate/Contract Info Section */} {/* Instantiate Info */} - + {/* Contract Info (Expand) */} diff --git a/src/lib/services/contract.ts b/src/lib/services/contract.ts index 2424fff7f..e58235619 100644 --- a/src/lib/services/contract.ts +++ b/src/lib/services/contract.ts @@ -97,7 +97,7 @@ export const queryInstantiateInfo = async ( createdTime = new Date(data.block.header.time); } else { // TODO: revisit default value - createdHeight = 0; + createdHeight = -1; createdTime = new Date(0); } diff --git a/src/lib/utils/date.ts b/src/lib/utils/date.ts new file mode 100644 index 000000000..0abd624fd --- /dev/null +++ b/src/lib/utils/date.ts @@ -0,0 +1,11 @@ +import dayjs from "dayjs"; + +export const formatUTC = (timestamp: string) => { + const localDate = timestamp.concat("Z"); + return dayjs(localDate).utc().format("MMM DD, YYYY, h:mm:ss A [(UTC)]"); +}; + +export const dateFromNow = (timestamp: string) => { + const localDate = timestamp.concat("Z"); + return dayjs(localDate).fromNow(); +}; diff --git a/src/lib/utils/index.ts b/src/lib/utils/index.ts index 0cf995c31..426511042 100644 --- a/src/lib/utils/index.ts +++ b/src/lib/utils/index.ts @@ -10,3 +10,4 @@ export * from "./isDecimalNumber"; export * from "./extractMsgType"; export * from "./redo"; export * from "./scrollTop"; +export * from "./date";