Skip to content

Commit

Permalink
Merge pull request #562 from alleslabs/feat/search-hex-module
Browse files Browse the repository at this point in the history
feat: support searching with hex addr and module path
  • Loading branch information
evilpeach authored Oct 20, 2023
2 parents 74fb14a + fbb0b12 commit 57b468c
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 16 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Features

- [#562](https://github.com/alleslabs/celatone-frontend/pull/562) Support searching with hex address and module path
- [#572](https://github.com/alleslabs/celatone-frontend/pull/572) Wireup module publish details
- [#558](https://github.com/alleslabs/celatone-frontend/pull/558) Wireup module transaction history table
- [#558](https://github.com/alleslabs/celatone-frontend/pull/558) Wireup module transaction history table
Expand Down
33 changes: 24 additions & 9 deletions src/lib/layout/Searchbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ import type {
SearchResultType,
} from "lib/services/searchService";
import { useSearchHandler } from "lib/services/searchService";
import type { Nullable, Option } from "lib/types";
import type { MoveAccountAddr, Nullable, Option } from "lib/types";
import { splitModule } from "lib/utils";

const NOT_FOUND_MSG =
"Matches not found. Please check your spelling or make sure you have selected the correct network.";
Expand All @@ -58,28 +59,38 @@ interface ResultItemProps {
onClose?: () => void;
}

const generateQueryObject = (params: string[], value: string | string[]) =>
typeof value === "string"
? { [params[0]]: value }
: params.reduce((acc, curr, idx) => ({ ...acc, [curr]: value[idx] }), {});

const getRouteOptions = (
type: Option<SearchResultType>
): Nullable<{ pathname: string; query: string }> => {
): Nullable<{ pathname: string; query: string[] }> => {
switch (type) {
case "Wallet Address":
return {
pathname: "/accounts/[accountAddress]",
query: "accountAddress",
query: ["accountAddress"],
};
case "Transaction Hash":
return { pathname: "/txs/[txHash]", query: "txHash" };
return { pathname: "/txs/[txHash]", query: ["txHash"] };
case "Code ID":
return { pathname: "/codes/[codeId]", query: "codeId" };
return { pathname: "/codes/[codeId]", query: ["codeId"] };
case "Contract Address":
return {
pathname: "/contracts/[contractAddress]",
query: "contractAddress",
query: ["contractAddress"],
};
case "Block":
return { pathname: "/blocks/[height]", query: "height" };
return { pathname: "/blocks/[height]", query: ["height"] };
case "Pool ID":
return { pathname: "/pools/[poolId]", query: "poolId" };
return { pathname: "/pools/[poolId]", query: ["poolId"] };
case "Module Path":
return {
pathname: "/modules/[address]/[moduleName]",
query: ["address", "moduleName"],
};
default:
return null;
}
Expand Down Expand Up @@ -259,9 +270,13 @@ const Searchbar = () => {
trackUseMainSearch(isClick);
const routeOptions = getRouteOptions(type);
if (routeOptions) {
const queryValues =
type === "Module Path"
? (splitModule(keyword) as [MoveAccountAddr, string])
: metadata.icns.address || keyword;
navigate({
pathname: routeOptions.pathname,
query: { [routeOptions.query]: metadata.icns.address || keyword },
query: generateQueryObject(routeOptions.query, queryValues),
});
setDisplayResults(false);
setKeyword("");
Expand Down
10 changes: 8 additions & 2 deletions src/lib/services/blockService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ import type {
Nullable,
ValidatorAddr,
} from "lib/types";
import { isBlock, parseDate, parseDateOpt, parseTxHash } from "lib/utils";
import {
isBlock,
isHexAddress,
parseDate,
parseDateOpt,
parseTxHash,
} from "lib/utils";

export const useBlocklistQuery = (
limit: number,
Expand Down Expand Up @@ -120,7 +126,7 @@ export const useBlockInfoQuery = (
[CELATONE_QUERY_KEYS.BLOCK_INFO, indexerGraphClient, height],
queryFn,
{
enabled: isBlock(height),
enabled: isBlock(height) && !isHexAddress(height),
retry: false,
refetchOnWindowFocus: false,
}
Expand Down
39 changes: 36 additions & 3 deletions src/lib/services/searchService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import {
useGetAddressType,
} from "lib/app-provider";
import type { Addr, ContractAddr, Option } from "lib/types";
import { isCodeId } from "lib/utils";
import { isCodeId, isHexAddress, splitModule } from "lib/utils";

import { useBlockInfoQuery } from "./blockService";
import { useCodeDataByCodeId } from "./codeService";
import { queryContract } from "./contract";
import { useAccountModules } from "./moduleService";
import { useAddressByICNSName, useICNSNamesByAddress } from "./nameService";
import type { ICNSNamesResponse } from "./ns";
import { usePoolByPoolId } from "./poolService";
Expand All @@ -26,7 +27,8 @@ export type SearchResultType =
| "Transaction Hash"
| "Proposal ID"
| "Block"
| "Pool ID";
| "Pool ID"
| "Module Path";

export interface ResultMetadata {
icns: {
Expand All @@ -37,6 +39,7 @@ export interface ResultMetadata {
}

// TODO: Add Proposal ID
// eslint-disable-next-line complexity
export const useSearchHandler = (
keyword: string,
resetHandlerStates: () => void
Expand All @@ -52,6 +55,7 @@ export const useSearchHandler = (
features: {
wasm: { enabled: isWasm },
pool: { enabled: isPool },
move: { enabled: isMove },
},
},
} = useCelatoneApp();
Expand Down Expand Up @@ -86,8 +90,35 @@ export const useSearchHandler = (
const { data: icnsAddressData, isFetching: icnsAddressFetching } =
useAddressByICNSName(debouncedKeyword);

const [initiaAddr, moduleName, functionName] = splitModule(debouncedKeyword);

const enableModuleFetching = useMemo(
() =>
Boolean(
isMove &&
(getAddressType(initiaAddr) === "user_address" ||
isHexAddress(initiaAddr)) &&
moduleName &&
functionName === undefined
),
[functionName, getAddressType, initiaAddr, isMove, moduleName]
);

const { data: moduleData, isFetching: moduleFetching } = useAccountModules({
address: initiaAddr,
moduleName,
functionName: undefined,
options: {
enabled: enableModuleFetching,
refetchOnWindowFocus: false,
retry: false,
},
});

const isAddr =
addressType === "user_address" || addressType === "contract_address";
addressType === "user_address" ||
addressType === "contract_address" ||
isHexAddress(debouncedKeyword);

// provide ICNS metadata result
const { data: icnsNames } = useICNSNamesByAddress(
Expand Down Expand Up @@ -117,12 +148,14 @@ export const useSearchHandler = (
return {
results: [
addressResult,
moduleData && "Module Path",
txData && "Transaction Hash",
codeData && "Code ID",
blockData && "Block",
poolData && "Pool ID",
].filter((res) => Boolean(res)) as SearchResultType[],
isLoading:
moduleFetching ||
txFetching ||
codeFetching ||
contractFetching ||
Expand Down
4 changes: 2 additions & 2 deletions src/lib/utils/modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import type { MoveAccountAddr } from "lib/types";
*/

type SplitReturn =
| [MoveAccountAddr, undefined, undefined]
| [MoveAccountAddr, string, undefined]
| [MoveAccountAddr]
| [MoveAccountAddr, string]
| [MoveAccountAddr, string, string];

export const splitModule = (path: string): SplitReturn => {
Expand Down

0 comments on commit 57b468c

Please sign in to comment.