From 11c83736a60ae5801ed12272fde9c50c8ef5a8fc Mon Sep 17 00:00:00 2001 From: evilpeach Date: Wed, 12 Jun 2024 16:34:16 +0700 Subject: [PATCH 1/5] feat: base + wasm account details page --- src/config/chain/osmosis.ts | 4 +- .../modal/account/SaveNewAccount.tsx | 2 +- .../components/AccountHeader.tsx | 2 +- .../tables/InstantiatedContractsTable.tsx | 127 ----------- .../components/tables/index.ts | 2 +- .../tables/instantiated-contracts/Full.tsx | 118 +++++++++++ .../tables/instantiated-contracts/Lite.tsx | 71 +++++++ .../tables/instantiated-contracts/index.tsx | 19 ++ .../tables/instantiated-contracts/types.ts | 9 + .../components/tables/txs/Full.tsx | 189 +++++++++++++++++ .../components/tables/txs/Lite.tsx | 98 +++++++++ .../components/tables/txs/index.tsx | 198 +----------------- .../components/tables/txs/types.ts | 8 + src/lib/pages/account-details/data.ts | 49 ++++- src/lib/pages/account-details/index.tsx | 60 +++--- .../components/tables/index.tsx | 18 +- src/lib/services/account.ts | 56 ----- src/lib/services/account/api.ts | 29 +++ src/lib/services/account/gql.ts | 42 ++++ src/lib/services/account/index.ts | 57 +++++ src/lib/services/account/lcd.ts | 17 ++ src/lib/services/accountService.ts | 83 -------- src/lib/services/bank/index.ts | 4 +- src/lib/services/tx/index.ts | 6 +- src/lib/services/types/account.ts | 31 +++ src/lib/services/types/index.ts | 1 + src/lib/services/wasm/contract/index.ts | 10 +- src/lib/services/wasm/contract/lcd.ts | 4 +- 28 files changed, 798 insertions(+), 516 deletions(-) delete mode 100644 src/lib/pages/account-details/components/tables/InstantiatedContractsTable.tsx create mode 100644 src/lib/pages/account-details/components/tables/instantiated-contracts/Full.tsx create mode 100644 src/lib/pages/account-details/components/tables/instantiated-contracts/Lite.tsx create mode 100644 src/lib/pages/account-details/components/tables/instantiated-contracts/index.tsx create mode 100644 src/lib/pages/account-details/components/tables/instantiated-contracts/types.ts create mode 100644 src/lib/pages/account-details/components/tables/txs/Full.tsx create mode 100644 src/lib/pages/account-details/components/tables/txs/Lite.tsx create mode 100644 src/lib/pages/account-details/components/tables/txs/types.ts delete mode 100644 src/lib/services/account.ts create mode 100644 src/lib/services/account/api.ts create mode 100644 src/lib/services/account/gql.ts create mode 100644 src/lib/services/account/index.ts create mode 100644 src/lib/services/account/lcd.ts delete mode 100644 src/lib/services/accountService.ts create mode 100644 src/lib/services/types/account.ts diff --git a/src/config/chain/osmosis.ts b/src/config/chain/osmosis.ts index ed53dcfad..85c205677 100644 --- a/src/config/chain/osmosis.ts +++ b/src/config/chain/osmosis.ts @@ -52,13 +52,13 @@ export const OSMOSIS_CHAIN_CONFIGS: ChainConfigs = { extra: {}, }, "osmo-test-5": { - tier: "full", + tier: "lite", chain: "osmosis", registryChainName: "osmosistestnet", prettyName: "Osmosis Testnet", lcd: "https://lcd.osmotest5.osmosis.zone", rpc: "https://osmosis-testnet-rpc.polkachu.com:443", - indexer: "https://osmo-test-5-graphql.alleslabs.dev/v1/graphql", + indexer: "", wallets: [...keplrWallets], features: { faucet: { diff --git a/src/lib/components/modal/account/SaveNewAccount.tsx b/src/lib/components/modal/account/SaveNewAccount.tsx index bbba983a0..5b0ed0df8 100644 --- a/src/lib/components/modal/account/SaveNewAccount.tsx +++ b/src/lib/components/modal/account/SaveNewAccount.tsx @@ -17,7 +17,7 @@ import { ControllerInput, ControllerTextarea } from "lib/components/forms"; import { useGetMaxLengthError, useHandleAccountSave } from "lib/hooks"; import { useFormatAddresses } from "lib/hooks/useFormatAddresses"; import { useAccountStore } from "lib/providers/store"; -import { useAccountType } from "lib/services/accountService"; +import { useAccountType } from "lib/services/account"; import type { BechAddr } from "lib/types"; import { AccountType } from "lib/types"; diff --git a/src/lib/pages/account-details/components/AccountHeader.tsx b/src/lib/pages/account-details/components/AccountHeader.tsx index aad9c6ac5..4834e6b16 100644 --- a/src/lib/pages/account-details/components/AccountHeader.tsx +++ b/src/lib/pages/account-details/components/AccountHeader.tsx @@ -12,7 +12,7 @@ import { import { PrimaryNameMark } from "lib/components/PrimaryNameMark"; import { TotalValue } from "lib/components/TotalValue"; import { useAccountStore } from "lib/providers/store"; -import type { AccountData } from "lib/services/account"; +import type { AccountData } from "lib/services/types"; import type { BechAddr, HexAddr, Option } from "lib/types"; interface AccounHeaderProps { diff --git a/src/lib/pages/account-details/components/tables/InstantiatedContractsTable.tsx b/src/lib/pages/account-details/components/tables/InstantiatedContractsTable.tsx deleted file mode 100644 index 616306cb0..000000000 --- a/src/lib/pages/account-details/components/tables/InstantiatedContractsTable.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import { Box } from "@chakra-ui/react"; -import { observer } from "mobx-react-lite"; -import type { ChangeEvent } from "react"; - -import { useInternalNavigate, useMobile } from "lib/app-provider"; -import { Pagination } from "lib/components/pagination"; -import { usePaginator } from "lib/components/pagination/usePaginator"; -import { EmptyState, ErrorFetching } from "lib/components/state"; -import { - ContractsTable, - MobileTitle, - TableTitle, - ViewMore, -} from "lib/components/table"; -import { useAccountContracts } from "lib/pages/account-details/data"; -import type { BechAddr, BechAddr32, Option } from "lib/types"; - -interface InstantiatedContractsTableProps { - address: BechAddr; - scrollComponentId: string; - totalData: Option; - refetchCount: () => void; - onViewMore?: () => void; -} - -export const InstantiatedContractsTable = observer( - ({ - address, - scrollComponentId, - totalData, - refetchCount, - onViewMore, - }: InstantiatedContractsTableProps) => { - const isMobile = useMobile(); - const navigate = useInternalNavigate(); - const onRowSelect = (contract: BechAddr32) => - navigate({ - pathname: "/contracts/[contract]", - query: { contract }, - }); - - const { - pagesQuantity, - currentPage, - setCurrentPage, - pageSize, - setPageSize, - offset, - } = usePaginator({ - total: totalData, - initialState: { - pageSize: 10, - currentPage: 1, - isDisabled: false, - }, - }); - const { contracts, isLoading } = useAccountContracts( - address, - offset, - onViewMore ? 5 : pageSize - ); - - const onPageChange = (nextPage: number) => { - refetchCount(); - setCurrentPage(nextPage); - }; - - const onPageSizeChange = (e: ChangeEvent) => { - const size = Number(e.target.value); - refetchCount(); - setPageSize(size); - setCurrentPage(1); - }; - - const isMobileOverview = isMobile && !!onViewMore; - return ( - - {isMobileOverview ? ( - - ) : ( - <> - - - ) : ( - - ) - } - onRowSelect={onRowSelect} - /> - - )} - {!!totalData && - (onViewMore - ? totalData > 5 && !isMobile && - : totalData > 10 && ( - - ))} - - ); - } -); diff --git a/src/lib/pages/account-details/components/tables/index.ts b/src/lib/pages/account-details/components/tables/index.ts index 87c868ada..763220921 100644 --- a/src/lib/pages/account-details/components/tables/index.ts +++ b/src/lib/pages/account-details/components/tables/index.ts @@ -1,5 +1,5 @@ export * from "./txs"; export * from "./AdminContractsTable"; -export * from "./InstantiatedContractsTable"; +export * from "./instantiated-contracts"; export * from "./OpenedProposalsTable"; export * from "./StoredCodesTable"; diff --git a/src/lib/pages/account-details/components/tables/instantiated-contracts/Full.tsx b/src/lib/pages/account-details/components/tables/instantiated-contracts/Full.tsx new file mode 100644 index 000000000..2af176080 --- /dev/null +++ b/src/lib/pages/account-details/components/tables/instantiated-contracts/Full.tsx @@ -0,0 +1,118 @@ +import { Box } from "@chakra-ui/react"; +import type { ChangeEvent } from "react"; + +import { useInternalNavigate, useMobile } from "lib/app-provider"; +import { Pagination } from "lib/components/pagination"; +import { usePaginator } from "lib/components/pagination/usePaginator"; +import { EmptyState, ErrorFetching } from "lib/components/state"; +import { + ContractsTable, + MobileTitle, + TableTitle, + ViewMore, +} from "lib/components/table"; +import { useAccountContracts } from "lib/pages/account-details/data"; +import type { BechAddr32 } from "lib/types"; + +import type { InstantiatedContractsTableProps } from "./types"; + +export const InstantiatedContractsTableFull = ({ + address, + scrollComponentId, + totalData, + refetchCount, + onViewMore, +}: InstantiatedContractsTableProps) => { + const isMobile = useMobile(); + const navigate = useInternalNavigate(); + const onRowSelect = (contract: BechAddr32) => + navigate({ + pathname: "/contracts/[contract]", + query: { contract }, + }); + + const { + pagesQuantity, + currentPage, + setCurrentPage, + pageSize, + setPageSize, + offset, + } = usePaginator({ + total: totalData, + initialState: { + pageSize: 10, + currentPage: 1, + isDisabled: false, + }, + }); + const { contracts, isLoading } = useAccountContracts( + address, + offset, + onViewMore ? 5 : pageSize + ); + + const onPageChange = (nextPage: number) => { + refetchCount(); + setCurrentPage(nextPage); + }; + + const onPageSizeChange = (e: ChangeEvent) => { + const size = Number(e.target.value); + refetchCount(); + setPageSize(size); + setCurrentPage(1); + }; + + const isMobileOverview = isMobile && !!onViewMore; + return ( + + {isMobileOverview ? ( + + ) : ( + <> + + + ) : ( + + ) + } + onRowSelect={onRowSelect} + /> + + )} + {!!totalData && + (onViewMore + ? totalData > 5 && !isMobile && + : totalData > 10 && ( + + ))} + + ); +}; diff --git a/src/lib/pages/account-details/components/tables/instantiated-contracts/Lite.tsx b/src/lib/pages/account-details/components/tables/instantiated-contracts/Lite.tsx new file mode 100644 index 000000000..c3e1dd251 --- /dev/null +++ b/src/lib/pages/account-details/components/tables/instantiated-contracts/Lite.tsx @@ -0,0 +1,71 @@ +import { Box } from "@chakra-ui/react"; + +import { useInternalNavigate, useMobile } from "lib/app-provider"; +import { EmptyState, ErrorFetching } from "lib/components/state"; +import { + ContractsTable, + MobileTitle, + TableTitle, + ViewMore, +} from "lib/components/table"; +import { useAccountContractsLcd } from "lib/pages/account-details/data"; +import type { BechAddr32 } from "lib/types"; + +import type { InstantiatedContractsTableProps } from "./types"; + +export const InstantiatedContractsTableLite = ({ + address, + onViewMore, +}: InstantiatedContractsTableProps) => { + const isMobile = useMobile(); + const navigate = useInternalNavigate(); + const onRowSelect = (contract: BechAddr32) => + navigate({ + pathname: "/contracts/[contract]", + query: { contract }, + }); + const { contracts, isLoading } = useAccountContractsLcd(address); + + const contractsCount = contracts?.length; + const isMobileOverview = isMobile && !!onViewMore; + return ( + + {isMobileOverview ? ( + + ) : ( + <> + + + ) : ( + + ) + } + onRowSelect={onRowSelect} + showLastUpdate={false} + /> + + )} + {!!contractsCount && + (onViewMore + ? contractsCount > 5 && !isMobile && + : null)} + + ); +}; diff --git a/src/lib/pages/account-details/components/tables/instantiated-contracts/index.tsx b/src/lib/pages/account-details/components/tables/instantiated-contracts/index.tsx new file mode 100644 index 000000000..61c4c1afe --- /dev/null +++ b/src/lib/pages/account-details/components/tables/instantiated-contracts/index.tsx @@ -0,0 +1,19 @@ +import { observer } from "mobx-react-lite"; + +import { useTierConfig } from "lib/app-provider"; + +import { InstantiatedContractsTableFull } from "./Full"; +import { InstantiatedContractsTableLite } from "./Lite"; +import type { InstantiatedContractsTableProps } from "./types"; + +export const InstantiatedContractsTable = observer( + (props: InstantiatedContractsTableProps) => { + const isFullTier = useTierConfig() === "full"; + + return isFullTier ? ( + + ) : ( + + ); + } +); diff --git a/src/lib/pages/account-details/components/tables/instantiated-contracts/types.ts b/src/lib/pages/account-details/components/tables/instantiated-contracts/types.ts new file mode 100644 index 000000000..c02e39edf --- /dev/null +++ b/src/lib/pages/account-details/components/tables/instantiated-contracts/types.ts @@ -0,0 +1,9 @@ +import type { BechAddr, Option } from "lib/types"; + +export interface InstantiatedContractsTableProps { + address: BechAddr; + scrollComponentId: string; + totalData: Option; + refetchCount: () => void; + onViewMore?: () => void; +} diff --git a/src/lib/pages/account-details/components/tables/txs/Full.tsx b/src/lib/pages/account-details/components/tables/txs/Full.tsx new file mode 100644 index 000000000..9fa36bdc5 --- /dev/null +++ b/src/lib/pages/account-details/components/tables/txs/Full.tsx @@ -0,0 +1,189 @@ +import { Box } from "@chakra-ui/react"; +import { useEffect, useMemo, useState } from "react"; + +import { useCurrentChain, useMobile } from "lib/app-provider"; +import { Pagination } from "lib/components/pagination"; +import { usePaginator } from "lib/components/pagination/usePaginator"; +import type { EmptyStateProps } from "lib/components/state"; +import { EmptyState, ErrorFetching } from "lib/components/state"; +import { MobileTitle, TransactionsTable, ViewMore } from "lib/components/table"; +import { TxFilterSelection } from "lib/components/TxFilterSelection"; +import { TxRelationSelection } from "lib/components/TxRelationSelection"; +import { DEFAULT_TX_FILTERS } from "lib/data"; +import { useTxsByAddress, useTxsCountByAddress } from "lib/services/tx"; +import type { Option, TxFilters } from "lib/types"; + +import { TxsAlert } from "./TxsAlert"; +import { TxsTop } from "./TxsTop"; +import type { TxsTableProps } from "./types"; + +const getEmptyStateProps = (selectedFilters: string[]): EmptyStateProps => + selectedFilters.length + ? { + imageVariant: "not-found", + message: "No past transaction matches found with your input.", + } + : { + message: "No transactions have been submitted by this account before.", + }; + +export const TxsTableFull = ({ + address, + scrollComponentId, + refetchCount, + onViewMore, +}: TxsTableProps) => { + const { + chain: { chain_id: chainId }, + } = useCurrentChain(); + const [isSigner, setIsSigner] = useState>(); + const [filters, setFilters] = useState(DEFAULT_TX_FILTERS); + const isMobile = useMobile(); + + const { + data: rawTxCount, + isLoading: isTxCountLoading, + refetch: refetchTxsCount, + } = useTxsCountByAddress(address, undefined, isSigner, filters); + const txsCount = rawTxCount ?? undefined; + const isTxsCountTimeout = rawTxCount === null; + + const { + pagesQuantity, + currentPage, + setCurrentPage, + pageSize, + setPageSize, + offset, + } = usePaginator({ + total: txsCount, + initialState: { + pageSize: 10, + currentPage: 1, + isDisabled: false, + }, + }); + + const { data: transactions, isLoading } = useTxsByAddress( + address, + undefined, + isSigner, + filters, + onViewMore ? 5 : pageSize, + offset + ); + + const handleOnIsSignerChange = (value: Option) => { + setCurrentPage(1); + setIsSigner(value); + refetchCount(); + }; + + const handleOnFiltersChange = (filter: string, bool: boolean) => { + setCurrentPage(1); + setFilters((prevFilters) => ({ ...prevFilters, [filter]: bool })); + refetchCount(); + }; + + const selectedFilters = useMemo( + () => + Object.keys(filters).filter( + (key) => filters[key as keyof typeof filters] + ), + // eslint-disable-next-line react-hooks/exhaustive-deps + [JSON.stringify(filters)] + ); + + useEffect(() => { + if (isTxsCountTimeout) setPageSize(50); + }, [isTxsCountTimeout, setPageSize]); + + useEffect(() => { + setIsSigner(undefined); + setFilters(DEFAULT_TX_FILTERS); + }, [chainId]); + + const isMobileOverview = isMobile && !!onViewMore; + return ( + + {isMobileOverview ? ( + + ) : ( + <> + + } + txTypeSelection={ + + } + /> + {isTxsCountTimeout && } + {!isMobileOverview && ( + + ) : ( + + ) + } + showRelations + /> + )} + {Boolean(transactions?.items?.length) && + (onViewMore + ? !isTxCountLoading && + (txsCount === undefined || txsCount > 5) && + !isMobile && + : txsCount && + txsCount > 10 && ( + { + setCurrentPage(nextPage); + refetchTxsCount(); + refetchCount(); + }} + onPageSizeChange={(e) => { + const size = Number(e.target.value); + setPageSize(size); + setCurrentPage(1); + refetchTxsCount(); + refetchCount(); + }} + /> + ))} + + )} + + ); +}; diff --git a/src/lib/pages/account-details/components/tables/txs/Lite.tsx b/src/lib/pages/account-details/components/tables/txs/Lite.tsx new file mode 100644 index 000000000..dc32b2500 --- /dev/null +++ b/src/lib/pages/account-details/components/tables/txs/Lite.tsx @@ -0,0 +1,98 @@ +import { Box } from "@chakra-ui/react"; + +import { useMobile } from "lib/app-provider"; +import { Pagination } from "lib/components/pagination"; +import { usePaginator } from "lib/components/pagination/usePaginator"; +import { ErrorFetching } from "lib/components/state"; +import { + MobileTitle, + TableTitle, + TransactionsTable, + ViewMore, +} from "lib/components/table"; +import { useTxsByAddressLcd } from "lib/services/tx"; +import type { BechAddr20 } from "lib/types"; + +import type { TxsTableProps } from "./types"; + +export const TxsTableLite = ({ + address, + scrollComponentId, + onViewMore, +}: TxsTableProps) => { + const isMobile = useMobile(); + + const { + pagesQuantity, + setTotalData, + currentPage, + setCurrentPage, + pageSize, + setPageSize, + offset, + } = usePaginator({ + initialState: { + pageSize: 10, + currentPage: 1, + isDisabled: false, + }, + }); + + const { data, isLoading } = useTxsByAddressLcd( + address as BechAddr20, + undefined, + onViewMore ? 5 : pageSize, + offset, + { + onSuccess: ({ total }) => setTotalData(total), + } + ); + + const isMobileOverview = isMobile && !!onViewMore; + const txsCount = data?.total; + return ( + + {isMobileOverview ? ( + + ) : ( + <> + + {!isMobileOverview && ( + } + showRelations={false} + /> + )} + {Boolean(data?.items?.length) && + (onViewMore + ? !isLoading && + (txsCount === undefined || txsCount > 5) && + !isMobile && + : txsCount && + txsCount > 10 && ( + setCurrentPage(nextPage)} + onPageSizeChange={(e) => { + const size = Number(e.target.value); + setPageSize(size); + setCurrentPage(1); + }} + /> + ))} + + )} + + ); +}; diff --git a/src/lib/pages/account-details/components/tables/txs/index.tsx b/src/lib/pages/account-details/components/tables/txs/index.tsx index b92261765..e22afece7 100644 --- a/src/lib/pages/account-details/components/tables/txs/index.tsx +++ b/src/lib/pages/account-details/components/tables/txs/index.tsx @@ -1,195 +1,11 @@ -import { Box } from "@chakra-ui/react"; -import { useEffect, useMemo, useState } from "react"; +import { useTierConfig } from "lib/app-provider"; -import { useCurrentChain, useMobile } from "lib/app-provider"; -import { Pagination } from "lib/components/pagination"; -import { usePaginator } from "lib/components/pagination/usePaginator"; -import type { EmptyStateProps } from "lib/components/state"; -import { EmptyState, ErrorFetching } from "lib/components/state"; -import { MobileTitle, TransactionsTable, ViewMore } from "lib/components/table"; -import { TxFilterSelection } from "lib/components/TxFilterSelection"; -import { TxRelationSelection } from "lib/components/TxRelationSelection"; -import { DEFAULT_TX_FILTERS } from "lib/data"; -import { useTxsByAddress, useTxsCountByAddress } from "lib/services/tx"; -import type { BechAddr, Option, TxFilters } from "lib/types"; +import { TxsTableFull } from "./Full"; +import { TxsTableLite } from "./Lite"; +import type { TxsTableProps } from "./types"; -import { TxsAlert } from "./TxsAlert"; -import { TxsTop } from "./TxsTop"; +export const TxsTable = (props: TxsTableProps) => { + const isFullTier = useTierConfig() === "full"; -interface TxsTableProps { - address: BechAddr; - scrollComponentId: string; - refetchCount: () => void; - onViewMore?: () => void; -} - -const getEmptyStateProps = (selectedFilters: string[]): EmptyStateProps => - selectedFilters.length - ? { - imageVariant: "not-found", - message: "No past transaction matches found with your input.", - } - : { - message: "No transactions have been submitted by this account before.", - }; - -export const TxsTable = ({ - address, - scrollComponentId, - refetchCount, - onViewMore, -}: TxsTableProps) => { - const { - chain: { chain_id: chainId }, - } = useCurrentChain(); - const [isSigner, setIsSigner] = useState>(); - const [filters, setFilters] = useState(DEFAULT_TX_FILTERS); - const isMobile = useMobile(); - - const { - data: rawTxCount, - isLoading: isTxCountLoading, - refetch: refetchTxsCount, - } = useTxsCountByAddress(address, undefined, isSigner, filters); - const txsCount = rawTxCount ?? undefined; - const isTxsCountTimeout = rawTxCount === null; - - const { - pagesQuantity, - currentPage, - setCurrentPage, - pageSize, - setPageSize, - offset, - } = usePaginator({ - total: txsCount, - initialState: { - pageSize: 10, - currentPage: 1, - isDisabled: false, - }, - }); - - const { data: transactions, isLoading } = useTxsByAddress( - address, - undefined, - isSigner, - filters, - onViewMore ? 5 : pageSize, - offset - ); - - const handleOnIsSignerChange = (value: Option) => { - setCurrentPage(1); - setIsSigner(value); - refetchCount(); - }; - - const handleOnFiltersChange = (filter: string, bool: boolean) => { - setCurrentPage(1); - setFilters((prevFilters) => ({ ...prevFilters, [filter]: bool })); - refetchCount(); - }; - - const selectedFilters = useMemo( - () => - Object.keys(filters).filter( - (key) => filters[key as keyof typeof filters] - ), - // eslint-disable-next-line react-hooks/exhaustive-deps - [JSON.stringify(filters)] - ); - - useEffect(() => { - if (isTxsCountTimeout) setPageSize(50); - }, [isTxsCountTimeout, setPageSize]); - - useEffect(() => { - setIsSigner(undefined); - setFilters(DEFAULT_TX_FILTERS); - }, [chainId]); - - const isMobileOverview = isMobile && !!onViewMore; - return ( - - {isMobileOverview ? ( - - ) : ( - <> - - } - txTypeSelection={ - - } - /> - {isTxsCountTimeout && } - {!isMobileOverview && ( - - ) : ( - - ) - } - showRelations - /> - )} - {Boolean(transactions?.items?.length) && - (onViewMore - ? !isTxCountLoading && - (txsCount === undefined || txsCount > 5) && - !isMobile && - : txsCount && - txsCount > 10 && ( - { - setCurrentPage(nextPage); - refetchTxsCount(); - refetchCount(); - }} - onPageSizeChange={(e) => { - const size = Number(e.target.value); - setPageSize(size); - setCurrentPage(1); - refetchTxsCount(); - refetchCount(); - }} - /> - ))} - - )} - - ); + return isFullTier ? : ; }; diff --git a/src/lib/pages/account-details/components/tables/txs/types.ts b/src/lib/pages/account-details/components/tables/txs/types.ts new file mode 100644 index 000000000..a85818dbe --- /dev/null +++ b/src/lib/pages/account-details/components/tables/txs/types.ts @@ -0,0 +1,8 @@ +import type { BechAddr } from "lib/types"; + +export interface TxsTableProps { + address: BechAddr; + scrollComponentId: string; + refetchCount: () => void; + onViewMore?: () => void; +} diff --git a/src/lib/pages/account-details/data.ts b/src/lib/pages/account-details/data.ts index 21c6422c1..a73386438 100644 --- a/src/lib/pages/account-details/data.ts +++ b/src/lib/pages/account-details/data.ts @@ -1,10 +1,12 @@ +import { useTierConfig } from "lib/app-provider"; import { useCodeStore, useContractStore } from "lib/providers/store"; -import { useAccountTableCounts } from "lib/services/accountService"; +import { useAccountTableCounts } from "lib/services/account"; import { useBalances } from "lib/services/bank"; import { useCodesByAddress } from "lib/services/wasm/code"; import { useAdminContractsByAddress, useInstantiatedContractsByAddress, + useInstantiatedContractsByAddressLcd, } from "lib/services/wasm/contract"; import type { BechAddr, @@ -34,13 +36,29 @@ interface AccountDetailsTableCounts { export const useAccountDetailsTableCounts = ( address: BechAddr ): AccountDetailsTableCounts => { + const isFullTier = useTierConfig() === "full"; const { data, refetch, isLoading: isLoadingAccountTableCounts, - } = useAccountTableCounts(address); + } = useAccountTableCounts(address, { enabled: isFullTier }); const { data: balances, isLoading: isBalancesLoading } = useBalances(address); + if (!isFullTier) { + return { + tableCounts: { + codesCount: undefined, + contractsAdminCount: undefined, + contractsCount: undefined, + txsCount: undefined, + proposalsCount: undefined, + assetsCount: balances?.length, + }, + isLoading: isBalancesLoading, + refetchCounts: refetch, + }; + } + return { tableCounts: { codesCount: data?.code, @@ -92,6 +110,33 @@ export const useAccountContracts = ( }; }; +export const useAccountContractsLcd = (address: BechAddr): AccountContracts => { + const { data: contracts, isLoading } = useInstantiatedContractsByAddressLcd( + address, + true + ); + const { getContractLocalInfo } = useContractStore(); + const data = contracts?.map((contract) => { + const localInfo = getContractLocalInfo(contract.contractAddress); + + return { + ...contract, + name: localInfo?.name, + description: localInfo?.description, + tags: localInfo?.tags, + lists: localInfo?.lists, + admin: undefined, + latestUpdated: undefined, + latestUpdater: undefined, + remark: undefined, + }; + }); + return { + contracts: data, + isLoading, + }; +}; + export const useAccountAdminContracts = ( address: BechAddr, offset: number, diff --git a/src/lib/pages/account-details/index.tsx b/src/lib/pages/account-details/index.tsx index 973ac192a..9b80eadd9 100644 --- a/src/lib/pages/account-details/index.tsx +++ b/src/lib/pages/account-details/index.tsx @@ -17,6 +17,7 @@ import { useInternalNavigate, useMoveConfig, useNftConfig, + useTierConfig, useValidateAddress, useWasmConfig, } from "lib/app-provider"; @@ -28,7 +29,7 @@ import PageContainer from "lib/components/PageContainer"; import { InvalidState } from "lib/components/state"; import { UserDocsLink } from "lib/components/UserDocsLink"; import { useFormatAddresses } from "lib/hooks/useFormatAddresses"; -import { useAccountData } from "lib/services/accountService"; +import { useAccountData } from "lib/services/account"; import { useModulesByAddress } from "lib/services/move/module"; import { useResourcesByAddress } from "lib/services/move/resourceService"; import { useNftsCountByAccount } from "lib/services/nft"; @@ -77,6 +78,7 @@ const AccountDetailsBody = ({ const navigate = useInternalNavigate(); const { address: accountAddress, hex: hexAddress } = formatAddresses(accountAddressParam); + const isFullTier = useTierConfig() === "full"; // ------------------------------------------// // ------------------QUERIES-----------------// @@ -172,7 +174,7 @@ const AccountDetailsBody = ({ isDisabled={nftsCount === 0} onClick={handleTabChange(TabIndex.Nfts, nftsCount)} isLoading={isNftsCountLoading} - hidden={!nft.enabled} + hidden={!nft.enabled || !isFullTier} > NFTs @@ -195,7 +197,7 @@ const AccountDetailsBody = ({ tableCounts.codesCount ?? undefined )} isLoading={isLoadingAccountTableCounts} - hidden={!wasm.enabled} + hidden={!wasm.enabled || !isFullTier} > Codes @@ -219,7 +221,7 @@ const AccountDetailsBody = ({ tableCounts.contractsAdminCount ?? undefined )} isLoading={isLoadingAccountTableCounts} - hidden={!wasm.enabled} + hidden={!wasm.enabled || !isFullTier} > Admins @@ -252,7 +254,7 @@ const AccountDetailsBody = ({ tableCounts.proposalsCount ?? undefined )} isLoading={isLoadingAccountTableCounts} - hidden={!gov.enabled} + hidden={!gov.enabled || !isFullTier} > Proposals @@ -319,7 +321,7 @@ const AccountDetailsBody = ({ )} - {nft.enabled && ( + {nft.enabled && isFullTier && ( {wasm.enabled && ( <> - + {isFullTier && ( + + )} - + {isFullTier && ( + + )} )} {move.enabled && ( @@ -390,7 +396,7 @@ const AccountDetailsBody = ({ /> )} - {gov.enabled && ( + {gov.enabled && isFullTier && ( { Migrations - {isFullTier && ( - - )} + diff --git a/src/lib/services/account.ts b/src/lib/services/account.ts deleted file mode 100644 index fb9eb3b0d..000000000 --- a/src/lib/services/account.ts +++ /dev/null @@ -1,56 +0,0 @@ -import axios from "axios"; -import { z } from "zod"; - -import { zProjectInfo, zPublicAccountInfo } from "lib/types"; -import type { BechAddr } from "lib/types"; -import { parseWithError, snakeToCamel } from "lib/utils"; - -const zIcns = z.object({ - names: z.array(z.string()), - primary_name: z.string(), -}); - -const zAccountData = z - .object({ - icns: zIcns.nullable(), - project_info: zProjectInfo.nullable(), - public_info: zPublicAccountInfo.nullable(), - }) - .transform(snakeToCamel); - -export type AccountData = z.infer; - -export const getAccountData = async ( - endpoint: string, - address: BechAddr -): Promise => - axios - .get(`${endpoint}/${encodeURIComponent(address)}/info`) - .then(({ data }) => parseWithError(zAccountData, data)); - -const zAccountTableCounts = z - .object({ - code: z.number().nullish(), - contract_by_admin: z.number().nullish(), - instantiated: z.number().nullish(), - proposal: z.number().nullish(), - tx: z.number().nullish(), - }) - .transform(snakeToCamel); - -export type AccountTableCounts = z.infer; - -export const getAccountTableCounts = async ( - endpoint: string, - address: string, - isGov: boolean, - isWasm: boolean -): Promise => - axios - .get(`${endpoint}/${encodeURIComponent(address)}/table-counts`, { - params: { - is_gov: isGov, - is_wasm: isWasm, - }, - }) - .then(({ data }) => parseWithError(zAccountTableCounts, data)); diff --git a/src/lib/services/account/api.ts b/src/lib/services/account/api.ts new file mode 100644 index 000000000..6c73859c0 --- /dev/null +++ b/src/lib/services/account/api.ts @@ -0,0 +1,29 @@ +import axios from "axios"; + +import { zAccountData, zAccountTableCounts } from "../types"; +import type { AccountData, AccountTableCounts } from "../types"; +import type { BechAddr } from "lib/types"; +import { parseWithError } from "lib/utils"; + +export const getAccountData = async ( + endpoint: string, + address: BechAddr +): Promise => + axios + .get(`${endpoint}/${encodeURIComponent(address)}/info`) + .then(({ data }) => parseWithError(zAccountData, data)); + +export const getAccountTableCounts = async ( + endpoint: string, + address: string, + isGov: boolean, + isWasm: boolean +): Promise => + axios + .get(`${endpoint}/${encodeURIComponent(address)}/table-counts`, { + params: { + is_gov: isGov, + is_wasm: isWasm, + }, + }) + .then(({ data }) => parseWithError(zAccountTableCounts, data)); diff --git a/src/lib/services/account/gql.ts b/src/lib/services/account/gql.ts new file mode 100644 index 000000000..40a19f693 --- /dev/null +++ b/src/lib/services/account/gql.ts @@ -0,0 +1,42 @@ +import type { UseQueryOptions, UseQueryResult } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; +import { useCallback } from "react"; + +import { CELATONE_QUERY_KEYS, useCelatoneApp } from "lib/app-provider"; +import { getAccountTypeByAddressQueryDocument } from "lib/query"; +import type { AccountType, BechAddr, Option } from "lib/types"; + +export const useAccountType = ( + address: Option, + options: Pick< + UseQueryOptions, + "enabled" | "onSuccess" | "onError" + > = {} +): UseQueryResult => { + const { indexerGraphClient } = useCelatoneApp(); + + const queryFn = useCallback(async () => { + if (!address) + throw new Error( + "Error fetching account type: failed to retrieve address." + ); + return indexerGraphClient + .request(getAccountTypeByAddressQueryDocument, { + address, + }) + .then( + ({ accounts_by_pk }) => + (accounts_by_pk?.type ?? "BaseAccount") as AccountType + ); + }, [indexerGraphClient, address]); + + return useQuery( + [CELATONE_QUERY_KEYS.ACCOUNT_TYPE, indexerGraphClient, address], + queryFn, + { + ...options, + retry: 1, + refetchOnWindowFocus: false, + } + ); +}; diff --git a/src/lib/services/account/index.ts b/src/lib/services/account/index.ts new file mode 100644 index 000000000..f27a2f8da --- /dev/null +++ b/src/lib/services/account/index.ts @@ -0,0 +1,57 @@ +import type { UseQueryOptions, UseQueryResult } from "@tanstack/react-query"; +import { useQuery } from "@tanstack/react-query"; + +import type { AccountData, AccountTableCounts } from "../types"; +import { + CELATONE_QUERY_KEYS, + useBaseApiRoute, + useGovConfig, + useLcdEndpoint, + useTierConfig, + useWasmConfig, +} from "lib/app-provider"; +import type { BechAddr } from "lib/types"; + +import { getAccountData, getAccountTableCounts } from "./api"; +import { getAccountDataLcd } from "./lcd"; + +export const useAccountData = ( + address: BechAddr +): UseQueryResult => { + const isFullTier = useTierConfig() === "full"; + const lcdEndpoint = useLcdEndpoint(); + const apiEndpoint = useBaseApiRoute("accounts"); + const endpoint = isFullTier ? lcdEndpoint : apiEndpoint; + + return useQuery( + [CELATONE_QUERY_KEYS.ACCOUNT_DATA, endpoint, address], + async () => + isFullTier + ? getAccountData(endpoint, address) + : getAccountDataLcd(endpoint, address), + { enabled: !!address, retry: 1, refetchOnWindowFocus: false } + ); +}; + +export const useAccountTableCounts = ( + address: BechAddr, + options?: UseQueryOptions +) => { + const endpoint = useBaseApiRoute("accounts"); + const { enabled: isGov } = useGovConfig({ shouldRedirect: false }); + const { enabled: isWasm } = useWasmConfig({ shouldRedirect: false }); + + return useQuery( + [ + CELATONE_QUERY_KEYS.ACCOUNT_TABLE_COUNTS, + endpoint, + address, + isGov, + isWasm, + ], + async () => getAccountTableCounts(endpoint, address, isGov, isWasm), + { retry: 1, refetchOnWindowFocus: false, ...options } + ); +}; + +export * from "./gql"; diff --git a/src/lib/services/account/lcd.ts b/src/lib/services/account/lcd.ts new file mode 100644 index 000000000..19dd245cd --- /dev/null +++ b/src/lib/services/account/lcd.ts @@ -0,0 +1,17 @@ +/* eslint-disable @typescript-eslint/no-unused-vars */ +import axios from "axios"; + +import type { AccountData } from "../types"; +import type { BechAddr } from "lib/types"; + +export const getAccountDataLcd = async ( + endpoint: string, + address: BechAddr +): Promise => { + // TODO: Implement this function + return { + projectInfo: null, + publicInfo: null, + icns: null, + }; +}; diff --git a/src/lib/services/accountService.ts b/src/lib/services/accountService.ts deleted file mode 100644 index 48a660c4d..000000000 --- a/src/lib/services/accountService.ts +++ /dev/null @@ -1,83 +0,0 @@ -import type { UseQueryOptions, UseQueryResult } from "@tanstack/react-query"; -import { useQuery } from "@tanstack/react-query"; -import { useCallback } from "react"; - -import { - CELATONE_QUERY_KEYS, - useBaseApiRoute, - useCelatoneApp, - useGovConfig, - useWasmConfig, -} from "lib/app-provider"; -import { getAccountTypeByAddressQueryDocument } from "lib/query"; -import type { AccountType, BechAddr, Option } from "lib/types"; - -import { getAccountData, getAccountTableCounts } from "./account"; -import type { AccountData, AccountTableCounts } from "./account"; - -export const useAccountType = ( - address: Option, - options: Pick< - UseQueryOptions, - "enabled" | "onSuccess" | "onError" - > = {} -): UseQueryResult => { - const { indexerGraphClient } = useCelatoneApp(); - - const queryFn = useCallback(async () => { - if (!address) - throw new Error( - "Error fetching account type: failed to retrieve address." - ); - return indexerGraphClient - .request(getAccountTypeByAddressQueryDocument, { - address, - }) - .then( - ({ accounts_by_pk }) => - (accounts_by_pk?.type ?? "BaseAccount") as AccountType - ); - }, [indexerGraphClient, address]); - - return useQuery( - [CELATONE_QUERY_KEYS.ACCOUNT_TYPE, indexerGraphClient, address], - queryFn, - { - ...options, - retry: 1, - refetchOnWindowFocus: false, - } - ); -}; - -export const useAccountData = ( - address: BechAddr -): UseQueryResult => { - const endpoint = useBaseApiRoute("accounts"); - - return useQuery( - [CELATONE_QUERY_KEYS.ACCOUNT_DATA, endpoint, address], - async () => getAccountData(endpoint, address), - { enabled: !!address, retry: 1, refetchOnWindowFocus: false } - ); -}; - -export const useAccountTableCounts = ( - address: BechAddr -): UseQueryResult => { - const endpoint = useBaseApiRoute("accounts"); - const { enabled: isGov } = useGovConfig({ shouldRedirect: false }); - const { enabled: isWasm } = useWasmConfig({ shouldRedirect: false }); - - return useQuery( - [ - CELATONE_QUERY_KEYS.ACCOUNT_TABLE_COUNTS, - endpoint, - address, - isGov, - isWasm, - ], - async () => getAccountTableCounts(endpoint, address, isGov, isWasm), - { enabled: !!address, retry: 1, refetchOnWindowFocus: false } - ); -}; diff --git a/src/lib/services/bank/index.ts b/src/lib/services/bank/index.ts index a746a430c..78bf916e9 100644 --- a/src/lib/services/bank/index.ts +++ b/src/lib/services/bank/index.ts @@ -25,9 +25,9 @@ import { getBalances } from "./api"; import { getBalancesLcd } from "./lcd"; export const useBalances = (address: BechAddr): UseQueryResult => { + const isFullTier = useTierConfig() === "full"; const apiEndpoint = useBaseApiRoute("accounts"); const lcdEndpoint = useLcdEndpoint(); - const isFullTier = useTierConfig() === "full"; const endpoint = isFullTier ? apiEndpoint : lcdEndpoint; return useQuery( @@ -36,7 +36,7 @@ export const useBalances = (address: BechAddr): UseQueryResult => { isFullTier ? getBalances(endpoint, address) : getBalancesLcd(endpoint, address), - { enabled: !!address, retry: 1, refetchOnWindowFocus: false } + { retry: 1, refetchOnWindowFocus: false } ); }; diff --git a/src/lib/services/tx/index.ts b/src/lib/services/tx/index.ts index a3bf557cf..06dd6bef4 100644 --- a/src/lib/services/tx/index.ts +++ b/src/lib/services/tx/index.ts @@ -307,7 +307,7 @@ export const useTxsByAccountAddressLcd = ( export const useTxsByAddressLcd = ( address: Option, - search: string, + search: Option, limit: number, offset: number, options: UseQueryOptions = {} @@ -320,9 +320,9 @@ export const useTxsByAddressLcd = ( const queryfn = useCallback(async () => { const txs = await (async () => { - if (isTxHash(search)) return getTxsByHashLcd(endpoint, search); + if (search && isTxHash(search)) return getTxsByHashLcd(endpoint, search); - if (!validateContractAddress(search)) + if (search && !validateContractAddress(search)) return getTxsByContractAddressLcd( endpoint, search as BechAddr32, diff --git a/src/lib/services/types/account.ts b/src/lib/services/types/account.ts new file mode 100644 index 000000000..77994972c --- /dev/null +++ b/src/lib/services/types/account.ts @@ -0,0 +1,31 @@ +import { z } from "zod"; + +import { zProjectInfo, zPublicAccountInfo } from "lib/types"; +import { snakeToCamel } from "lib/utils"; + +const zIcns = z.object({ + names: z.array(z.string()), + primary_name: z.string(), +}); + +export const zAccountData = z + .object({ + icns: zIcns.nullable(), + project_info: zProjectInfo.nullable(), + public_info: zPublicAccountInfo.nullable(), + }) + .transform(snakeToCamel); + +export type AccountData = z.infer; + +export const zAccountTableCounts = z + .object({ + code: z.number().nullish(), + contract_by_admin: z.number().nullish(), + instantiated: z.number().nullish(), + proposal: z.number().nullish(), + tx: z.number().nullish(), + }) + .transform(snakeToCamel); + +export type AccountTableCounts = z.infer; diff --git a/src/lib/services/types/index.ts b/src/lib/services/types/index.ts index 4633b5a31..07902f2c6 100644 --- a/src/lib/services/types/index.ts +++ b/src/lib/services/types/index.ts @@ -1,3 +1,4 @@ +export * from "./account"; export * from "./bank"; export * from "./block"; export * from "./distribution"; diff --git a/src/lib/services/wasm/contract/index.ts b/src/lib/services/wasm/contract/index.ts index fcb6261fb..c50b5bbd3 100644 --- a/src/lib/services/wasm/contract/index.ts +++ b/src/lib/services/wasm/contract/index.ts @@ -14,13 +14,7 @@ import type { ContractTableCounts, MigrationHistoriesResponse, } from "lib/services/types"; -import type { - BechAddr, - BechAddr20, - BechAddr32, - JsonDataType, - Option, -} from "lib/types"; +import type { BechAddr, BechAddr32, JsonDataType, Option } from "lib/types"; import { getAdminContractsByAddress, @@ -247,7 +241,7 @@ export const useContractQueryLcd = ( }; export const useInstantiatedContractsByAddressLcd = ( - address: Option, + address: Option, enabled = false ) => { const endpoint = useLcdEndpoint(); diff --git a/src/lib/services/wasm/contract/lcd.ts b/src/lib/services/wasm/contract/lcd.ts index 91eb5cf5b..162078e85 100644 --- a/src/lib/services/wasm/contract/lcd.ts +++ b/src/lib/services/wasm/contract/lcd.ts @@ -13,7 +13,7 @@ import { } from "lib/services/types"; import type { ContractLocalInfo } from "lib/stores/contract"; import type { - BechAddr20, + BechAddr, BechAddr32, JsonDataType, Nullable, @@ -127,7 +127,7 @@ export const getMigrationHistoriesByContractAddressLcd = async ( export const getInstantiatedContractsByAddressLcd = ( endpoint: string, - address: BechAddr20 + address: BechAddr ) => axios .get( From 632e8720f367de075ea81ee0add67bd20b78d69e Mon Sep 17 00:00:00 2001 From: evilpeach Date: Wed, 12 Jun 2024 16:35:31 +0700 Subject: [PATCH 2/5] docs: add changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8813ada07..eca8559c1 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 +- [#970](https://github.com/alleslabs/celatone-frontend/pull/970) Support account details lite version (basic + wasm) - [#964](https://github.com/alleslabs/celatone-frontend/pull/964) Support migrate page lite version with LCD - [#966](https://github.com/alleslabs/celatone-frontend/pull/966) Support lite version for proposal details - [#958](https://github.com/alleslabs/celatone-frontend/pull/958) Support lite version for block index page From 0ccdf306b8b39d37a52ba21e7e0c953a0669d0cf Mon Sep 17 00:00:00 2001 From: evilpeach Date: Wed, 12 Jun 2024 16:43:14 +0700 Subject: [PATCH 3/5] fix: revert osmosis config --- src/config/chain/osmosis.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/config/chain/osmosis.ts b/src/config/chain/osmosis.ts index 85c205677..71b2e301f 100644 --- a/src/config/chain/osmosis.ts +++ b/src/config/chain/osmosis.ts @@ -52,7 +52,7 @@ export const OSMOSIS_CHAIN_CONFIGS: ChainConfigs = { extra: {}, }, "osmo-test-5": { - tier: "lite", + tier: "full", chain: "osmosis", registryChainName: "osmosistestnet", prettyName: "Osmosis Testnet", From a66da5f79f1509a5399c789aea4fa7ea94d27457 Mon Sep 17 00:00:00 2001 From: evilpeach Date: Thu, 13 Jun 2024 12:19:32 +0700 Subject: [PATCH 4/5] feat: support lite for move --- src/lib/pages/account-details/index.tsx | 4 +- src/lib/pages/nft-collection-details/data.ts | 4 +- src/lib/services/move/module/lcd.ts | 2 +- src/lib/services/move/resource.ts | 29 -------------- .../{resourceService.ts => resource/index.ts} | 10 ++--- src/lib/services/move/resource/lcd.ts | 38 +++++++++++++++++++ src/lib/services/types/move/index.ts | 1 + src/lib/services/types/move/resource.ts | 25 ++++++++++++ 8 files changed, 74 insertions(+), 39 deletions(-) delete mode 100644 src/lib/services/move/resource.ts rename src/lib/services/move/{resourceService.ts => resource/index.ts} (92%) create mode 100644 src/lib/services/move/resource/lcd.ts create mode 100644 src/lib/services/types/move/resource.ts diff --git a/src/lib/pages/account-details/index.tsx b/src/lib/pages/account-details/index.tsx index 9b80eadd9..812569aa4 100644 --- a/src/lib/pages/account-details/index.tsx +++ b/src/lib/pages/account-details/index.tsx @@ -31,7 +31,7 @@ import { UserDocsLink } from "lib/components/UserDocsLink"; import { useFormatAddresses } from "lib/hooks/useFormatAddresses"; import { useAccountData } from "lib/services/account"; import { useModulesByAddress } from "lib/services/move/module"; -import { useResourcesByAddress } from "lib/services/move/resourceService"; +import { useResourcesByAddressLcd } from "lib/services/move/resource"; import { useNftsCountByAccount } from "lib/services/nft"; import type { Addr, BechAddr, HexAddr, Option } from "lib/types"; import { truncate } from "lib/utils"; @@ -94,7 +94,7 @@ const AccountDetailsBody = ({ const { data: modulesData, isFetching: isModulesLoading } = useModulesByAddress({ address: accountAddress }); const { data: resourcesData, isFetching: isResourceLoading } = - useResourcesByAddress(accountAddress); + useResourcesByAddressLcd(accountAddress); // nft const { data: nftsCount, isFetching: isNftsCountLoading } = useNftsCountByAccount(hexAddress); diff --git a/src/lib/pages/nft-collection-details/data.ts b/src/lib/pages/nft-collection-details/data.ts index 97b59a8ae..cbeb94e95 100644 --- a/src/lib/pages/nft-collection-details/data.ts +++ b/src/lib/pages/nft-collection-details/data.ts @@ -1,5 +1,5 @@ import { useFormatAddresses } from "lib/hooks/useFormatAddresses"; -import { useResourcesByAddress } from "lib/services/move/resourceService"; +import { useResourcesByAddressLcd } from "lib/services/move/resource"; import type { HexAddr, HexAddr32, Option } from "lib/types"; interface SupplyData { @@ -24,7 +24,7 @@ export const useCollectionInfos = ( ): { collectionInfos: Option; isLoading: boolean } => { const formatAddress = useFormatAddresses(); const { address } = formatAddress(collectionAddress); - const { data: resourcesData, isFetching } = useResourcesByAddress(address); + const { data: resourcesData, isFetching } = useResourcesByAddressLcd(address); if (!resourcesData) return { collectionInfos: undefined, isLoading: isFetching }; diff --git a/src/lib/services/move/module/lcd.ts b/src/lib/services/move/module/lcd.ts index 3d0301d33..74f7102b4 100644 --- a/src/lib/services/move/module/lcd.ts +++ b/src/lib/services/move/module/lcd.ts @@ -28,7 +28,7 @@ export const getModulesByAddressLcd = async ( `${endpoint}/initia/move/v1/accounts/${encodeURI(address)}/modules`, { params: { - "pagination.key": paginationKey ?? "", + "pagination.key": paginationKey, }, } ) diff --git a/src/lib/services/move/resource.ts b/src/lib/services/move/resource.ts deleted file mode 100644 index 544748bd4..000000000 --- a/src/lib/services/move/resource.ts +++ /dev/null @@ -1,29 +0,0 @@ -import axios from "axios"; -import { z } from "zod"; - -import type { Addr } from "lib/types"; -import { zHexAddr } from "lib/types"; -import { parseWithError, snakeToCamel } from "lib/utils"; - -const zResourcesResponseItem = z - .object({ - address: zHexAddr, - move_resource: z.string(), - raw_bytes: z.string(), - struct_tag: z.string(), - }) - .transform(snakeToCamel); - -const zResourcesResponse = z.object({ - items: z.array(zResourcesResponseItem), - total: z.number().nonnegative(), -}); -export type ResourceResponse = z.infer; - -export const getAccountResources = async ( - endpoint: string, - address: Addr -): Promise => - axios - .get(`${endpoint}/${encodeURIComponent(address)}/move/resources`) - .then(({ data }) => parseWithError(zResourcesResponse, data)); diff --git a/src/lib/services/move/resourceService.ts b/src/lib/services/move/resource/index.ts similarity index 92% rename from src/lib/services/move/resourceService.ts rename to src/lib/services/move/resource/index.ts index 49f568834..3b2ec881c 100644 --- a/src/lib/services/move/resourceService.ts +++ b/src/lib/services/move/resource/index.ts @@ -3,7 +3,7 @@ import { useQuery } from "@tanstack/react-query"; import { CELATONE_QUERY_KEYS, - useBaseApiRoute, + useLcdEndpoint, useMoveConfig, } from "lib/app-provider"; import type { @@ -14,7 +14,7 @@ import type { } from "lib/types"; import { truncate } from "lib/utils"; -import { getAccountResources } from "./resource"; +import { getAccountResourcesLcd } from "./lcd"; export interface ResourcesByAddressReturn { groupedByOwner: ResourceGroupByAccount[]; @@ -22,14 +22,14 @@ export interface ResourcesByAddressReturn { totalCount: number; } -export const useResourcesByAddress = ( +export const useResourcesByAddressLcd = ( address: Addr ): UseQueryResult => { - const endpoint = useBaseApiRoute("accounts"); + const endpoint = useLcdEndpoint(); const { enabled } = useMoveConfig({ shouldRedirect: false }); const queryFn: QueryFunction = () => - getAccountResources(endpoint, address).then((resources) => { + getAccountResourcesLcd(endpoint, address).then((resources) => { const groupedByOwner = resources.items.reduce< Record >((acc, resource) => { diff --git a/src/lib/services/move/resource/lcd.ts b/src/lib/services/move/resource/lcd.ts new file mode 100644 index 000000000..cadc62380 --- /dev/null +++ b/src/lib/services/move/resource/lcd.ts @@ -0,0 +1,38 @@ +import axios from "axios"; + +import { zResourcesResponseLcd } from "lib/services/types"; +import type { + ResourceResponse, + ResourceResponseItem, +} from "lib/services/types"; +import type { Addr, Nullable } from "lib/types"; +import { parseWithError } from "lib/utils"; + +export const getAccountResourcesLcd = async ( + endpoint: string, + address: Addr +): Promise => { + const result: ResourceResponseItem[] = []; + + const fetchFn = async (paginationKey: Nullable) => { + const res = await axios + .get( + `${endpoint}/initia/move/v1/accounts/${encodeURI(address)}/resources`, + { + params: { + "pagination.key": paginationKey, + }, + } + ) + .then(({ data }) => parseWithError(zResourcesResponseLcd, data)); + result.push(...res.resources); + if (res.pagination.nextKey) await fetchFn(res.pagination.nextKey); + }; + + await fetchFn(null); + + return { + items: result.sort((a, b) => a.structTag.localeCompare(b.structTag)), + total: result.length, + }; +}; diff --git a/src/lib/services/types/move/index.ts b/src/lib/services/types/move/index.ts index b999044ad..5cf18b55c 100644 --- a/src/lib/services/types/move/index.ts +++ b/src/lib/services/types/move/index.ts @@ -1 +1,2 @@ export * from "./module"; +export * from "./resource"; diff --git a/src/lib/services/types/move/resource.ts b/src/lib/services/types/move/resource.ts new file mode 100644 index 000000000..976e4cf53 --- /dev/null +++ b/src/lib/services/types/move/resource.ts @@ -0,0 +1,25 @@ +import { z } from "zod"; + +import { zHexAddr, zPagination } from "lib/types"; +import { snakeToCamel } from "lib/utils"; + +const zResourcesResponseItem = z + .object({ + address: zHexAddr, + move_resource: z.string(), + raw_bytes: z.string(), + struct_tag: z.string(), + }) + .transform(snakeToCamel); +export type ResourceResponseItem = z.infer; + +export const zResourcesResponseLcd = z.object({ + resources: z.array(zResourcesResponseItem), + pagination: zPagination, +}); + +export const zResourcesResponse = z.object({ + items: z.array(zResourcesResponseItem), + total: z.number().nonnegative(), +}); +export type ResourceResponse = z.infer; From 7c82015f7e100d777f07d224fc6b6640390e149d Mon Sep 17 00:00:00 2001 From: evilpeach Date: Thu, 13 Jun 2024 18:20:03 +0700 Subject: [PATCH 5/5] docs: edit changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eca8559c1..da7610a1b 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 -- [#970](https://github.com/alleslabs/celatone-frontend/pull/970) Support account details lite version (basic + wasm) +- [#970](https://github.com/alleslabs/celatone-frontend/pull/970) Support account details lite version - [#964](https://github.com/alleslabs/celatone-frontend/pull/964) Support migrate page lite version with LCD - [#966](https://github.com/alleslabs/celatone-frontend/pull/966) Support lite version for proposal details - [#958](https://github.com/alleslabs/celatone-frontend/pull/958) Support lite version for block index page