From 27c0c698e80c32d58474c57887f6413bfa79de66 Mon Sep 17 00:00:00 2001 From: bkioshn Date: Tue, 17 Jan 2023 16:18:03 +0700 Subject: [PATCH 1/9] feat(components): implement unsupported assets in contract details page --- .../modal/UnsupportedTokensModal.tsx | 123 ++++++++++++++++++ .../components/token/TokenSection.tsx | 17 ++- src/lib/pages/contract-details/index.tsx | 4 - src/lib/utils/formatter/index.ts | 1 + src/lib/utils/formatter/tokenType.ts | 9 ++ 5 files changed, 148 insertions(+), 6 deletions(-) create mode 100644 src/lib/components/modal/UnsupportedTokensModal.tsx create mode 100644 src/lib/utils/formatter/tokenType.ts diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx new file mode 100644 index 000000000..5c8fb4499 --- /dev/null +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -0,0 +1,123 @@ +import { + Modal, + ModalHeader, + Flex, + Icon, + Text, + ModalOverlay, + ModalContent, + ModalCloseButton, + useDisclosure, + ModalBody, + Button, + Heading, + Box, +} from "@chakra-ui/react"; +import router from "next/router"; +import { useCallback } from "react"; +import { FaDollarSign } from "react-icons/fa"; + +import { Copier } from "../Copier"; +import { ExplorerLink } from "../ExplorerLink"; +import type { BalanceWithAssetInfo, Balance } from "lib/types"; +import { getFirstQueryParam, tokenType, truncate } from "lib/utils"; +import { formatToken } from "lib/utils/formatter/token"; + +interface UnsupportedTokensModalProps { + unsupportedAssets: BalanceWithAssetInfo[]; +} + +interface UnsupportedTokenProps { + balance: Balance; +} + +const UnsupportedToken = ({ balance }: UnsupportedTokenProps) => { + const splitId = balance.id.split("/"); + const type = !balance.id.includes("/") + ? tokenType(balance.type) + : tokenType(splitId[0]); + if (splitId[1]) { + splitId[1] = truncate(splitId[1]); + } + const label = () => (splitId.length === 1 ? balance.id : splitId.join("/")); + + return ( + + + + + {label()} + + + + + + + {`${type} Token`} + + + + {formatToken(balance.amount, balance.precision)} + + + ); +}; + +export const UnsupportedTokensModal = ({ + unsupportedAssets, +}: UnsupportedTokensModalProps) => { + const contractAddress = getFirstQueryParam(router.query.contractAddress); + + const { isOpen, onOpen, onClose } = useDisclosure(); + + const handleOnOther = useCallback(() => { + onClose(); + }, [onClose]); + + return ( + <> + + {" "} + + + + + + + + + Unsupported Assets + + + + + + + + + + Contract Address + + + + + {unsupportedAssets.map((asset) => ( + + ))} + + + + + + + ); +}; diff --git a/src/lib/pages/contract-details/components/token/TokenSection.tsx b/src/lib/pages/contract-details/components/token/TokenSection.tsx index a467b2a4b..1d650ae9c 100644 --- a/src/lib/pages/contract-details/components/token/TokenSection.tsx +++ b/src/lib/pages/contract-details/components/token/TokenSection.tsx @@ -1,7 +1,8 @@ -import { Grid, Text } from "@chakra-ui/react"; +import { Flex, Grid, Text } from "@chakra-ui/react"; import { useMemo, useState } from "react"; import { ShowMoreButton } from "lib/components/button"; +import { UnsupportedTokensModal } from "lib/components/modal/UnsupportedTokensModal"; import type { BalanceWithAssetInfo, Option } from "lib/types"; import { TokenCard } from "./TokenCard"; @@ -11,6 +12,11 @@ interface TokenSectionProps { } export const TokenSection = ({ balances }: TokenSectionProps) => { const [showMore, setShowMore] = useState(false); + const unsupportedAssets = useMemo( + () => balances?.filter((balance) => !balance.assetInfo) ?? [], + [balances] + ); + const supportedAssets = useMemo( () => balances?.filter((balance) => balance.assetInfo) ?? [], [balances] @@ -25,7 +31,14 @@ export const TokenSection = ({ balances }: TokenSectionProps) => { return ( <> - {/* TODO - Implement unsupported assets */} + + + Assets + + {unsupportedAssets.length !== 0 && ( + + )} + {supportedAssets.map((balance, index) => { if (!showMore && index >= 4) { diff --git a/src/lib/pages/contract-details/index.tsx b/src/lib/pages/contract-details/index.tsx index 7831840a6..393fe5a6a 100644 --- a/src/lib/pages/contract-details/index.tsx +++ b/src/lib/pages/contract-details/index.tsx @@ -5,7 +5,6 @@ import { Tabs, TabPanels, TabPanel, - Text, } from "@chakra-ui/react"; import { observer } from "mobx-react-lite"; import { useRouter } from "next/router"; @@ -58,9 +57,6 @@ const ContractDetailsBody = observer( {/* Tokens Section */} - - Assets - {/* Contract Description Section */} diff --git a/src/lib/utils/formatter/index.ts b/src/lib/utils/formatter/index.ts index 186256c30..6533c4090 100644 --- a/src/lib/utils/formatter/index.ts +++ b/src/lib/utils/formatter/index.ts @@ -4,3 +4,4 @@ export * from "./denom"; export * from "./camelToSnake"; export * from "./snakeToCamel"; export * from "./formatBalanceWithDenom"; +export * from "./tokenType"; diff --git a/src/lib/utils/formatter/tokenType.ts b/src/lib/utils/formatter/tokenType.ts new file mode 100644 index 000000000..00e8a3bad --- /dev/null +++ b/src/lib/utils/formatter/tokenType.ts @@ -0,0 +1,9 @@ +export const tokenType = (type: string) => { + switch (type.toLowerCase()) { + case "ibc": + case "cw20": + return type.toUpperCase(); + default: + return type.charAt(0).toUpperCase() + type.slice(1).toLowerCase(); + } +}; From 1729e7d13b005572c065f6d8cc868cd6b6b25f12 Mon Sep 17 00:00:00 2001 From: bkioshn Date: Tue, 17 Jan 2023 16:30:51 +0700 Subject: [PATCH 2/9] fix: disappear Assets text --- .../modal/UnsupportedTokensModal.tsx | 2 +- .../components/token/TokenSection.tsx | 48 +++++++++++-------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx index 5c8fb4499..c82eff1fa 100644 --- a/src/lib/components/modal/UnsupportedTokensModal.tsx +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -44,7 +44,7 @@ const UnsupportedToken = ({ balance }: UnsupportedTokenProps) => { return ( - + {label()} diff --git a/src/lib/pages/contract-details/components/token/TokenSection.tsx b/src/lib/pages/contract-details/components/token/TokenSection.tsx index 1d650ae9c..f9b06a3c5 100644 --- a/src/lib/pages/contract-details/components/token/TokenSection.tsx +++ b/src/lib/pages/contract-details/components/token/TokenSection.tsx @@ -22,12 +22,35 @@ export const TokenSection = ({ balances }: TokenSectionProps) => { [balances] ); - if (!balances?.length) + const renderContext = () => { + if (!balances?.length) { + return ( + + This contract does not hold any assets + + ); + } return ( - - This contract does not hold any assets - + <> + + {supportedAssets.map((balance, index) => { + if (!showMore && index >= 4) { + return null; + } + return ; + })} + + {supportedAssets.length > 4 && ( + setShowMore(!showMore)} + /> + )} + ); + }; return ( <> @@ -39,22 +62,7 @@ export const TokenSection = ({ balances }: TokenSectionProps) => { )} - - {supportedAssets.map((balance, index) => { - if (!showMore && index >= 4) { - return null; - } - return ; - })} - - {supportedAssets.length > 4 && ( - setShowMore(!showMore)} - /> - )} + {renderContext()} ); }; From e365196f4f32002f0965d134b331d73508aea4f0 Mon Sep 17 00:00:00 2001 From: bkioshn Date: Tue, 17 Jan 2023 16:48:42 +0700 Subject: [PATCH 3/9] chore: add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec5eacc80..180051ce2 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 +- [#94](https://github.com/alleslabs/celatone-frontend/pull/94) Add unsupported assets in contract details page - [#90](https://github.com/alleslabs/celatone-frontend/pull/90) Add update admin (`/admin`) and migrate (`/migrate`) page routes - [#91](https://github.com/alleslabs/celatone-frontend/pull/91) Add migrate shortcut to the sidebar - [#75](https://github.com/alleslabs/celatone-frontend/pull/75) Add code-related contracts table to the code detail page From f744b6f3b6d61c120e21735eb7fd958d56574113 Mon Sep 17 00:00:00 2001 From: bkioshn Date: Tue, 17 Jan 2023 16:53:26 +0700 Subject: [PATCH 4/9] style: fix unsupported token hovering --- src/lib/components/modal/UnsupportedTokensModal.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx index c82eff1fa..1ee2605bb 100644 --- a/src/lib/components/modal/UnsupportedTokensModal.tsx +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -42,9 +42,15 @@ const UnsupportedToken = ({ balance }: UnsupportedTokenProps) => { const label = () => (splitId.length === 1 ? balance.id : splitId.join("/")); return ( - + - + {label()} @@ -79,7 +85,7 @@ export const UnsupportedTokensModal = ({ {" "} + From 4903c15b05f9be41f0ece2e55b55b5b0204c7dae Mon Sep 17 00:00:00 2001 From: bkioshn Date: Tue, 17 Jan 2023 22:26:10 +0700 Subject: [PATCH 5/9] fix: add useMemo to tokenLabel and tokenType, change name for getTokenType --- .../modal/UnsupportedTokensModal.tsx | 32 +++++++++++-------- src/lib/utils/formatter/tokenType.ts | 2 +- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx index 1ee2605bb..639253a01 100644 --- a/src/lib/components/modal/UnsupportedTokensModal.tsx +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -14,13 +14,13 @@ import { Box, } from "@chakra-ui/react"; import router from "next/router"; -import { useCallback } from "react"; +import { useCallback, useMemo } from "react"; import { FaDollarSign } from "react-icons/fa"; import { Copier } from "../Copier"; import { ExplorerLink } from "../ExplorerLink"; import type { BalanceWithAssetInfo, Balance } from "lib/types"; -import { getFirstQueryParam, tokenType, truncate } from "lib/utils"; +import { getFirstQueryParam, getTokenType, truncate } from "lib/utils"; import { formatToken } from "lib/utils/formatter/token"; interface UnsupportedTokensModalProps { @@ -32,14 +32,17 @@ interface UnsupportedTokenProps { } const UnsupportedToken = ({ balance }: UnsupportedTokenProps) => { - const splitId = balance.id.split("/"); - const type = !balance.id.includes("/") - ? tokenType(balance.type) - : tokenType(splitId[0]); - if (splitId[1]) { - splitId[1] = truncate(splitId[1]); - } - const label = () => (splitId.length === 1 ? balance.id : splitId.join("/")); + const [tokenLabel, tokenType] = useMemo(() => { + const splitId = balance.id.split("/"); + const type = !balance.id.includes("/") + ? getTokenType(balance.type) + : getTokenType(splitId[0]); + if (splitId[1]) { + splitId[1] = truncate(splitId[1]); + } + const label = splitId.length === 1 ? balance.id : splitId.join("/"); + return [label, type]; + }, [balance]); return ( { - {label()} + {tokenLabel} - {`${type} Token`} + {`${tokenType} Token`} @@ -117,7 +120,10 @@ export const UnsupportedTokensModal = ({ {unsupportedAssets.map((asset) => ( - + ))} diff --git a/src/lib/utils/formatter/tokenType.ts b/src/lib/utils/formatter/tokenType.ts index 00e8a3bad..3a829984c 100644 --- a/src/lib/utils/formatter/tokenType.ts +++ b/src/lib/utils/formatter/tokenType.ts @@ -1,4 +1,4 @@ -export const tokenType = (type: string) => { +export const getTokenType = (type: string) => { switch (type.toLowerCase()) { case "ibc": case "cw20": From 85188f9dd4ee423e24f894e626e9bd6f923e2031 Mon Sep 17 00:00:00 2001 From: bkioshn Date: Thu, 19 Jan 2023 13:02:48 +0700 Subject: [PATCH 6/9] fix: remove numeral lib and use regex , change icon --- package.json | 1 - src/lib/components/modal/UnsupportedTokensModal.tsx | 12 ++++-------- src/lib/utils/formatter/token.ts | 4 ++-- yarn.lock | 5 ----- 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index b85036860..8f8c60a07 100644 --- a/package.json +++ b/package.json @@ -60,7 +60,6 @@ "next": "^13.0.0", "next-pwa": "^5.6.0", "next-seo": "^5.8.0", - "numeral": "^2.0.6", "react": "^18.2.0", "react-ace": "^10.1.0", "react-dom": "^18.2.0", diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx index 639253a01..d2a11003d 100644 --- a/src/lib/components/modal/UnsupportedTokensModal.tsx +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -14,8 +14,8 @@ import { Box, } from "@chakra-ui/react"; import router from "next/router"; -import { useCallback, useMemo } from "react"; -import { FaDollarSign } from "react-icons/fa"; +import { useMemo } from "react"; +import { MdAttachMoney } from "react-icons/md"; import { Copier } from "../Copier"; import { ExplorerLink } from "../ExplorerLink"; @@ -79,10 +79,6 @@ export const UnsupportedTokensModal = ({ const { isOpen, onOpen, onClose } = useDisclosure(); - const handleOnOther = useCallback(() => { - onClose(); - }, [onClose]); - return ( <> @@ -90,7 +86,7 @@ export const UnsupportedTokensModal = ({ {`View ${unsupportedAssets.length} Unsupported Assets`} - + onClose()} isCentered> @@ -102,7 +98,7 @@ export const UnsupportedTokensModal = ({ pl={2} pt={1} > - + Unsupported Assets diff --git a/src/lib/utils/formatter/token.ts b/src/lib/utils/formatter/token.ts index d95254211..d38511a10 100644 --- a/src/lib/utils/formatter/token.ts +++ b/src/lib/utils/formatter/token.ts @@ -1,6 +1,5 @@ import type { BigSource } from "big.js"; import big from "big.js"; -import numeral from "numeral"; export const formatDemimal = ({ @@ -23,8 +22,9 @@ export const formatDemimal = if (num === "NaN") return fallbackValue; const [i, d] = num.split("."); + const thousands = /\B(?=(\d{3})+(?!\d))/g; - const ii = delimiter ? numeral(i).format("0,0") : i; + const ii = delimiter ? i.replace(thousands, ",") : i; const dd = d ? `.${d}` : ""; return (ii === "0" && num[0] === "-" ? "-" : "") + ii + dd; diff --git a/yarn.lock b/yarn.lock index 3deddd2bc..25487a9b5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8326,11 +8326,6 @@ nullthrows@^1.1.1: resolved "https://registry.npmjs.org/nullthrows/-/nullthrows-1.1.1.tgz" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== -numeral@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/numeral/-/numeral-2.0.6.tgz#4ad080936d443c2561aed9f2197efffe25f4e506" - integrity sha512-qaKRmtYPZ5qdw4jWJD6bxEf1FJEqllJrwxCLIm0sQU/A7v2/czigzOb+C2uSiFsa9lBUzeH7M1oK+Q+OLxL3kA== - object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" From b8967046db2839b2616860223b69b825cc49536d Mon Sep 17 00:00:00 2001 From: bkioshn Date: Fri, 20 Jan 2023 11:49:41 +0700 Subject: [PATCH 7/9] style: remove padding, change modal width --- src/lib/components/modal/UnsupportedTokensModal.tsx | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx index d2a11003d..2b70fe52e 100644 --- a/src/lib/components/modal/UnsupportedTokensModal.tsx +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -88,16 +88,9 @@ export const UnsupportedTokensModal = ({ onClose()} isCentered> - + - + Unsupported Assets From 6109c3d0d78b4d65192034d6f75506da2797b93d Mon Sep 17 00:00:00 2001 From: bkioshn Date: Fri, 20 Jan 2023 17:02:18 +0700 Subject: [PATCH 8/9] chore: add comment, fix import, fix display logic --- src/lib/components/modal/UnsupportedTokensModal.tsx | 13 ++++++++++--- .../components/token/TokenSection.tsx | 4 +--- src/lib/utils/formatter/index.ts | 1 + 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/lib/components/modal/UnsupportedTokensModal.tsx b/src/lib/components/modal/UnsupportedTokensModal.tsx index 2b70fe52e..a260cd59f 100644 --- a/src/lib/components/modal/UnsupportedTokensModal.tsx +++ b/src/lib/components/modal/UnsupportedTokensModal.tsx @@ -20,8 +20,12 @@ import { MdAttachMoney } from "react-icons/md"; import { Copier } from "../Copier"; import { ExplorerLink } from "../ExplorerLink"; import type { BalanceWithAssetInfo, Balance } from "lib/types"; -import { getFirstQueryParam, getTokenType, truncate } from "lib/utils"; -import { formatToken } from "lib/utils/formatter/token"; +import { + getFirstQueryParam, + getTokenType, + truncate, + formatToken, +} from "lib/utils"; interface UnsupportedTokensModalProps { unsupportedAssets: BalanceWithAssetInfo[]; @@ -32,6 +36,7 @@ interface UnsupportedTokenProps { } const UnsupportedToken = ({ balance }: UnsupportedTokenProps) => { + // TODO - Move this to utils const [tokenLabel, tokenType] = useMemo(() => { const splitId = balance.id.split("/"); const type = !balance.id.includes("/") @@ -79,6 +84,8 @@ export const UnsupportedTokensModal = ({ const { isOpen, onOpen, onClose } = useDisclosure(); + if (unsupportedAssets.length === 0) return null; + return ( <> @@ -86,7 +93,7 @@ export const UnsupportedTokensModal = ({ {`View ${unsupportedAssets.length} Unsupported Assets`} - onClose()} isCentered> + diff --git a/src/lib/pages/contract-details/components/token/TokenSection.tsx b/src/lib/pages/contract-details/components/token/TokenSection.tsx index f9b06a3c5..3b19ab29e 100644 --- a/src/lib/pages/contract-details/components/token/TokenSection.tsx +++ b/src/lib/pages/contract-details/components/token/TokenSection.tsx @@ -58,9 +58,7 @@ export const TokenSection = ({ balances }: TokenSectionProps) => { Assets - {unsupportedAssets.length !== 0 && ( - - )} + {renderContext()} diff --git a/src/lib/utils/formatter/index.ts b/src/lib/utils/formatter/index.ts index 6533c4090..307a42162 100644 --- a/src/lib/utils/formatter/index.ts +++ b/src/lib/utils/formatter/index.ts @@ -5,3 +5,4 @@ export * from "./camelToSnake"; export * from "./snakeToCamel"; export * from "./formatBalanceWithDenom"; export * from "./tokenType"; +export * from "./token"; From 8142b5e109d73e12ffe20b058b68e9cda4fcb19d Mon Sep 17 00:00:00 2001 From: bkioshn Date: Fri, 20 Jan 2023 17:07:10 +0700 Subject: [PATCH 9/9] Merge branch 'develop' into feat/unsupported-tokens --- CHANGELOG.md | 5 + package.json | 1 + src/lib/components/CustomTab.tsx | 2 +- src/lib/components/state/ZeroState.tsx | 4 +- src/lib/data/queries.ts | 24 ++- src/lib/gql/gql.ts | 18 +- src/lib/gql/graphql.ts | 162 ++++++++++++++---- .../components/CodeInfoSection.tsx | 73 ++++---- .../table/contracts/ContractTable.tsx | 12 +- src/lib/pages/code-details/index.tsx | 4 +- src/lib/pages/codes/components/CodesTable.tsx | 4 +- .../components/InstantiateInfo.tsx | 26 +-- .../related-proposals/RelatedProposalsRow.tsx | 2 +- .../tables/related-proposals/StatusChip.tsx | 4 +- src/lib/pages/deploy/index.tsx | 4 +- src/lib/pages/home/components/QuickMenu.tsx | 10 +- .../home/components/RecentActivities.tsx | 5 +- src/lib/pages/instantiate/instantiate.tsx | 6 +- src/lib/pages/past-txs/hooks/useRedo.ts | 6 +- src/lib/pages/past-txs/index.tsx | 2 +- src/lib/services/codeService.ts | 6 +- src/lib/services/contractService.ts | 3 +- src/lib/utils/base64.ts | 5 + yarn.lock | 5 + 24 files changed, 262 insertions(+), 131 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15a7bc544..2995798ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Features - [#94](https://github.com/alleslabs/celatone-frontend/pull/94) Add unsupported assets in contract details page +- [#72](https://github.com/alleslabs/celatone-frontend/pull/72) Fix general wording and grammar +- [#110](https://github.com/alleslabs/celatone-frontend/pull/110) Fix proposal detail rendering +- [#109](https://github.com/alleslabs/celatone-frontend/pull/109) Fix incorrect rendering of zero value badges - [#106](https://github.com/alleslabs/celatone-frontend/pull/106) Add sort alphabetically to query and execute shortcuts - [#88](https://github.com/alleslabs/celatone-frontend/pull/88) Add code snippet for query and execute - [#107](https://github.com/alleslabs/celatone-frontend/pull/107) Remove osmosis mainnet from chain list @@ -104,6 +107,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Bug fixes +- [#111](https://github.com/alleslabs/celatone-frontend/pull/111) Fix recent activities navigation and instantiate encode/decode +- [#105](https://github.com/alleslabs/celatone-frontend/pull/105) Propoerly show instantiator of code contracts and contract in the instantiated list - [#42](https://github.com/alleslabs/celatone-frontend/pull/42) Properly show CTAs on contract-list page and edit zero/disconnected state - [#45](https://github.com/alleslabs/celatone-frontend/pull/45) Add chain ID and code details to contract detail data loader diff --git a/package.json b/package.json index 8f8c60a07..01d1be7f6 100644 --- a/package.json +++ b/package.json @@ -50,6 +50,7 @@ "framer-motion": "^7.6.12", "graphql": "^16.6.0", "graphql-request": "^5.0.0", + "js-base64": "^3.7.4", "localforage": "^1.10.0", "long": "^5.2.1", "map-obj": "^5.0.2", diff --git a/src/lib/components/CustomTab.tsx b/src/lib/components/CustomTab.tsx index 570172c96..2805eb948 100644 --- a/src/lib/components/CustomTab.tsx +++ b/src/lib/components/CustomTab.tsx @@ -33,7 +33,7 @@ export const CustomTab = ({ count, ...restProps }: CustomTabProps) => { > {tabProps.children} - {count && ( + {count !== undefined && ( }} /> - Created contract list and saved contracts are stored in your device only. + Contract lists and saved contracts are stored locally on your device. ); @@ -76,7 +76,7 @@ export const ZeroState = ({ list, isReadOnly }: ZeroStateProps) => { alignContent="center" > {!isWalletConnected && isInstantiatedByMe ? ( - + ) : ( diff --git a/src/lib/data/queries.ts b/src/lib/data/queries.ts index c91da9562..5c4198906 100644 --- a/src/lib/data/queries.ts +++ b/src/lib/data/queries.ts @@ -82,13 +82,19 @@ export const getInstantiatedCountByUserQueryDocument = graphql(` export const getInstantiatedListByUserQueryDocument = graphql(` query getInstantiatedListByUserQueryDocument($walletAddr: String!) { contracts( - where: { transaction: { account: { address: { _eq: $walletAddr } } } } + where: { + accountByInitBy: { address: { _eq: $walletAddr } } + _or: { transaction: { account: { address: { _eq: $walletAddr } } } } + } limit: 500 offset: 0 order_by: { transaction: { block: { timestamp: desc } } } ) { label address + accountByInitBy { + address + } } } `); @@ -103,9 +109,16 @@ export const getInstantiateDetailByContractQueryDocument = graphql(` contract_proposals( where: { proposal: { - type: { _in: ["InstantiateContract", "InstantiateContract2"] } + type: { + _in: [ + "InstantiateContract" + "InstantiateContract2" + "SoftwareUpgrade" + ] + } } } + order_by: { proposal: { id: asc } } limit: 1 ) { proposal { @@ -259,13 +272,16 @@ export const getContractListByCodeId = graphql(` query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) { contracts( where: { code_id: { _eq: $codeId } } - order_by: { transaction: { block: { timestamp: desc } } } + order_by: { id: desc } offset: $offset limit: $pageSize ) { address label - transaction { + init_by: contract_histories( + order_by: { block: { timestamp: asc } } + limit: 1 + ) { block { timestamp } diff --git a/src/lib/gql/gql.ts b/src/lib/gql/gql.ts index d044531c6..82d9d4ae4 100644 --- a/src/lib/gql/gql.ts +++ b/src/lib/gql/gql.ts @@ -13,9 +13,9 @@ const documents = { types.GetCodeListByIDsQueryDocument, "\n query getInstantiatedCountByUserQueryDocument($walletAddr: String!) {\n contracts_aggregate(\n where: { transaction: { account: { address: { _eq: $walletAddr } } } }\n ) {\n aggregate {\n count\n }\n }\n }\n": types.GetInstantiatedCountByUserQueryDocumentDocument, - "\n query getInstantiatedListByUserQueryDocument($walletAddr: String!) {\n contracts(\n where: { transaction: { account: { address: { _eq: $walletAddr } } } }\n limit: 500\n offset: 0\n order_by: { transaction: { block: { timestamp: desc } } }\n ) {\n label\n address\n }\n }\n": + "\n query getInstantiatedListByUserQueryDocument($walletAddr: String!) {\n contracts(\n where: {\n accountByInitBy: { address: { _eq: $walletAddr } }\n _or: { transaction: { account: { address: { _eq: $walletAddr } } } }\n }\n limit: 500\n offset: 0\n order_by: { transaction: { block: { timestamp: desc } } }\n ) {\n label\n address\n accountByInitBy {\n address\n }\n }\n }\n": types.GetInstantiatedListByUserQueryDocumentDocument, - '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: { _in: ["InstantiateContract", "InstantiateContract2"] }\n }\n }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n': + '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n': types.GetInstantiateDetailByContractQueryDocumentDocument, "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n": types.GetExecuteTxsByContractAddressDocument, @@ -31,7 +31,7 @@ const documents = { types.GetRelatedProposalsCountByContractAddressDocument, "\n query getContractListByAdmin($address: String!) {\n contracts(\n where: { account: { address: { _eq: $address } } }\n order_by: { id: desc }\n ) {\n address\n label\n accountByInitBy {\n address\n }\n }\n }\n": types.GetContractListByAdminDocument, - "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n": + "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n": types.GetContractListByCodeIdDocument, "\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n": types.GetContractListCountByCodeIdDocument, @@ -59,11 +59,11 @@ export function graphql( source: "\n query getInstantiatedCountByUserQueryDocument($walletAddr: String!) {\n contracts_aggregate(\n where: { transaction: { account: { address: { _eq: $walletAddr } } } }\n ) {\n aggregate {\n count\n }\n }\n }\n" ): typeof documents["\n query getInstantiatedCountByUserQueryDocument($walletAddr: String!) {\n contracts_aggregate(\n where: { transaction: { account: { address: { _eq: $walletAddr } } } }\n ) {\n aggregate {\n count\n }\n }\n }\n"]; export function graphql( - source: "\n query getInstantiatedListByUserQueryDocument($walletAddr: String!) {\n contracts(\n where: { transaction: { account: { address: { _eq: $walletAddr } } } }\n limit: 500\n offset: 0\n order_by: { transaction: { block: { timestamp: desc } } }\n ) {\n label\n address\n }\n }\n" -): typeof documents["\n query getInstantiatedListByUserQueryDocument($walletAddr: String!) {\n contracts(\n where: { transaction: { account: { address: { _eq: $walletAddr } } } }\n limit: 500\n offset: 0\n order_by: { transaction: { block: { timestamp: desc } } }\n ) {\n label\n address\n }\n }\n"]; + source: "\n query getInstantiatedListByUserQueryDocument($walletAddr: String!) {\n contracts(\n where: {\n accountByInitBy: { address: { _eq: $walletAddr } }\n _or: { transaction: { account: { address: { _eq: $walletAddr } } } }\n }\n limit: 500\n offset: 0\n order_by: { transaction: { block: { timestamp: desc } } }\n ) {\n label\n address\n accountByInitBy {\n address\n }\n }\n }\n" +): typeof documents["\n query getInstantiatedListByUserQueryDocument($walletAddr: String!) {\n contracts(\n where: {\n accountByInitBy: { address: { _eq: $walletAddr } }\n _or: { transaction: { account: { address: { _eq: $walletAddr } } } }\n }\n limit: 500\n offset: 0\n order_by: { transaction: { block: { timestamp: desc } } }\n ) {\n label\n address\n accountByInitBy {\n address\n }\n }\n }\n"]; export function graphql( - source: '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: { _in: ["InstantiateContract", "InstantiateContract2"] }\n }\n }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n' -): typeof documents['\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: { _in: ["InstantiateContract", "InstantiateContract2"] }\n }\n }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n']; + source: '\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n' +): typeof documents['\n query getInstantiateDetailByContractQueryDocument($contractAddress: String!) {\n contracts_by_pk(address: $contractAddress) {\n init_msg\n transaction {\n hash\n }\n contract_proposals(\n where: {\n proposal: {\n type: {\n _in: [\n "InstantiateContract"\n "InstantiateContract2"\n "SoftwareUpgrade"\n ]\n }\n }\n }\n order_by: { proposal: { id: asc } }\n limit: 1\n ) {\n proposal {\n id\n title\n }\n }\n }\n }\n']; export function graphql( source: "\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n" ): typeof documents["\n query getExecuteTxsByContractAddress(\n $contractAddress: String!\n $offset: Int!\n $pageSize: Int!\n ) {\n contract_transactions(\n where: {\n contract: { address: { _eq: $contractAddress } }\n transaction: { is_execute: { _eq: true } }\n }\n order_by: { transaction: { block: { timestamp: desc } } }\n limit: $pageSize\n offset: $offset\n ) {\n transaction {\n hash\n messages\n success\n account {\n address\n }\n block {\n height\n timestamp\n }\n }\n }\n }\n"]; @@ -86,8 +86,8 @@ export function graphql( source: "\n query getContractListByAdmin($address: String!) {\n contracts(\n where: { account: { address: { _eq: $address } } }\n order_by: { id: desc }\n ) {\n address\n label\n accountByInitBy {\n address\n }\n }\n }\n" ): typeof documents["\n query getContractListByAdmin($address: String!) {\n contracts(\n where: { account: { address: { _eq: $address } } }\n order_by: { id: desc }\n ) {\n address\n label\n accountByInitBy {\n address\n }\n }\n }\n"]; export function graphql( - source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n" -): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { transaction: { block: { timestamp: desc } } }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n transaction {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"]; + source: "\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n" +): typeof documents["\n query getContractListByCodeId($codeId: Int!, $offset: Int!, $pageSize: Int!) {\n contracts(\n where: { code_id: { _eq: $codeId } }\n order_by: { id: desc }\n offset: $offset\n limit: $pageSize\n ) {\n address\n label\n init_by: contract_histories(\n order_by: { block: { timestamp: asc } }\n limit: 1\n ) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n contract_histories(order_by: { block: { timestamp: desc } }, limit: 1) {\n block {\n timestamp\n }\n account {\n address\n }\n }\n }\n }\n"]; export function graphql( source: "\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n" ): typeof documents["\n query getContractListCountByCodeId($codeId: Int!) {\n contracts_aggregate(where: { code_id: { _eq: $codeId } }) {\n aggregate {\n count\n }\n }\n }\n"]; diff --git a/src/lib/gql/graphql.ts b/src/lib/gql/graphql.ts index 20919cd04..7980aad7b 100644 --- a/src/lib/gql/graphql.ts +++ b/src/lib/gql/graphql.ts @@ -6345,6 +6345,7 @@ export type GetInstantiatedListByUserQueryDocumentQuery = { __typename?: "contracts"; label: string; address: string; + accountByInitBy?: { __typename?: "accounts"; address: string } | null; }>; }; @@ -6498,11 +6499,11 @@ export type GetContractListByCodeIdQuery = { __typename?: "contracts"; address: string; label: string; - transaction?: { - __typename?: "transactions"; + init_by: Array<{ + __typename?: "contract_histories"; block: { __typename?: "blocks"; timestamp: any }; account: { __typename?: "accounts"; address: string }; - } | null; + }>; contract_histories: Array<{ __typename?: "contract_histories"; block: { __typename?: "blocks"; timestamp: any }; @@ -7152,31 +7153,72 @@ export const GetInstantiatedListByUserQueryDocumentDocument = { fields: [ { kind: "ObjectField", - name: { kind: "Name", value: "transaction" }, + name: { kind: "Name", value: "accountByInitBy" }, value: { kind: "ObjectValue", fields: [ { kind: "ObjectField", - name: { kind: "Name", value: "account" }, + name: { kind: "Name", value: "address" }, value: { kind: "ObjectValue", fields: [ { kind: "ObjectField", - name: { kind: "Name", value: "address" }, + name: { kind: "Name", value: "_eq" }, + value: { + kind: "Variable", + name: { kind: "Name", value: "walletAddr" }, + }, + }, + ], + }, + }, + ], + }, + }, + { + kind: "ObjectField", + name: { kind: "Name", value: "_or" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "transaction" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "account" }, value: { kind: "ObjectValue", fields: [ { kind: "ObjectField", - name: { kind: "Name", value: "_eq" }, + name: { + kind: "Name", + value: "address", + }, value: { - kind: "Variable", - name: { - kind: "Name", - value: "walletAddr", - }, + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { + kind: "Name", + value: "_eq", + }, + value: { + kind: "Variable", + name: { + kind: "Name", + value: "walletAddr", + }, + }, + }, + ], }, }, ], @@ -7239,6 +7281,19 @@ export const GetInstantiatedListByUserQueryDocumentDocument = { selections: [ { kind: "Field", name: { kind: "Name", value: "label" } }, { kind: "Field", name: { kind: "Name", value: "address" } }, + { + kind: "Field", + name: { kind: "Name", value: "accountByInitBy" }, + selectionSet: { + kind: "SelectionSet", + selections: [ + { + kind: "Field", + name: { kind: "Name", value: "address" }, + }, + ], + }, + }, ], }, }, @@ -7344,6 +7399,11 @@ export const GetInstantiateDetailByContractQueryDocumentDocument = { value: "InstantiateContract2", block: false, }, + { + kind: "StringValue", + value: "SoftwareUpgrade", + block: false, + }, ], }, }, @@ -7356,6 +7416,29 @@ export const GetInstantiateDetailByContractQueryDocumentDocument = { ], }, }, + { + kind: "Argument", + name: { kind: "Name", value: "order_by" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "proposal" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "id" }, + value: { kind: "EnumValue", value: "asc" }, + }, + ], + }, + }, + ], + }, + }, { kind: "Argument", name: { kind: "Name", value: "limit" }, @@ -8472,26 +8555,8 @@ export const GetContractListByCodeIdDocument = { fields: [ { kind: "ObjectField", - name: { kind: "Name", value: "transaction" }, - value: { - kind: "ObjectValue", - fields: [ - { - kind: "ObjectField", - name: { kind: "Name", value: "block" }, - value: { - kind: "ObjectValue", - fields: [ - { - kind: "ObjectField", - name: { kind: "Name", value: "timestamp" }, - value: { kind: "EnumValue", value: "desc" }, - }, - ], - }, - }, - ], - }, + name: { kind: "Name", value: "id" }, + value: { kind: "EnumValue", value: "desc" }, }, ], }, @@ -8520,7 +8585,38 @@ export const GetContractListByCodeIdDocument = { { kind: "Field", name: { kind: "Name", value: "label" } }, { kind: "Field", - name: { kind: "Name", value: "transaction" }, + alias: { kind: "Name", value: "init_by" }, + name: { kind: "Name", value: "contract_histories" }, + arguments: [ + { + kind: "Argument", + name: { kind: "Name", value: "order_by" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "block" }, + value: { + kind: "ObjectValue", + fields: [ + { + kind: "ObjectField", + name: { kind: "Name", value: "timestamp" }, + value: { kind: "EnumValue", value: "asc" }, + }, + ], + }, + }, + ], + }, + }, + { + kind: "Argument", + name: { kind: "Name", value: "limit" }, + value: { kind: "IntValue", value: "1" }, + }, + ], selectionSet: { kind: "SelectionSet", selections: [ diff --git a/src/lib/pages/code-details/components/CodeInfoSection.tsx b/src/lib/pages/code-details/components/CodeInfoSection.tsx index c963e0a9e..1b25bec04 100644 --- a/src/lib/pages/code-details/components/CodeInfoSection.tsx +++ b/src/lib/pages/code-details/components/CodeInfoSection.tsx @@ -6,11 +6,11 @@ import { ExplorerLink } from "lib/components/ExplorerLink"; import { LabelText } from "lib/components/LabelText"; import { PermissionChip } from "lib/components/PermissionChip"; import { useGetAddressType } from "lib/hooks"; -import type { CodeData, Option, PermissionAddresses } from "lib/types"; +import type { CodeData, PermissionAddresses } from "lib/types"; import { dateFromNow, formatUTC, getAddressTypeText } from "lib/utils"; interface CodeInfoSectionProps { - codeData: Option; + codeData: CodeData; } const getMethodSpecificRender = ( @@ -120,7 +120,7 @@ const ViewAddresses = ({ ); }; -const CodeDetailsRender = ({ codeData }: { codeData: CodeData }) => { +export const CodeInfoSection = ({ codeData }: CodeInfoSectionProps) => { const getAddressType = useGetAddressType(); const { hash, @@ -140,49 +140,42 @@ const CodeDetailsRender = ({ codeData }: { codeData: CodeData }) => { } ); const uploaderType = getAddressType(uploader); - return ( - - {codeData.chainId ?? "unknown"} - - - - - {getAddressTypeText(uploaderType)} - - - - {methodRender} - - - - - - - - - {storedBlockRender} - - - - ); -}; -export const CodeInfoSection = ({ codeData }: CodeInfoSectionProps) => { return ( Code Information - {codeData ? ( - - ) : ( - - Error fetching data - - )} + + {codeData.chainId ?? "unknown"} + + + + + {getAddressTypeText(uploaderType)} + + + + {methodRender} + + + + + + + + + {storedBlockRender} + + + ); }; diff --git a/src/lib/pages/code-details/components/table/contracts/ContractTable.tsx b/src/lib/pages/code-details/components/table/contracts/ContractTable.tsx index 6ef07ed1e..83ee9ae12 100644 --- a/src/lib/pages/code-details/components/table/contracts/ContractTable.tsx +++ b/src/lib/pages/code-details/components/table/contracts/ContractTable.tsx @@ -40,13 +40,13 @@ export const ContractTable = observer(({ codeId }: ContractTableProps) => { }, }); - const { data: rawInstantiatedContracts } = useContractListByCodeId( + const { data: rawCodeContracts } = useContractListByCodeId( codeId, offset, pageSize ); - const instantiatedContracts: Option = - rawInstantiatedContracts?.map((contract) => ({ + const codeContracts: Option = + rawCodeContracts?.map((contract) => ({ ...contract, ...getContractLocalInfo(contract.contractAddress), })); @@ -81,12 +81,12 @@ export const ContractTable = observer(({ codeId }: ContractTableProps) => { ml={2} variant="primary" textAlign="center" - bg={!instantiatedContracts?.length ? "gray.800" : "primary.dark"} + bg={!codeContracts?.length ? "gray.800" : "primary.dark"} > {totalData} - {!instantiatedContracts?.length ? ( + {!codeContracts?.length ? ( ) : ( @@ -98,7 +98,7 @@ export const ContractTable = observer(({ codeId }: ContractTableProps) => { Timestamp - {instantiatedContracts?.map((contractInfo) => ( + {codeContracts.map((contractInfo) => ( { uploader={localCodeInfo?.uploader ?? codeData.uploader} description={localCodeInfo?.description} instantiatePermission={ - codeData?.instantiatePermission ?? InstantiatePermission.UNKNOWN + codeData.instantiatePermission ?? InstantiatePermission.UNKNOWN } - permissionAddresses={codeData?.permissionAddresses ?? []} + permissionAddresses={codeData.permissionAddresses ?? []} /> diff --git a/src/lib/pages/codes/components/CodesTable.tsx b/src/lib/pages/codes/components/CodesTable.tsx index 0e3548c5d..fd80afc8d 100644 --- a/src/lib/pages/codes/components/CodesTable.tsx +++ b/src/lib/pages/codes/components/CodesTable.tsx @@ -74,7 +74,7 @@ const NotMatched = () => { const Unconnected = () => { return ( - + ); }; @@ -85,7 +85,7 @@ const Empty = ({ type }: OtherTBodyProps) => { case "all": return "All Code IDs will display here"; case "saved": - return "Your saved Code IDs will display here. Saved Codes are stored in your device."; + return "Your saved code IDs will display here. Saved codes are stored locally on your device."; case "stored": return "Your uploaded Wasm files will display as My Stored Codes"; default: diff --git a/src/lib/pages/contract-details/components/InstantiateInfo.tsx b/src/lib/pages/contract-details/components/InstantiateInfo.tsx index e8bab3ff0..c1537da55 100644 --- a/src/lib/pages/contract-details/components/InstantiateInfo.tsx +++ b/src/lib/pages/contract-details/components/InstantiateInfo.tsx @@ -14,6 +14,8 @@ interface InstantiateInfoProps { export const InstantiateInfo = ({ contractData }: InstantiateInfoProps) => { const getAddressType = useGetAddressType(); + // TODO: fix eslint + // eslint-disable-next-line sonarjs/cognitive-complexity const renderDataFound = () => { if (contractData.instantiateInfo) { const instantiatorType = getAddressType( @@ -82,23 +84,27 @@ export const InstantiateInfo = ({ contractData }: InstantiateInfoProps) => { /> - {contractData.initProposalId ? ( - + {contractData.initTxHash ? ( + ) : ( - + )} diff --git a/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx b/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx index 60620abd8..fcf9b21a6 100644 --- a/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx +++ b/src/lib/pages/contract-details/components/tables/related-proposals/RelatedProposalsRow.tsx @@ -43,7 +43,7 @@ const VotingEndTimeRender = ({

( {isDepositPeriod - ? `Deposit Period ends in ${dateFromNow(depositEndTime)}` + ? `Deposit Period ends ${dateFromNow(depositEndTime)}` : dateFromNow(votingEndTime)} )

diff --git a/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx b/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx index 728e9d2c9..f81e1d0d8 100644 --- a/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx +++ b/src/lib/pages/contract-details/components/tables/related-proposals/StatusChip.tsx @@ -23,9 +23,9 @@ const getBgColor = ( return "#BA863A"; case ProposalStatus.FAILED: case ProposalStatus.REJECTED: - return "#F2605B"; + return "rgba(242, 96, 91, 0.6)"; case ProposalStatus.PASSED: - return "#A1E58F"; + return "rgba(161, 229, 143, 0.5)"; case ProposalStatus.VOTING_PERIOD: return "#0288D1"; case ProposalStatus.INACTIVE: diff --git a/src/lib/pages/deploy/index.tsx b/src/lib/pages/deploy/index.tsx index 13b825152..05d6da484 100644 --- a/src/lib/pages/deploy/index.tsx +++ b/src/lib/pages/deploy/index.tsx @@ -18,13 +18,13 @@ const Deploy = () => { navigate({ pathname: "/upload" })} mb="16px" /> navigate({ pathname: "/instantiate" })} /> diff --git a/src/lib/pages/home/components/QuickMenu.tsx b/src/lib/pages/home/components/QuickMenu.tsx index dbd736b52..92174c821 100644 --- a/src/lib/pages/home/components/QuickMenu.tsx +++ b/src/lib/pages/home/components/QuickMenu.tsx @@ -15,13 +15,13 @@ const cardProps = { const secondaryMenu = [ { title: "Query", - subtitle: "Query and get response from smart contract", + subtitle: "Query state data from smart contracts", slug: "query", icon: MdSearch, }, { title: "Execute", - subtitle: "Send execute messages to smart contract", + subtitle: "Send transactions to smart contracts", slug: "execute", icon: MdInput, }, @@ -35,7 +35,7 @@ export const QuickMenu = () => { @@ -49,10 +49,10 @@ export const QuickMenu = () => { > - Deploy new contract + Deploy a new contract - Deploy contract by upload new Wasm file + Upload a new wasm code or instantiate a new contract diff --git a/src/lib/pages/home/components/RecentActivities.tsx b/src/lib/pages/home/components/RecentActivities.tsx index 82d3620e8..2a23da538 100644 --- a/src/lib/pages/home/components/RecentActivities.tsx +++ b/src/lib/pages/home/components/RecentActivities.tsx @@ -39,7 +39,8 @@ export const RecentActivities = observer(() => { key={item.type + item.contractAddress + item.timestamp} onClick={() => navigate({ - pathname: `/${item.type}?contract=${item.contractAddress}&msg=${item.msg}`, + pathname: `/${item.type}`, + query: { contract: item.contractAddress, msg: item.msg }, }) } > @@ -101,7 +102,7 @@ export const RecentActivities = observer(() => { minH="128px" > - Your recent queries will display here. + Your recent interactions will display here. )} diff --git a/src/lib/pages/instantiate/instantiate.tsx b/src/lib/pages/instantiate/instantiate.tsx index 21f137689..466e9a4ea 100644 --- a/src/lib/pages/instantiate/instantiate.tsx +++ b/src/lib/pages/instantiate/instantiate.tsx @@ -29,9 +29,9 @@ import type { HumanAddr, Token, U } from "lib/types"; import { MsgType } from "lib/types"; import { composeMsg, - decode, demicrofy, jsonValidate, + libDecode, microfy, } from "lib/utils"; @@ -171,12 +171,12 @@ const Instantiate = ({ onComplete }: InstantiatePageProps) => { useEffect(() => { if (codeIdQuery) setValue("codeId", codeIdQuery); if (msgQuery) { - const decodedMsg = decode(msgQuery); + const decodedMsg = libDecode(msgQuery); try { const msgObject = JSON.parse(decodedMsg) as InstantiateRedoMsg; - setValue("codeId", String(msgObject.code_id)); reset({ + codeId: msgObject.code_id.toString(), label: msgObject.label, adminAddress: msgObject.admin, initMsg: JSON.stringify(msgObject.msg, null, 2), diff --git a/src/lib/pages/past-txs/hooks/useRedo.ts b/src/lib/pages/past-txs/hooks/useRedo.ts index 61a211729..4a2b3227c 100644 --- a/src/lib/pages/past-txs/hooks/useRedo.ts +++ b/src/lib/pages/past-txs/hooks/useRedo.ts @@ -2,7 +2,7 @@ import { useCallback } from "react"; import { useInternalNavigate } from "lib/app-provider"; import type { Msg } from "lib/types"; -import { encode, camelToSnake } from "lib/utils"; +import { libEncode, camelToSnake } from "lib/utils"; export const useRedo = () => { const navigate = useInternalNavigate(); @@ -17,13 +17,13 @@ export const useRedo = () => { e.stopPropagation(); if (!type || !msg) return null; if (type === "MsgExecuteContract") { - const encodeMsg = encode(JSON.stringify(camelToSnake(msg.msg))); + const encodeMsg = libEncode(JSON.stringify(camelToSnake(msg.msg))); navigate({ pathname: "/execute", query: { chainName, contract: msg.contract, msg: encodeMsg }, }); } else if (type === "MsgInstantiateContract") { - const encodeMsg = encode(JSON.stringify(camelToSnake(msg))); + const encodeMsg = libEncode(JSON.stringify(camelToSnake(msg))); navigate({ pathname: "/instantiate", query: { chainName, msg: encodeMsg }, diff --git a/src/lib/pages/past-txs/index.tsx b/src/lib/pages/past-txs/index.tsx index 6f8571494..4a0b40954 100644 --- a/src/lib/pages/past-txs/index.tsx +++ b/src/lib/pages/past-txs/index.tsx @@ -178,7 +178,7 @@ const PastTxs = () => { > ); diff --git a/src/lib/services/codeService.ts b/src/lib/services/codeService.ts index 757a940ef..f1e42451d 100644 --- a/src/lib/services/codeService.ts +++ b/src/lib/services/codeService.ts @@ -158,9 +158,11 @@ export const useContractListByCodeId = ( .then(({ contracts }) => contracts.map((contract) => ({ contractAddress: contract.address as ContractAddr, - instantiator: unwrap(contract.transaction?.account.address), + instantiator: unwrap(contract.init_by.at(0)?.account.address), label: contract.label, - instantiated: parseDateDefault(contract.transaction?.block.timestamp), + instantiated: parseDateDefault( + contract.init_by.at(0)?.block.timestamp + ), // TODO: handle Genesis case latestUpdator: contract.contract_histories.at(0)?.account.address, latestUpdated: parseDateDefault( diff --git a/src/lib/services/contractService.ts b/src/lib/services/contractService.ts index b342ccdbb..ae0432842 100644 --- a/src/lib/services/contractService.ts +++ b/src/lib/services/contractService.ts @@ -37,6 +37,7 @@ import { parseTxHash, parseTxHashOpt, snakeToCamel, + unwrap, } from "lib/utils"; interface InstantiateDetail { @@ -79,7 +80,7 @@ export const useInstantiatedListByUserQuery = ( .then(({ contracts }) => contracts.map((contract) => ({ contractAddress: contract.address as ContractAddr, - instantiator: walletAddr, + instantiator: unwrap(contract.accountByInitBy?.address), label: contract.label, })) ); diff --git a/src/lib/utils/base64.ts b/src/lib/utils/base64.ts index ec85e7672..ef4d43978 100644 --- a/src/lib/utils/base64.ts +++ b/src/lib/utils/base64.ts @@ -1,3 +1,8 @@ +export { encode as libEncode, decode as libDecode } from "js-base64"; + +/** + * @todos Change the whole project encode/decode function to use from lib + */ export const decode = (str: string): string => Buffer.from(str, "base64").toString("binary"); diff --git a/yarn.lock b/yarn.lock index 25487a9b5..17be17990 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7429,6 +7429,11 @@ jest-worker@^27.4.5: merge-stream "^2.0.0" supports-color "^8.0.0" +js-base64@^3.7.4: + version "3.7.4" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.4.tgz#af95b20f23efc8034afd2d1cc5b9d0adf7419037" + integrity sha512-wpM/wi20Tl+3ifTyi0RdDckS4YTD4Lf953mBRrpG8547T7hInHNPEj8+ck4gB8VDcGyeAWFK++Wb/fU1BeavKQ== + js-crypto-env@^0.3.2: version "0.3.2" resolved "https://registry.npmjs.org/js-crypto-env/-/js-crypto-env-0.3.2.tgz"