Increase prettier print width

pull/4/head
J M Rossy 2 years ago
parent 8e3cff4a28
commit e27b9e4028
  1. 1
      .prettierrc
  2. 4
      src/components/animation/Spinner.tsx
  3. 12
      src/components/buttons/ConnectAwareSubmitButton.tsx
  4. 11
      src/components/buttons/IconButton.tsx
  5. 3
      src/components/buttons/SolidButton.tsx
  6. 14
      src/components/icons/ChainIcon.tsx
  7. 11
      src/components/layout/ContentFrame.tsx
  8. 13
      src/components/nav/Footer.tsx
  9. 62
      src/components/nav/Header.tsx
  10. 4
      src/components/search/SearchBar.tsx
  11. 12
      src/components/search/SearchError.tsx
  12. 7
      src/consts/networksConfig.ts
  13. 51
      src/features/search/MessageDetails.tsx
  14. 38
      src/features/search/MessageSearch.tsx
  15. 31
      src/features/search/MessageSummary.tsx
  16. 9
      src/features/search/placeholderMessages.ts
  17. 19
      src/features/search/query.ts
  18. 5
      src/features/search/utils.ts
  19. 17
      src/pages/_app.tsx
  20. 30
      src/pages/_document.tsx
  21. 4
      src/pages/message/[messageId].tsx
  22. 3
      src/styles/globals.css
  23. 4
      src/utils/addresses.ts
  24. 4
      src/utils/objects.ts
  25. 4
      src/utils/string.ts
  26. 9
      src/utils/timeout.ts

@ -1,5 +1,6 @@
{
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all",
"importOrder": ["^@abacus-network/(.*)$", "^../(.*)$", "^./(.*)$"],

@ -5,9 +5,7 @@ import styles from './Spinner.module.css';
// From https://loading.io/css/
function _Spinner({ white, classes }: { white?: boolean; classes?: string }) {
return (
<div
className={`${styles.spinner} ${white && styles.white} ${classes || ''}`}
>
<div className={`${styles.spinner} ${white && styles.white} ${classes || ''}`}>
<div></div>
<div></div>
<div></div>

@ -19,19 +19,13 @@ export function ConnectAwareSubmitButton<FormValues = any>(props: Props) {
const isAccountReady = !!(address && isConnected && connector);
const { errors, setErrors, touched, setTouched } =
useFormikContext<FormValues>();
const { errors, setErrors, touched, setTouched } = useFormikContext<FormValues>();
const hasError =
Object.keys(touched).length > 0 && Object.keys(errors).length > 0;
const hasError = Object.keys(touched).length > 0 && Object.keys(errors).length > 0;
const firstError = `${Object.values(errors)[0]}` || 'Unknown error';
const color = hasError ? 'red' : 'blue';
const text = hasError
? firstError
: isAccountReady
? connectText
: 'Connect Wallet';
const text = hasError ? firstError : isAccountReady ? connectText : 'Connect Wallet';
const type = isAccountReady ? 'submit' : 'button';
const onClick = isAccountReady ? undefined : openConnectModal;

@ -13,16 +13,7 @@ export interface IconButtonProps {
}
export function IconButton(props: PropsWithChildren<IconButtonProps>) {
const {
width,
height,
classes,
onClick,
imgSrc,
disabled,
title,
passThruProps,
} = props;
const { width, height, classes, onClick, imgSrc, disabled, title, passThruProps } = props;
const base = 'flex items-center justify-center transition-all';
const onHover = 'hover:opacity-70';

@ -28,8 +28,7 @@ export function SolidButton(props: PropsWithChildren<ButtonProps>) {
} = props;
const color = _color ?? 'blue';
const base =
'flex items-center justify-center rounded-full transition-all duration-1000';
const base = 'flex items-center justify-center rounded-full transition-all duration-1000';
const sizing = sizeToClasses(size);
let baseColors, onHover, onActive;
if (color === 'blue') {

@ -2,11 +2,7 @@ import Image from 'next/future/image';
import { memo } from 'react';
import { chain } from 'wagmi';
import {
avalancheChain,
bscChain,
celoMainnetChain,
} from '../../consts/networksConfig';
import { avalancheChain, bscChain, celoMainnetChain } from '../../consts/networksConfig';
import QuestionMark from '../../images/icons/question-mark.svg';
import Arbitrum from '../../images/logos/arbitrum.svg';
import Avalanche from '../../images/logos/avalanche.svg';
@ -27,13 +23,7 @@ const CHAIN_TO_ICON = {
[chain.polygon.id]: Polygon,
};
function _ChainIcon({
chainId,
size = 44,
}: {
chainId?: number;
size?: number;
}) {
function _ChainIcon({ chainId, size = 44 }: { chainId?: number; size?: number }) {
const imageSrc = (chainId && CHAIN_TO_ICON[chainId]) || QuestionMark;
return (

@ -1,10 +1,6 @@
import { PropsWithChildren } from 'react';
import {
BackgroundBanner,
BannerColorContext,
useBackgroundBannerState,
} from './BackgroundBanner';
import { BackgroundBanner, BannerColorContext, useBackgroundBannerState } from './BackgroundBanner';
export function ContentFrame(props: PropsWithChildren) {
// Provide context so children can change banner color
@ -12,10 +8,7 @@ export function ContentFrame(props: PropsWithChildren) {
return (
<div className="flex flex-col justify-center items-center min-h-full">
<div
style={styles.container}
className="relative overflow-visible mt-7 mb-8"
>
<div style={styles.container} className="relative overflow-visible mt-7 mb-8">
<BannerColorContext.Provider value={bannerState}>
<BackgroundBanner />
<div className="relative z-20">{props.children}</div>

@ -19,8 +19,7 @@ export function Footer() {
</div>
<div className="flex flex-col ml-3">
<p className="text-sm font-light">
<span className="text-base font-medium">Hyperlane</span> is the
platform
<span className="text-base font-medium">Hyperlane</span> is the platform
<br />
for developers building
<br />
@ -41,15 +40,7 @@ export function Footer() {
);
}
function FooterIconLink({
to,
imgSrc,
text,
}: {
to: string;
imgSrc: any;
text: string;
}) {
function FooterIconLink({ to, imgSrc, text }: { to: string; imgSrc: any; text: string }) {
return (
<a
href={to}

@ -32,9 +32,7 @@ export function Header() {
<div className="relative pt-1 ml-2">
<Image src={Name} width={124} height={28} alt="Hyperlane" />
</div>
<div className="font-serif text-[1.9rem] text-blue-500 sm:ml-2 pt-px">
Explorer
</div>
<div className="font-serif text-[1.9rem] text-blue-500 sm:ml-2 pt-px">Explorer</div>
</div>
</a>
</Link>
@ -45,20 +43,10 @@ export function Header() {
<Link href="/debugger">
<a className={styles.navLink}>Transaction Debugger</a>
</Link>
<a
className={styles.navLink}
target="_blank"
href={links.docs}
rel="noopener noreferrer"
>
<a className={styles.navLink} target="_blank" href={links.docs} rel="noopener noreferrer">
Docs
</a>
<a
className={styles.navLink}
target="_blank"
href={links.home}
rel="noopener noreferrer"
>
<a className={styles.navLink} target="_blank" href={links.home} rel="noopener noreferrer">
About
</a>
<NetworkSelector />
@ -70,25 +58,14 @@ export function Header() {
</div>
</div>
{/* Dropdown menu, used on mobile */}
<div
className={`${styles.dropdownContainer} ${!isOpen && 'hidden'} right-0`}
role="menu"
>
<div className={`${styles.dropdownContainer} ${!isOpen && 'hidden'} right-0`} role="menu">
<Link href="/">
<a
{...itemProps[0]}
className={styles.dropdownOption}
onClick={closeDropdown}
>
<a {...itemProps[0]} className={styles.dropdownOption} onClick={closeDropdown}>
<DropdownItemContent icon={HouseIcon} text="Home" />
</a>
</Link>
<Link href="/debugger">
<a
{...itemProps[1]}
className={styles.dropdownOption}
onClick={closeDropdown}
>
<a {...itemProps[1]} className={styles.dropdownOption} onClick={closeDropdown}>
<DropdownItemContent icon={BugIcon} text="Debugger" />
</a>
</Link>
@ -120,10 +97,7 @@ export function Header() {
target="_blank"
rel="noopener noreferrer"
>
<DropdownItemContent
icon={HubIcon}
text={isMainnet ? 'Testnet' : 'Mainnet'}
/>
<DropdownItemContent icon={HubIcon} text={isMainnet ? 'Testnet' : 'Mainnet'} />
</a>
</div>
</header>
@ -143,27 +117,17 @@ function NetworkSelector() {
const { buttonProps, itemProps, isOpen, setIsOpen } = useDropdownMenu(2);
return (
<div className="relative">
<button
className="flex items-center pb-px hover:opacity-60 transition-all"
{...buttonProps}
>
<button className="flex items-center pb-px hover:opacity-60 transition-all" {...buttonProps}>
<Image src={HubIcon} width={20} height={20} className="opacity-70" />
</button>
<div
className={`${styles.dropdownContainer} ${!isOpen && 'hidden'} right-0`}
role="menu"
>
<div className={`${styles.dropdownContainer} ${!isOpen && 'hidden'} right-0`} role="menu">
<a
{...itemProps[0]}
className={`${styles.dropdownOption} justify-center ${
config.environment === Environment.Mainnet && styles.activeEnv
}`}
onClick={() => setIsOpen(false)}
href={
config.environment !== Environment.Mainnet
? allConfigs.mainnet.url
: undefined
}
href={config.environment !== Environment.Mainnet ? allConfigs.mainnet.url : undefined}
target="_blank"
rel="noopener noreferrer"
>
@ -175,11 +139,7 @@ function NetworkSelector() {
className={`${styles.dropdownOption} justify-center ${
config.environment === Environment.Testnet2 && styles.activeEnv
}`}
href={
config.environment !== Environment.Testnet2
? allConfigs.testnet2.url
: undefined
}
href={config.environment !== Environment.Testnet2 ? allConfigs.testnet2.url : undefined}
target="_blank"
rel="noopener noreferrer"
>

@ -29,9 +29,7 @@ export function SearchBar({ value, onChangeValue, fetching }: Props) {
/>
<div className="bg-beige-300 h-10 sm:h-12 w-10 sm:w-12 flex items-center justify-center rounded">
{fetching && <Spinner classes="scale-[30%] mr-2.5" />}
{!fetching && !value && (
<Image src={SearchIcon} width={20} height={20} />
)}
{!fetching && !value && <Image src={SearchIcon} width={20} height={20} />}
{!fetching && value && (
<IconButton
imgSrc={XIcon}

@ -23,9 +23,7 @@ export function SearchError({
<div className="flex justify-center my-10">
<div className="flex flex-col items-center justify-center max-w-md px-3 py-5">
<Image src={imgSrc} width={imgWidth} className="opacity-80" />
<div className="mt-4 text-center leading-loose text-gray-700">
{text}
</div>
<div className="mt-4 text-center leading-loose text-gray-700">{text}</div>
</div>
</div>
</Fade>
@ -45,13 +43,7 @@ export function SearchInvalidError({ show }: { show: boolean }) {
);
}
export function SearchEmptyError({
show,
hasInput,
}: {
show: boolean;
hasInput: boolean;
}) {
export function SearchEmptyError({ show, hasInput }: { show: boolean; hasInput: boolean }) {
return (
<SearchError
show={show}

@ -123,10 +123,7 @@ export const allChains = [
celoAlfajoresChain,
];
export const chainIdToChain = allChains.reduce<Record<number, Chain>>(
(result, chain) => {
export const chainIdToChain = allChains.reduce<Record<number, Chain>>((result, chain) => {
result[chain.id] = chain;
return result;
},
{},
);
}, {});

@ -62,14 +62,7 @@ export function MessageDetails({ messageId }: { messageId: string }) {
} else if (bannerClassName) {
setBannerClassName('');
}
}, [
error,
fetching,
message,
isMessageFound,
bannerClassName,
setBannerClassName,
]);
}, [error, fetching, message, isMessageFound, bannerClassName, setBannerClassName]);
const reExecutor = useCallback(() => {
if (!isMessageFound || status !== MessageStatus.Delivered) {
@ -174,10 +167,7 @@ function TransactionCard({
help,
shouldBlur,
}: TransactionCardProps) {
const txExplorerLink = getTxExplorerLink(
chainId,
transaction?.transactionHash,
);
const txExplorerLink = getTxExplorerLink(chainId, transaction?.transactionHash);
return (
<Card classes="flex-1 min-w-fit space-y-4">
<div className="flex items-center justify-between">
@ -194,9 +184,7 @@ function TransactionCard({
<ValueRow
label="Chain:"
labelWidth="w-16"
display={`${getChainName(chainId)} (${chainId} / ${
chainToDomain[chainId]
})`}
display={`${getChainName(chainId)} (${chainId} / ${chainToDomain[chainId]})`}
displayWidth="w-44 sm:w-56"
blurValue={shouldBlur}
/>
@ -219,9 +207,7 @@ function TransactionCard({
<ValueRow
label="Block:"
labelWidth="w-16"
display={`${transaction.blockNumber} (${getDateTimeString(
transaction.timestamp,
)})`}
display={`${transaction.blockNumber} (${getDateTimeString(transaction.timestamp)})`}
displayWidth="w-44 sm:w-56"
blurValue={shouldBlur}
/>
@ -271,15 +257,10 @@ function DetailsCard({
<Card classes="mt-2 space-y-4">
<div className="flex items-center justify-between">
<div className="relative -top-px -left-0.5">
<ChainToChain
originChainId={originChainId}
destinationChainId={destinationChainId}
/>
<ChainToChain originChainId={originChainId} destinationChainId={destinationChainId} />
</div>
<div className="flex items-center pb-1">
<h3 className="text-gray-500 font-medium text-md mr-2">
Message Details
</h3>
<h3 className="text-gray-500 font-medium text-md mr-2">Message Details</h3>
<HelpIcon size={16} text={helpText.details} />
</div>
</div>
@ -333,24 +314,16 @@ function ValueRow({
return (
<div className="flex items-center pl-px">
<label className={`text-sm text-gray-500 ${labelWidth}`}>{label}</label>
<span
className={`text-sm ml-2 truncate ${displayWidth} ${
blurValue && 'blur-xs'
}`}
>
<span className={`text-sm ml-2 truncate ${displayWidth} ${blurValue && 'blur-xs'}`}>
{display}
</span>
{showCopy && (
<CopyButton copyValue={display} width={15} height={15} classes="ml-3" />
)}
{showCopy && <CopyButton copyValue={display} width={15} height={15} classes="ml-3" />}
</div>
);
}
function ErrorIcon() {
return (
<Image src={ErrorCircleIcon} width={24} height={24} className="invert" />
);
return <Image src={ErrorCircleIcon} width={24} height={24} className="invert" />;
}
const messageDetailsQuery = `
@ -410,10 +383,8 @@ query MessageDetails ($messageId: bigint!){
}`;
const helpText = {
origin:
'Info about the transaction that initiated the message placement into the outbox.',
origin: 'Info about the transaction that initiated the message placement into the outbox.',
destination:
'Info about the transaction that triggered the delivery of the message from an inbox.',
details:
'Immutable information about the message itself such as its contents.',
details: 'Immutable information about the message itself such as its contents.',
};

@ -47,9 +47,7 @@ export function MessageSearch() {
const debouncedSearchInput = useDebounce(searchInput, 750);
const hasInput = !!debouncedSearchInput;
const sanitizedInput = sanitizeString(debouncedSearchInput);
const isValidInput = hasInput
? isValidSearchQuery(sanitizedInput, true)
: true;
const isValidInput = hasInput ? isValidSearchQuery(sanitizedInput, true) : true;
// Filter state and handlers
const chainOptions = useMemo(getChainOptionList, []);
@ -85,37 +83,21 @@ export function MessageSearch() {
return (
<>
<SearchBar
value={searchInput}
onChangeValue={setSearchInput}
fetching={fetching}
/>
<SearchBar value={searchInput} onChangeValue={setSearchInput} fetching={fetching} />
<div className="w-full h-[38.05rem] mt-5 bg-white shadow-md border border-blue-50 rounded overflow-auto relative">
{/* Content header and filter bar */}
<div className="px-2 py-3 sm:px-4 md:px-5 md:py-3 flex items-center justify-between border-b border-gray-100">
<h2 className="text-gray-600">
{!hasInput ? 'Latest Messages' : 'Search Results'}
</h2>
<h2 className="text-gray-600">{!hasInput ? 'Latest Messages' : 'Search Results'}</h2>
<div className="flex items-center space-x-1 sm:space-x-2 md:space-x-3">
<div className="w-px h-8 bg-gray-100"></div>
<Image
src={FunnelIcon}
width={22}
height={22}
className="hidden sm:block opacity-50"
/>
<Image src={FunnelIcon} width={22} height={22} className="hidden sm:block opacity-50" />
<SelectField
classes="w-24 md:w-32"
options={chainOptions}
value={originChainFilter}
onValueSelect={onChangeOriginFilter}
/>
<Image
src={ArrowRightIcon}
width={30}
height={30}
className="opacity-50"
/>
<Image src={ArrowRightIcon} width={30} height={30} className="opacity-50" />
<SelectField
classes="w-24 md:w-32"
options={chainOptions}
@ -143,9 +125,7 @@ export function MessageSearch() {
<SearchUnknownError show={isValidInput && hasError} />
<SearchEmptyError
show={
isValidInput && !hasError && !fetching && messageList.length === 0
}
show={isValidInput && !hasError && !fetching && messageList.length === 0}
hasInput={hasInput}
/>
</div>
@ -163,11 +143,7 @@ function getChainOptionList(): Array<{ value: string; display: string }> {
];
}
function assembleQuery(
searchInput: string,
originFilter: string,
destFilter: string,
) {
function assembleQuery(searchInput: string, originFilter: string, destFilter: string) {
const hasInput = !!searchInput;
const variables = {
search: hasInput ? trimLeading0x(searchInput) : undefined,

@ -6,15 +6,7 @@ import { shortenAddress } from '../../utils/addresses';
import { getHumanReadableTimeString } from '../../utils/time';
export function MessageSummary({ message }: { message: MessageStub }) {
const {
id,
status,
sender,
recipient,
timestamp,
originChainId,
destinationChainId,
} = message;
const { id, status, sender, recipient, timestamp, originChainId, destinationChainId } = message;
let statusColor = 'bg-beige-500';
let statusText = 'Pending';
@ -29,33 +21,22 @@ export function MessageSummary({ message }: { message: MessageStub }) {
return (
<Link href={`/message/${id}`}>
<a className="flex items-center justify-between space-x-4 xs:space-x-9 sm:space-x-12 md:space-x-16">
<ChainToChain
originChainId={originChainId}
destinationChainId={destinationChainId}
/>
<ChainToChain originChainId={originChainId} destinationChainId={destinationChainId} />
<div className="flex items-center justify-between flex-1">
<div className={styles.valueContainer}>
<div className={styles.label}>Sender</div>
<div className={styles.value}>
{shortenAddress(sender) || 'Invalid Address'}
</div>
<div className={styles.value}>{shortenAddress(sender) || 'Invalid Address'}</div>
</div>
<div className="hidden sm:flex flex-col">
<div className={styles.label}>Recipient</div>
<div className={styles.value}>
{shortenAddress(recipient) || 'Invalid Address'}
</div>
<div className={styles.value}>{shortenAddress(recipient) || 'Invalid Address'}</div>
</div>
<div className={styles.valueContainer + ' sm:w-28'}>
<div className={styles.label}>Time sent</div>
<div className={styles.value}>
{getHumanReadableTimeString(timestamp)}
</div>
<div className={styles.value}>{getHumanReadableTimeString(timestamp)}</div>
</div>
</div>
<div
className={`w-20 md:w-24 py-2 text-sm text-center rounded ${statusColor}`}
>
<div className={`w-20 md:w-24 py-2 text-sm text-center rounded ${statusColor}`}>
{statusText}
</div>
</a>

@ -1,15 +1,10 @@
import { constants } from 'ethers';
import { chain } from 'wagmi';
import {
avalancheChain,
bscChain,
celoMainnetChain,
} from '../../consts/networksConfig';
import { avalancheChain, bscChain, celoMainnetChain } from '../../consts/networksConfig';
import { Message, MessageStatus, PartialTransactionReceipt } from '../../types';
const TX_HASH_ZERO =
'0x0000000000000000000000000000000000000000000000000000000000000000';
const TX_HASH_ZERO = '0x0000000000000000000000000000000000000000000000000000000000000000';
export const TX_ZERO: PartialTransactionReceipt = {
from: constants.AddressZero,

@ -1,10 +1,5 @@
import { domainToChain } from '../../consts/domains';
import {
Message,
MessageStatus,
MessageStub,
PartialTransactionReceipt,
} from '../../types';
import { Message, MessageStatus, MessageStub, PartialTransactionReceipt } from '../../types';
import { ensureLeading0x } from '../../utils/addresses';
import { logger } from '../../utils/logger';
@ -16,18 +11,12 @@ import {
TransactionEntry,
} from './types';
export function parseMessageStubResult(
data: MessagesStubQueryResult | undefined,
): MessageStub[] {
export function parseMessageStubResult(data: MessagesStubQueryResult | undefined): MessageStub[] {
if (!data?.message?.length) return [];
return data.message
.map(parseMessageStub)
.filter((m): m is MessageStub => !!m);
return data.message.map(parseMessageStub).filter((m): m is MessageStub => !!m);
}
export function parseMessageQueryResult(
data: MessagesQueryResult | undefined,
): Message[] {
export function parseMessageQueryResult(data: MessagesQueryResult | undefined): Message[] {
if (!data?.message?.length) return [];
return data.message.map(parseMessage).filter((m): m is Message => !!m);
}

@ -1,8 +1,5 @@
import { chainIdToChain } from '../../consts/networksConfig';
import {
isValidAddressFast,
isValidTransactionHash,
} from '../../utils/addresses';
import { isValidAddressFast, isValidTransactionHash } from '../../utils/addresses';
export function isValidSearchQuery(input: string, allowAddress?: boolean) {
if (!input) return false;

@ -8,15 +8,8 @@ import '@rainbow-me/rainbowkit/styles.css';
import type { AppProps } from 'next/app';
import { ToastContainer, Zoom, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import {
Provider as UrqlProvider,
createClient as createUrqlClient,
} from 'urql';
import {
WagmiConfig,
configureChains,
createClient as createWagmiClient,
} from 'wagmi';
import { Provider as UrqlProvider, createClient as createUrqlClient } from 'urql';
import { WagmiConfig, configureChains, createClient as createWagmiClient } from 'wagmi';
import { publicProvider } from 'wagmi/providers/public';
import { ErrorBoundary } from '../components/errors/ErrorBoundary';
@ -78,11 +71,7 @@ export default function App({ Component, router, pageProps }: AppProps) {
</AppLayout>
</UrqlProvider>
</RainbowKitProvider>
<ToastContainer
transition={Zoom}
position={toast.POSITION.BOTTOM_RIGHT}
limit={2}
/>
<ToastContainer transition={Zoom} position={toast.POSITION.BOTTOM_RIGHT} limit={2} />
</WagmiConfig>
</ErrorBoundary>
);

@ -6,23 +6,9 @@ export default function Document() {
<Head>
<meta charSet="utf-8" />
<link
rel="apple-touch-icon"
sizes="180x180"
href="/apple-touch-icon.png"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/favicon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/favicon-16x16.png"
/>
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
<link rel="manifest" href="/site.webmanifest" />
<link rel="mask-icon" href="/safari-pinned-tab.svg" color="#025aa1" />
<link rel="shortcut icon" href="/favicon.ico" />
@ -30,10 +16,7 @@ export default function Document() {
<meta name="theme-color" content="#ffffff" />
<meta name="application-name" content="Hyperlane Explorer" />
<meta
name="keywords"
content="Hyperlane Explorer App Multi-chain Cross-chain"
/>
<meta name="keywords" content="Hyperlane Explorer App Multi-chain Cross-chain" />
<meta
name="description"
content="A multi-chain explorer for the Hyperlane protocol and network"
@ -46,10 +29,7 @@ export default function Document() {
<meta property="og:url" content="https://explorer.hyperlane.xyz" />
<meta property="og:title" content="Hyperlane Explorer" />
<meta property="og:type" content="website" />
<meta
property="og:image"
content="https://explorer.hyperlane.xyz/logo-with-text.png"
/>
<meta property="og:image" content="https://explorer.hyperlane.xyz/logo-with-text.png" />
<meta
property="og:description"
content="A multi-chain explorer for the Hyperlane protocol and network"

@ -12,9 +12,7 @@ const Message: NextPage = () => {
useEffect(() => {
if (!messageId || typeof messageId !== 'string')
router
.replace('/')
.catch((e) => logger.error('Error routing back to home', e));
router.replace('/').catch((e) => logger.error('Error routing back to home', e));
}, [router, messageId]);
if (!messageId || typeof messageId !== 'string') return null;

@ -145,8 +145,7 @@ Dropdowns
padding: 0.5rem 0.6rem;
border: 1px solid #f1f1f1;
border-radius: 0.5rem;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: transform 0.2s ease, opacity 0.2s ease, visibility 0s linear 0.2s;
will-change: transform;
}

@ -37,9 +37,7 @@ export function shortenAddress(address: string, capitalize?: boolean) {
try {
const normalized = normalizeAddress(address);
const shortened =
normalized.substring(0, 6) +
'...' +
normalized.substring(normalized.length - 4);
normalized.substring(0, 6) + '...' + normalized.substring(normalized.length - 4);
return capitalize ? capitalizeAddress(shortened) : shortened;
} catch (error) {
logger.error('Unable to shorten invalid address', address, error);

@ -1,5 +1,3 @@
export function invertKeysAndValues(data: any) {
return Object.fromEntries(
Object.entries(data).map(([key, value]) => [value, key]),
);
return Object.fromEntries(Object.entries(data).map(([key, value]) => [value, key]));
}

@ -15,7 +15,5 @@ export function sanitizeString(str: string) {
export function trimToLength(value: string, maxLength: number) {
if (!value) return '';
const trimmed = value.trim();
return trimmed.length > maxLength
? trimmed.substring(0, maxLength) + '...'
: trimmed;
return trimmed.length > maxLength ? trimmed.substring(0, maxLength) + '...' : trimmed;
}

@ -67,17 +67,12 @@ export async function fetchWithTimeout(
}
export function sleep(milliseconds: number) {
return new Promise((resolve) =>
setTimeout(() => resolve(true), milliseconds),
);
return new Promise((resolve) => setTimeout(() => resolve(true), milliseconds));
}
export const PROMISE_TIMEOUT = '__promise_timeout__';
export async function promiseTimeout<T>(
promise: Promise<T>,
milliseconds: number,
) {
export async function promiseTimeout<T>(promise: Promise<T>, milliseconds: number) {
// Create a promise that rejects in <ms> milliseconds
const timeout = new Promise<T>((_resolve, reject) => {
const id = setTimeout(() => {

Loading…
Cancel
Save