Skip to content

Commit

Permalink
Use new chain widget props
Browse files Browse the repository at this point in the history
Replace chainConfig store state with chainMetadataOverrides
  • Loading branch information
jmrossy committed Oct 7, 2024
1 parent ae86d66 commit eabdf92
Show file tree
Hide file tree
Showing 27 changed files with 156 additions and 494 deletions.
14 changes: 7 additions & 7 deletions src/components/nav/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,9 @@ export function Header({ pathName }: { pathName: string }) {
>
Docs
</a>
<Link href="/settings" className={navLinkClass('/settings')}>
{/* <Link href="/settings" className={navLinkClass('/settings')}>
Settings
</Link>
</Link> */}
{showSearch && <MiniSearchBar />}
</nav>
{/* Dropdown menu, used on mobile */}
Expand All @@ -79,11 +79,11 @@ export function Header({ pathName }: { pathName: string }) {
Home
</MobileNavLink>
),
({ close }) => (
<MobileNavLink href="/settings" closeDropdown={close} key="Settings">
Settings
</MobileNavLink>
),
// ({ close }) => (
// <MobileNavLink href="/settings" closeDropdown={close} key="Settings">
// Settings
// </MobileNavLink>
// ),
// ({ close }) => (
// <MobileNavLink href="/api" closeDropdown={c} key="API">
// API
Expand Down
23 changes: 13 additions & 10 deletions src/components/search/SearchFilterBar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import clsx from 'clsx';
import Link from 'next/link';
import { useState } from 'react';

import { ChainMetadata } from '@hyperlane-xyz/sdk';
import { trimToLength } from '@hyperlane-xyz/utils';
import {
ChainSearchMenu,
ChevronIcon,
GearIcon,
IconButton,
Modal,
Popover,
Expand All @@ -16,7 +14,7 @@ import {

import { useScrapedEvmChains } from '../../features/chains/queries/useScrapedChains';
import { getChainDisplayName } from '../../features/chains/utils';
import { useMultiProvider } from '../../store';
import { useMultiProvider, useStore } from '../../store';
import { Color } from '../../styles/Color';
import { SolidButton } from '../buttons/SolidButton';
import { TextButton } from '../buttons/TextButton';
Expand Down Expand Up @@ -57,11 +55,6 @@ export function SearchFilterBar({
endValue={endTimestamp}
onChangeEndValue={onChangeEndTimestamp}
/>
<Link href="/settings" title="View explorer settings" className="hidden sm:block">
<div className="active:opacity-90 hover:rotate-90 transition-all">
<GearIcon color={Color.pink} height={18} width={18} />
</div>
</Link>
</div>
);
}
Expand All @@ -77,6 +70,10 @@ function ChainSelector({
}) {
const multiProvider = useMultiProvider();
const { chains } = useScrapedEvmChains(multiProvider);
const { chainMetadataOverrides, setChainMetadataOverrides } = useStore((s) => ({
chainMetadataOverrides: s.chainMetadataOverrides,
setChainMetadataOverrides: s.setChainMetadataOverrides,
}));

const [showModal, setShowModal] = useState(false);
const closeModal = () => {
Expand Down Expand Up @@ -121,9 +118,15 @@ function ChainSelector({
<Modal
isOpen={showModal}
close={closeModal}
panelClassname="p-4 sm:p-5 max-w-lg min-h-[50vh]"
panelClassname="p-4 sm:p-5 max-w-lg min-h-[40vh]"
>
<ChainSearchMenu chainMetadata={chains} onClickChain={onClickChain} />
<ChainSearchMenu
chainMetadata={chains}
onClickChain={onClickChain}
overrideChainMetadata={chainMetadataOverrides}
onChangeOverrideMetadata={setChainMetadataOverrides}
showAddChainButton={true}
/>
</Modal>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion src/components/search/SearchStates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export function SearchFetching({ show, isPiFetching }: { show: boolean; isPiFetc
<Spinner />
</div>
<div className="mt-4 text-center font-light leading-loose text-gray-700">
{isPiFetching ? 'Searching custom chains for messages' : 'Searching for messages'}
{isPiFetching ? 'Searching override chains for messages' : 'Searching for messages'}
</div>
</div>
</div>
Expand Down
15 changes: 7 additions & 8 deletions src/features/api/getMessages.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { Client } from '@urql/core';
import type { NextApiRequest } from 'next';

import { Result, failure, success } from '@hyperlane-xyz/utils';

import { API_GRAPHQL_QUERY_LIMIT } from '../../consts/api';
import { logger } from '../../utils/logger';
import { sanitizeString } from '../../utils/string';
import { MessageIdentifierType, buildMessageQuery } from '../messages/queries/build';
import { MessagesQueryResult } from '../messages/queries/fragments';
import { parseMessageQueryResult } from '../messages/queries/parse';

import { ApiHandlerResult, ApiMessage, toApiMessage } from './types';
import { failureResult, getMultiProvider, getScrapedChains, successResult } from './utils';
import { ApiMessage, toApiMessage } from './types';
import { getMultiProvider, getScrapedChains } from './utils';

export async function handler(
req: NextApiRequest,
client: Client,
): Promise<ApiHandlerResult<ApiMessage[]>> {
export async function handler(req: NextApiRequest, client: Client): Promise<Result<ApiMessage[]>> {
const identifierParam = parseQueryParams(req);
if (!identifierParam) return failureResult('No message identifier param provided');
if (!identifierParam) return failure('No message identifier param provided');

logger.debug('Attempting to find messages matching:', identifierParam);
const { query, variables } = buildMessageQuery(
Expand All @@ -30,7 +29,7 @@ export async function handler(
const scrapedChains = await getScrapedChains(client);

const messages = parseMessageQueryResult(multiProvider, scrapedChains, result.data);
return successResult(messages.map(toApiMessage));
return success(messages.map(toApiMessage));
}

// TODO replace with Zod
Expand Down
11 changes: 6 additions & 5 deletions src/features/api/getStatus.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Client } from '@urql/core';
import type { NextApiRequest } from 'next';

import { Result, failure, success } from '@hyperlane-xyz/utils';

import { API_GRAPHQL_QUERY_LIMIT } from '../../consts/api';
import { MessageStatus } from '../../types';
import { logger } from '../../utils/logger';
Expand All @@ -9,8 +11,7 @@ import { MessagesStubQueryResult } from '../messages/queries/fragments';
import { parseMessageStubResult } from '../messages/queries/parse';

import { parseQueryParams } from './getMessages';
import { ApiHandlerResult } from './types';
import { failureResult, getMultiProvider, getScrapedChains, successResult } from './utils';
import { getMultiProvider, getScrapedChains } from './utils';

interface MessageStatusResult {
id: string;
Expand All @@ -20,9 +21,9 @@ interface MessageStatusResult {
export async function handler(
req: NextApiRequest,
client: Client,
): Promise<ApiHandlerResult<MessageStatusResult[]>> {
): Promise<Result<MessageStatusResult[]>> {
const identifierParam = parseQueryParams(req);
if (!identifierParam) return failureResult('No message identifier param provided');
if (!identifierParam) return failure('No message identifier param provided');

logger.debug('Attempting to find message status matching:', identifierParam);
const { query, variables } = buildMessageQuery(
Expand All @@ -38,5 +39,5 @@ export async function handler(

const messages = parseMessageStubResult(multiProvider, scrapedChains, result.data);

return successResult(messages.map((m) => ({ id: m.msgId, status: m.status })));
return success(messages.map((m) => ({ id: m.msgId, status: m.status })));
}
15 changes: 7 additions & 8 deletions src/features/api/searchMessages.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { Client } from '@urql/core';
import type { NextApiRequest } from 'next';

import { Result, failure, success } from '@hyperlane-xyz/utils';

import { API_GRAPHQL_QUERY_LIMIT } from '../../consts/api';
import { logger } from '../../utils/logger';
import { sanitizeString } from '../../utils/string';
import { buildMessageSearchQuery } from '../messages/queries/build';
import { MessagesQueryResult } from '../messages/queries/fragments';
import { parseMessageQueryResult } from '../messages/queries/parse';

import { ApiHandlerResult, ApiMessage, toApiMessage } from './types';
import { failureResult, getMultiProvider, getScrapedChains, successResult } from './utils';
import { ApiMessage, toApiMessage } from './types';
import { getMultiProvider, getScrapedChains } from './utils';

const SEARCH_QUERY_PARAM_NAME = 'query';

export async function handler(
req: NextApiRequest,
client: Client,
): Promise<ApiHandlerResult<ApiMessage[]>> {
export async function handler(req: NextApiRequest, client: Client): Promise<Result<ApiMessage[]>> {
const queryValue = parseSearchQueryParam(req);
if (!queryValue) return failureResult('No query param provided');
if (!queryValue) return failure('No query param provided');

logger.debug('Attempting to search for messages:', queryValue);
// TODO consider supporting time/chain filters here
Expand All @@ -37,7 +36,7 @@ export async function handler(

const messages = parseMessageQueryResult(multiProvider, scrapedChains, result.data);

return successResult(messages.map(toApiMessage));
return success(messages.map(toApiMessage));
}

// TODO replace with Zod
Expand Down
25 changes: 12 additions & 13 deletions src/features/api/searchPiMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,43 @@ import type { NextApiRequest } from 'next';
import { z } from 'zod';

import { GithubRegistry } from '@hyperlane-xyz/registry';
import { MultiProvider } from '@hyperlane-xyz/sdk';
import { ChainMetadataSchema, MultiProvider } from '@hyperlane-xyz/sdk';
import { Result, failure, success } from '@hyperlane-xyz/utils';

import { config } from '../../consts/config';
import { logger } from '../../utils/logger';
import { tryParseChainConfig } from '../chains/chainConfig';
import {
PiMessageQuery,
fetchMessagesFromPiChain,
} from '../messages/pi-queries/fetchPiChainMessages';

import { ApiHandlerResult, ApiMessage } from './types';
import { failureResult, successResult } from './utils';
import { ApiMessage } from './types';

const queryParamSchema = z.object({
query: z.string(),
fromBlock: z.string().optional(),
toBlock: z.string().optional(),
});

export async function handler(req: NextApiRequest): Promise<ApiHandlerResult<ApiMessage[]>> {
export async function handler(req: NextApiRequest): Promise<Result<ApiMessage[]>> {
const query = tryParseParams(req);
if (!query) return failureResult('Invalid query params provided');
if (!query) return failure('Invalid query params provided');

const parseResult = tryParseChainConfig(req.body);
if (!parseResult.success) return failureResult(`Invalid chain configs: ${parseResult.error}`);
const chainConfig = parseResult.chainConfig;
const parseResult = ChainMetadataSchema.safeParse(req.body);
if (!parseResult.success) return failure(`Invalid chain configs: ${parseResult.error}`);
const chainMetadata = parseResult.data;

try {
logger.debug('Attempting to search for PI messages:', query);
const multiProvider = new MultiProvider({ [chainConfig.name]: chainConfig });
const multiProvider = new MultiProvider({ [chainMetadata.name]: chainMetadata });
const registry = new GithubRegistry({ proxyUrl: config.githubProxy });
// TODO consider supporting block/time/chain filters here
const messages = await fetchMessagesFromPiChain(chainConfig, query, multiProvider, registry);
const messages = await fetchMessagesFromPiChain(chainMetadata, query, multiProvider, registry);
logger.debug(`Found ${messages.length} PI messages`);
return successResult(messages);
return success(messages);
} catch (error) {
logger.error('Error fetching PI messages', error);
return failureResult('Unable to fetch messages, check config and query');
return failure('Unable to fetch messages, check config and query');
}
}

Expand Down
10 changes: 0 additions & 10 deletions src/features/api/types.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
import { Message } from '../../types';

export type ApiHandlerResult<T> =
| {
success: true;
data: T;
}
| {
success: false;
error: string;
};

export type ApiMessage = Omit<
Message,
| 'msgId' // use id field for msgId
Expand Down
8 changes: 0 additions & 8 deletions src/features/api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,6 @@ import { config } from '../../consts/config';
import { logger } from '../../utils/logger';
import { DOMAINS_QUERY, DomainsEntry } from '../chains/queries/fragments';

export function successResult<R>(data: R): { success: true; data: R } {
return { success: true, data };
}

export function failureResult(error: string): { success: false; error: string } {
return { success: false, error };
}

// TODO de-dupe this with store.ts and handle registry/multiProvider concerns in a single place
export async function getMultiProvider(): Promise<MultiProvider> {
const registry = new GithubRegistry({ proxyUrl: config.githubProxy });
Expand Down
2 changes: 1 addition & 1 deletion src/features/chains/ChainConfigSyncer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PropsWithChildren } from 'react';

import { useQueryParamChainConfigSync } from './useChainConfigs';
import { useQueryParamChainConfigSync } from './useChainMetadata';

export function ChainConfigSyncer({ children }: PropsWithChildren<Record<never, any>>) {
useQueryParamChainConfigSync();
Expand Down
Loading

0 comments on commit eabdf92

Please sign in to comment.