Merge pull request #54 from hyperlane-xyz/v3

- Update to v3 sdk
- Upgrade to yarn 4
pull/55/head
J M Rossy 1 year ago committed by GitHub
commit 7f9d7893ea
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 785
      .yarn/releases/yarn-3.2.0.cjs
  2. 893
      .yarn/releases/yarn-4.0.1.cjs
  3. 8
      .yarnrc.yml
  4. 2
      README.md
  5. 10
      package.json
  6. 10
      src/components/icons/ChainLogo.tsx
  7. 3
      src/components/layout/AppLayout.tsx
  8. 6
      src/components/nav/Footer.tsx
  9. 11
      src/components/nav/Header.tsx
  10. 6
      src/components/nav/InfoBanner.tsx
  11. 6
      src/components/search/SearchFilterBar.tsx
  12. 2
      src/consts/config.ts
  13. 10
      src/consts/links.ts
  14. 6
      src/features/chains/ConfigureChains.tsx
  15. 2
      src/features/chains/MissingChainConfigToast.tsx
  16. 13
      src/features/chains/chainConfig.ts
  17. 4
      src/features/chains/utils.ts
  18. 4
      src/features/messages/cards/GasDetailsCard.tsx
  19. 4
      src/features/messages/cards/IsmDetailsCard.tsx
  20. 1
      src/features/messages/cards/TimelineCard.tsx
  21. 5
      src/features/messages/ica.ts
  22. 3
      src/features/messages/pi-queries/fetchPiChainMessages.ts
  23. 2
      src/features/providers/SmartProvider.ts
  24. 2
      src/global.d.ts
  25. 6755
      yarn.lock

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1,7 +1,13 @@
compressionLevel: mixed
enableGlobalCache: false
enableScripts: false
nodeLinker: node-modules
plugins:
- path: .yarn/plugins/@yarnpkg/plugin-outdated.cjs
spec: "https://mskelton.dev/yarn-outdated/v3"
yarnPath: .yarn/releases/yarn-3.2.0.cjs
yarnPath: .yarn/releases/yarn-4.0.1.cjs

@ -31,4 +31,4 @@ yarn lint
## Learn more
For more information, see the [Hyperlane documentation](https://docs.hyperlane.xyz/hyperlane-docs/).
For more information, see the [Hyperlane documentation](https://v3.hyperlane.xyz).

@ -1,13 +1,13 @@
{
"name": "@hyperlane-xyz/explorer",
"description": "An interchain explorer for the Hyperlane protocol and network.",
"version": "1.5.1",
"version": "3.1.4",
"author": "J M Rossy",
"dependencies": {
"@headlessui/react": "^1.7.17",
"@hyperlane-xyz/sdk": "1.5.1",
"@hyperlane-xyz/utils": "1.5.1",
"@hyperlane-xyz/widgets": "1.5.0",
"@hyperlane-xyz/sdk": "3.1.4",
"@hyperlane-xyz/utils": "3.1.4",
"@hyperlane-xyz/widgets": "3.1.4",
"@metamask/jazzicon": "https://github.com/jmrossy/jazzicon#7a8df28974b4e81129bfbe3cab76308b889032a6",
"@rainbow-me/rainbowkit": "0.12.16",
"@tanstack/react-query": "^4.24.10",
@ -48,7 +48,7 @@
"homepage": "https://www.hyperlane.xyz",
"license": "Apache-2.0",
"main": "dist/src/index.js",
"packageManager": "yarn@3.2.0",
"packageManager": "yarn@4.0.1",
"private": true,
"repository": {
"type": "git",

@ -5,9 +5,13 @@ import { ChainLogo as ChainLogoInner } from '@hyperlane-xyz/widgets';
import { getChainName } from '../../features/chains/utils';
import { useMultiProvider } from '../../features/providers/multiProvider';
export function ChainLogo(props: ComponentProps<typeof ChainLogoInner>) {
const { chainName, ...rest } = props;
// TODO widget lib for new chainid type
type Props = Omit<ComponentProps<typeof ChainLogoInner>, 'chainId'> & { chainId: number | string };
export function ChainLogo(props: Props) {
const { chainName, chainId, ...rest } = props;
const multiProvider = useMultiProvider();
const name = chainName || getChainName(multiProvider, props.chainId);
return <ChainLogoInner {...rest} chainName={name} />;
const chainIdNumber = typeof chainId === 'number' ? chainId : undefined;
return <ChainLogoInner {...rest} chainName={name} chainId={chainIdNumber} />;
}

@ -5,6 +5,7 @@ import { toTitleCase } from '@hyperlane-xyz/utils';
import { Footer } from '../nav/Footer';
import { Header } from '../nav/Header';
import { InfoBanner } from '../nav/InfoBanner';
interface Props {
pathName: string;
@ -22,7 +23,7 @@ export function AppLayout({ pathName, children }: PropsWithChildren<Props>) {
style={styles.container}
className="relative w-full min-w-screen h-full min-h-screen flex flex-col justify-between bg-blue-500"
>
{/* <InfoBanner /> */}
<InfoBanner />
<Header pathName={pathName} />
<div className="max-w-5xl mx-auto grow">
<main style={styles.main} className="relative min-h-full pt-3 z-20">

@ -2,7 +2,7 @@
import Image from 'next/image';
import Link from 'next/link';
import { links } from '../../consts/links';
import { docLinks, links } from '../../consts/links';
// import FooterLine from '../../images/backgrounds/footer-line-desktop.svg';
// import FooterLineMobile from '../../images/backgrounds/footer-line-mobile.svg';
import FooterBg from '../../images/backgrounds/footer-bg.svg';
@ -15,9 +15,9 @@ import { Medium } from '../icons/Medium';
import { Twitter } from '../icons/Twitter';
const footerLinks1 = [
{ title: 'Docs', url: links.docs, external: true },
{ title: 'Docs', url: docLinks.home, external: true },
{ title: 'Homepage', url: links.home, external: true },
{ title: 'Chains', url: links.chains, external: true },
{ title: 'Chains', url: docLinks.chains, external: true },
];
const footerLinks2 = [

@ -2,7 +2,7 @@ import Image from 'next/image';
import Link from 'next/link';
import { PropsWithChildren, useEffect, useState } from 'react';
import { links } from '../../consts/links';
import { docLinks, links } from '../../consts/links';
import Explorer from '../../images/logos/hyperlane-explorer.svg';
import Logo from '../../images/logos/hyperlane-logo.svg';
import Name from '../../images/logos/hyperlane-name.svg';
@ -68,7 +68,12 @@ export function Header({ pathName }: { pathName: string }) {
<a className={navLinkClass()} target="_blank" href={links.home} rel="noopener noreferrer">
About
</a>
<a className={navLinkClass()} target="_blank" href={links.docs} rel="noopener noreferrer">
<a
className={navLinkClass()}
target="_blank"
href={docLinks.home}
rel="noopener noreferrer"
>
Docs
</a>
{showSearch && <MiniSearchBar />}
@ -96,7 +101,7 @@ export function Header({ pathName }: { pathName: string }) {
</MobileNavLink>
),
(c: Fn) => (
<MobileNavLink href={links.docs} closeDropdown={c} key="Docs">
<MobileNavLink href={docLinks.home} closeDropdown={c} key="Docs">
Docs
</MobileNavLink>
),

@ -1,13 +1,13 @@
export function InfoBanner() {
return (
<a
href="https://explorer-v1.hyperlane.xyz"
href="https://explorer-v2.hyperlane.xyz"
target="_blank"
rel="noopener noreferrer"
className="block py-1.5 w-full text-white text-center text-sm bg-blue-600 hover:bg-blue-700 active:bg-blue-800 ring-1 ring-inset ring-green-700 transition-all duration-300"
>
This is the Explorer for Hyperlane version 2.{' '}
<span className="underline underline-offset-2">Use version 1</span>
This is the explorer for Hyperlane version 3.{' '}
<span className="underline underline-offset-2">Use version 2</span>
</a>
);
}

@ -90,7 +90,7 @@ function ChainMultiSelector({
const [checkedChains, setCheckedChains] = useState(
value
? arrayToObject(value.split(','))
: arrayToObject(mainnetAndTestChains.map((c) => c.chainId)),
: arrayToObject(mainnetAndTestChains.map((c) => c.chainId.toString())),
);
const hasAnyUncheckedChain = (chains: ChainMetadata[]) => {
@ -113,7 +113,7 @@ function ChainMultiSelector({
const onToggleSection = (chains: ChainMetadata[]) => {
return () => {
const chainIds = chains.map((c) => c.chainId);
const chainIds = chains.map((c) => c.chainId.toString());
if (hasAnyUncheckedChain(chains)) {
// If some are unchecked, check all
setCheckedChains({ ...checkedChains, ...arrayToObject(chainIds, true) });
@ -125,7 +125,7 @@ function ChainMultiSelector({
};
const onToggleAll = () => {
setCheckedChains(arrayToObject(mainnetAndTestChains.map((c) => c.chainId)));
setCheckedChains(arrayToObject(mainnetAndTestChains.map((c) => c.chainId.toString())));
};
const onToggleNone = () => {

@ -12,6 +12,6 @@ interface Config {
export const config: Config = Object.freeze({
debug: isDevMode,
version,
apiUrl: 'https://hyperlane-explorer-3.hasura.app/v1/graphql',
apiUrl: 'https://explorer4.hasura.app/v1/graphql',
explorerApiKeys,
});

@ -3,8 +3,6 @@ export const links = {
home: 'https://www.hyperlane.xyz',
discord: 'https://discord.gg/VK9ZUy3aTV',
github: 'https://github.com/hyperlane-xyz',
docs: 'https://docs.hyperlane.xyz',
chains: 'https://docs.hyperlane.xyz/docs/resources/domains',
jobs: 'https://jobs.lever.co/Hyperlane',
twitter: 'https://twitter.com/hyperlane_xyz',
blog: 'https://medium.com/hyperlane',
@ -13,3 +11,11 @@ export const links = {
brand:
'https://www.figma.com/file/jC5NORmNDCl6WZgjIRwKX5/Hyperlane-Brand-Assets-%5BExternal%5D?type=design&node-id=0-1&t=6eez9F8gttV7L6VG-0',
};
export const docLinks = {
home: 'https://v3.hyperlane.xyz',
chains: 'https://v3.hyperlane.xyz/docs/reference/domains',
pi: 'https://v3.hyperlane.xyz/docs/deploy-hyperlane',
ism: 'https://v3.hyperlane.xyz/docs/reference/ISM/specify-your-ISM',
gas: 'https://v3.hyperlane.xyz/docs/protocol/interchain-gas-payment',
};

@ -8,7 +8,7 @@ import { XIconButton } from '../../components/buttons/XIconButton';
import { ChainLogo } from '../../components/icons/ChainLogo';
import { Card } from '../../components/layout/Card';
import { Modal } from '../../components/layout/Modal';
import { links } from '../../consts/links';
import { docLinks } from '../../consts/links';
import { useMultiProvider } from '../providers/multiProvider';
import { tryParseChainConfig } from './chainConfig';
@ -61,7 +61,7 @@ export function ConfigureChains() {
<p className="mt-3 font-light">
Hyperlane can be deployed to any chain using{' '}
<a
href={`${links.docs}/docs/deploy/permissionless-interoperability`}
href={docLinks.pi}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-2 text-blue-500 hover:text-blue-400"
@ -149,7 +149,7 @@ export function ConfigureChains() {
Input a chain metadata config including core contract addresses to enable exploration of
that chain. See{' '}
<a
href={`${links.docs}/docs/build-with-hyperlane/explorer/configuring-pi-chains`}
href={docLinks.pi}
target="_blank"
rel="noopener noreferrer"
className="underline underline-offset-2 text-blue-500 hover:text-blue-400"

@ -5,7 +5,7 @@ export function MissingChainConfigToast({
chainId,
}: {
domainId: number;
chainId: number | null | undefined;
chainId: number | string | null | undefined;
}) {
const errorDesc = chainId
? `chain ID: ${chainId}`

@ -1,15 +1,16 @@
import { z } from 'zod';
import { ChainMetadataSchema, MultiProvider } from '@hyperlane-xyz/sdk';
import { ChainMetadata, ChainMetadataSchema, MultiProvider } from '@hyperlane-xyz/sdk';
import { logger } from '../../utils/logger';
export const ChainConfigSchema = ChainMetadataSchema.extend({
mailbox: z.string().optional(),
interchainGasPaymaster: z.string().optional(),
});
export const ChainConfigSchema = z.record(
ChainMetadataSchema.and(
z.object({ mailbox: z.string().optional(), interchainGasPaymaster: z.string().optional() }),
),
);
export type ChainConfig = z.infer<typeof ChainConfigSchema>;
export type ChainConfig = ChainMetadata & { mailbox?: Address; interchainGasPaymaster?: Address };
type ParseResult =
| {

@ -10,7 +10,7 @@ import { Environment } from '../../consts/environments';
import { ChainConfig } from './chainConfig';
export function getChainName(mp: MultiProvider, chainId?: number) {
export function getChainName(mp: MultiProvider, chainId?: number | string) {
return mp.tryGetChainName(chainId || 0) || undefined;
}
@ -35,6 +35,6 @@ export function getChainEnvironment(mp: MultiProvider, chainIdOrName: number | s
return isTestnet ? Environment.Testnet : Environment.Mainnet;
}
export function isPiChain(chainId: number) {
export function isPiChain(chainId: number | string) {
return !chainIdToMetadata[chainId];
}

@ -8,7 +8,7 @@ import { fromWei, toTitleCase } from '@hyperlane-xyz/utils';
import { RadioButtons } from '../../../components/buttons/RadioButtons';
import { HelpIcon } from '../../../components/icons/HelpIcon';
import { Card } from '../../../components/layout/Card';
import { links } from '../../../consts/links';
import { docLinks } from '../../../consts/links';
import FuelPump from '../../../images/icons/fuel-pump.svg';
import { Message } from '../../../types';
import { BigNumberMax } from '../../../utils/big-number';
@ -84,7 +84,7 @@ export function GasDetailsCard({ message, blur, igpPayments = {} }: Props) {
<p className="text-sm font-light">
Interchain gas payments are required to fund message delivery on the destination chain.{' '}
<a
href={`${links.docs}/docs/protocol/interchain-gas-payments`}
href={docLinks.gas}
target="_blank"
rel="noopener noreferrer"
className="cursor-pointer text-blue-500 hover:text-blue-400 active:text-blue-300 transition-all"

@ -4,7 +4,7 @@ import { isNullish } from '@hyperlane-xyz/utils';
import { HelpIcon } from '../../../components/icons/HelpIcon';
import { Card } from '../../../components/layout/Card';
import { links } from '../../../consts/links';
import { docLinks } from '../../../consts/links';
import ShieldLock from '../../../images/icons/shield-lock.svg';
import { IsmModuleTypes, MessageDebugResult } from '../../debugger/types';
@ -31,7 +31,7 @@ export function IsmDetailsCard({ ismDetails, blur }: Props) {
<p className="text-sm font-light">
Interchain Security Modules define the rules for verifying messages before delivery.{' '}
<a
href={`${links.docs}/docs/protocol/sovereign-consensus`}
href={docLinks.ism}
target="_blank"
rel="noopener noreferrer"
className="cursor-pointer text-blue-500 hover:text-blue-400 active:text-blue-300 transition-all"

@ -9,6 +9,7 @@ interface Props {
}
export function TimelineCard({ message, blur }: Props) {
// @ts-ignore TODO update widget chainId type
const { stage, timings } = useMessageStage({ message });
return (

@ -3,14 +3,15 @@ import { BigNumber, providers, utils } from 'ethers';
import { useMemo } from 'react';
import { InterchainAccountRouter__factory } from '@hyperlane-xyz/core';
import { hyperlaneEnvironments } from '@hyperlane-xyz/sdk';
import { eqAddress, isValidAddress } from '@hyperlane-xyz/utils';
import { logger } from '../../utils/logger';
import { useMultiProvider } from '../providers/multiProvider';
// This assumes all chains have the same ICA address
const ICA_ADDRESS = hyperlaneEnvironments.mainnet.ethereum.interchainAccountRouter;
// const ICA_ADDRESS = hyperlaneEnvironments.mainnet.ethereum.interchainAccountRouter;
// TODO V3 determine what ICA address should be
const ICA_ADDRESS = '';
export function useIsIcaMessage({ sender, recipient }: { sender: Address; recipient: Address }) {
return useMemo(() => isIcaMessage({ sender, recipient }), [sender, recipient]);

@ -3,6 +3,7 @@ import { BigNumber, constants, ethers, providers } from 'ethers';
import { IInterchainGasPaymaster__factory, Mailbox__factory } from '@hyperlane-xyz/core';
import { MultiProvider } from '@hyperlane-xyz/sdk';
import {
ProtocolType,
addressToBytes32,
bytes32ToAddress,
isValidAddress,
@ -72,7 +73,7 @@ export async function fetchMessagesFromPiChain(
let logs: ExtendedLog[] = [];
if (isValidAddress(input) && (!queryType || queryType === PiQueryType.Address)) {
logs = await fetchLogsForAddress(chainConfig, query, multiProvider);
} else if (isValidTransactionHash(input)) {
} else if (isValidTransactionHash(input, ProtocolType.Ethereum)) {
if (!queryType || queryType === PiQueryType.TxHash) {
logs = await fetchLogsForTxHash(chainConfig, query, multiProvider);
}

@ -227,7 +227,7 @@ function chainMetadataToProviderNetwork(
): providers.Network {
return {
name: chainMetadata.name,
chainId: chainMetadata.chainId,
chainId: chainMetadata.chainId as number,
// @ts-ignore add ensAddress to ChainMetadata
ensAddress: chainMetadata.ensAddress,
};

2
src/global.d.ts vendored

@ -1,6 +1,6 @@
declare type Address = string;
declare type HexString = string;
declare type ChainId = number;
declare type ChainId = number | string;
declare type DomainId = number;
declare type AddressTo<T> = Record<Address, T>;
declare type Fn = () => void;

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save