feat: use chain name or domain as identifier instead of chainId (#136)

relates to:
- https://github.com/hyperlane-xyz/hyperlane-warp-ui-template/pull/313
- https://github.com/hyperlane-xyz/hyperlane-monorepo/pull/4798

testing:
- [x] update SDK to latest once monorepo PR is merged + rolled out
- [x] add duplicate chain metadata with different domain id to custom
yaml

---------

Signed-off-by: pbio <10051819+paulbalaji@users.noreply.github.com>
pull/137/head
Paul Balaji 4 weeks ago committed by GitHub
parent ec0db733e5
commit b8e0d310e3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 6
      package.json
  2. 7
      src/components/icons/ChainLogo.tsx
  3. 10
      src/components/search/SearchFilterBar.tsx
  4. 15
      src/features/chains/MissingChainConfigToast.tsx
  5. 8
      src/features/chains/queries/useScrapedChains.ts
  6. 18
      src/features/chains/utils.ts
  7. 16
      src/features/deliveryStatus/fetchDeliveryStatus.ts
  8. 17
      src/features/deliveryStatus/useMessageDeliveryStatus.tsx
  9. 26
      src/features/messages/MessageDetails.tsx
  10. 15
      src/features/messages/MessageTable.tsx
  11. 2
      src/features/messages/cards/GasDetailsCard.tsx
  12. 47
      src/features/messages/cards/TransactionCard.tsx
  13. 43
      src/features/messages/pi-queries/fetchPiChainMessages.ts
  14. 5
      src/features/messages/pi-queries/usePiChainMessageQuery.ts
  15. 14
      src/features/messages/queries/parse.ts
  16. 26
      src/utils/explorers.ts
  17. 75
      yarn.lock

@ -6,9 +6,9 @@
"dependencies": {
"@headlessui/react": "^2.1.8",
"@hyperlane-xyz/registry": "5.1.0",
"@hyperlane-xyz/sdk": "5.7.0",
"@hyperlane-xyz/utils": "5.7.0",
"@hyperlane-xyz/widgets": "5.7.0",
"@hyperlane-xyz/sdk": "6.0.0",
"@hyperlane-xyz/utils": "6.0.0",
"@hyperlane-xyz/widgets": "6.0.0",
"@tanstack/react-query": "^5.35.5",
"bignumber.js": "^9.1.2",
"buffer": "^6.0.3",

@ -1,21 +1,18 @@
import { ChainLogo as ChainLogoInner } from '@hyperlane-xyz/widgets';
import { useMultiProvider, useRegistry } from '../../store';
import { useRegistry } from '../../store';
export function ChainLogo({
chainId,
chainName,
background,
size,
}: {
chainId: ChainId;
chainName?: string;
background?: boolean;
size?: number;
}) {
const multiProvider = useMultiProvider();
const registry = useRegistry();
const name = chainName || multiProvider.tryGetChainName(chainId) || '';
const name = chainName || '';
return (
<ChainLogoInner chainName={name} registry={registry} size={size} background={background} />
);

@ -64,14 +64,16 @@ function ChainSelector({
onChangeValue,
}: {
text: string;
value: ChainId | null;
value: string | null;
onChangeValue: (value: string | null) => void;
}) {
const { isOpen, open, close } = useModal();
const multiProvider = useMultiProvider();
const chainName = value
? trimToLength(getChainDisplayName(multiProvider, value, true), 12)
const chainName = value ? multiProvider.getChainName(value) : undefined;
const chainDisplayName = chainName
? trimToLength(getChainDisplayName(multiProvider, chainName, true), 12)
: undefined;
const onClickChain = (c: ChainMetadata) => {
@ -93,7 +95,7 @@ function ChainSelector({
)}
onClick={open}
>
<span>{chainName || text} </span>
<span>{chainDisplayName || text} </span>
{!value && (
<ChevronIcon
direction="s"

@ -1,18 +1,7 @@
export function MissingChainConfigToast({
domainId,
chainId,
}: {
domainId: number;
chainId: number | string | null | undefined;
}) {
const errorDesc = chainId
? `chain ID: ${chainId}`
: domainId
? `domain ID: ${domainId}`
: 'unknown message chain';
export function MissingChainConfigToast({ domainId }: { domainId: number }) {
return (
<div>
<span>{`No chain config found for ${errorDesc}. You can add a config in the origin/destination chain selector.`}</span>
<span>{`No chain config found for domain ${domainId}. You can add a config in the origin/destination chain selector.`}</span>
</div>
);
}

@ -42,8 +42,8 @@ export function useScrapedChains(multiProvider: MultiProvider) {
const scrapedChains = objFilter(
chainMetadata,
(_, chainMetadata): chainMetadata is ChainMetadata =>
!isPiChain(multiProvider, scrapedDomains, chainMetadata.chainId) &&
!isUnscrapedDbChain(multiProvider, chainMetadata.chainId),
!isPiChain(multiProvider, scrapedDomains, chainMetadata.domainId) &&
!isUnscrapedDbChain(multiProvider, chainMetadata.domainId),
);
return { chains: scrapedChains };
}, [multiProvider, chainMetadata, scrapedDomains]);
@ -52,7 +52,7 @@ export function useScrapedChains(multiProvider: MultiProvider) {
}
// TODO: Remove once all chains in the DB are scraped
export function isUnscrapedDbChain(multiProvider: MultiProvider, chainIdOrName: number | string) {
const chainName = multiProvider.tryGetChainName(chainIdOrName);
export function isUnscrapedDbChain(multiProvider: MultiProvider, domainId: DomainId) {
const chainName = multiProvider.tryGetChainName(domainId);
return chainName && unscrapedChainsInDb.includes(chainName);
}

@ -19,18 +19,18 @@ export async function getMailboxAddress(
export function getChainDisplayName(
multiProvider: MultiProvider,
chainOrDomainId?: ChainId | DomainId,
chainName?: string,
shortName = false,
fallbackToId = true,
): string {
const metadata = multiProvider.tryGetChainMetadata(chainOrDomainId || 0);
if (!metadata) return fallbackToId && chainOrDomainId ? chainOrDomainId.toString() : 'Unknown';
const metadata = multiProvider.tryGetChainMetadata(chainName || 0);
if (!metadata) return fallbackToId && chainName ? chainName : 'Unknown';
const displayName = shortName ? metadata.displayNameShort : metadata.displayName;
return toTitleCase(displayName || metadata.displayName || metadata.name);
}
export function getChainEnvironment(multiProvider: MultiProvider, chainIdOrName: number | string) {
const isTestnet = multiProvider.tryGetChainMetadata(chainIdOrName)?.isTestnet;
export function getChainEnvironment(multiProvider: MultiProvider, domainId: DomainId) {
const isTestnet = multiProvider.tryGetChainMetadata(domainId)?.isTestnet;
return isTestnet ? Environment.Testnet : Environment.Mainnet;
}
@ -38,14 +38,14 @@ export function getChainEnvironment(multiProvider: MultiProvider, chainIdOrName:
export function isPiChain(
multiProvider: MultiProvider,
scrapedChains: DomainsEntry[],
chainIdOrName: number | string,
domainId: DomainId,
) {
const chainName = multiProvider.tryGetChainName(chainIdOrName);
const chainName = multiProvider.tryGetChainName(domainId);
// Note: .trim() because one chain name in the DB has a trailing \n char for some reason
return !chainName || !scrapedChains.find((chain) => chain.name.trim() === chainName);
}
export function isEvmChain(multiProvider: MultiProvider, chainIdOrName: number | string) {
const protocol = multiProvider.tryGetProtocol(chainIdOrName);
export function isEvmChain(multiProvider: MultiProvider, domainId: DomainId) {
const protocol = multiProvider.tryGetProtocol(domainId);
return protocol === ProtocolType.Ethereum;
}

@ -25,7 +25,7 @@ export async function fetchDeliveryStatus(
overrideChainMetadata: ChainMap<Partial<ChainMetadata>>,
message: Message,
): Promise<MessageDeliveryStatusResponse> {
const destName = multiProvider.getChainName(message.destinationChainId);
const destName = multiProvider.getChainName(message.destinationDomainId);
const destMailboxAddr = await getMailboxAddress(destName, overrideChainMetadata, registry);
if (!destMailboxAddr)
throw new Error(
@ -41,7 +41,7 @@ export async function fetchDeliveryStatus(
if (isDelivered) {
const txDetails = await fetchTransactionDetails(
multiProvider,
message.destinationChainId,
message.destinationDomainId,
transactionHash,
);
// If a delivery (aka process) tx is found, mark as success
@ -85,8 +85,8 @@ async function checkIsMessageDelivered(
message: Message,
mailboxAddr: Address,
) {
const { msgId, destinationChainId } = message;
const provider = multiProvider.getProvider(destinationChainId);
const { msgId, destinationDomainId } = message;
const provider = multiProvider.getProvider(destinationDomainId);
const mailbox = IMailbox__factory.connect(mailboxAddr, provider);
// Try finding logs first as they have more info
@ -114,9 +114,13 @@ async function checkIsMessageDelivered(
return { isDelivered };
}
function fetchTransactionDetails(multiProvider: MultiProvider, chainId: ChainId, txHash?: string) {
function fetchTransactionDetails(
multiProvider: MultiProvider,
domainId: DomainId,
txHash?: string,
) {
if (!txHash) return null;
logger.debug(`Searching for transaction details for ${txHash}`);
const provider = multiProvider.getProvider(chainId);
const provider = multiProvider.getProvider(domainId);
return provider.getTransaction(txHash);
}

@ -31,12 +31,11 @@ export function useMessageDeliveryStatus({
return { message };
}
const { id, originChainId, originDomainId, destinationChainId, destinationDomainId } =
message;
const { id, originDomainId, destinationDomainId } = message;
if (
!checkChain(multiProvider, originChainId, originDomainId) ||
!checkChain(multiProvider, destinationChainId, destinationDomainId)
!checkChain(multiProvider, originDomainId) ||
!checkChain(multiProvider, destinationDomainId)
) {
return { message };
}
@ -93,13 +92,13 @@ export function useMessageDeliveryStatus({
};
}
function checkChain(multiProvider: MultiProvider, chainId: ChainId, domainId: number) {
if (!multiProvider.hasChain(chainId)) {
toast.error(<MissingChainConfigToast chainId={chainId} domainId={domainId} />);
function checkChain(multiProvider: MultiProvider, domainId: number) {
if (!multiProvider.hasChain(domainId)) {
toast.error(<MissingChainConfigToast domainId={domainId} />);
return false;
}
if (!isEvmChain(multiProvider, chainId)) {
logger.debug('Skipping delivery status check for non-EVM chain:', chainId);
if (!isEvmChain(multiProvider, domainId)) {
logger.debug('Skipping delivery status check for non-EVM chain:', domainId);
return false;
}
return true;

@ -73,17 +73,8 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
enabled: isMessageFound,
});
const {
msgId,
status,
originChainId,
destinationChainId,
originDomainId,
destinationDomainId,
origin,
destination,
isPiMsg,
} = message;
const { msgId, status, originDomainId, destinationDomainId, origin, destination, isPiMsg } =
message;
const duration = destination?.timestamp
? getHumanReadableDuration(destination.timestamp - origin.timestamp, 3)
@ -91,12 +82,15 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
const showTimeline =
!isPiMsg &&
isEvmChain(multiProvider, originChainId) &&
isEvmChain(multiProvider, destinationChainId);
isEvmChain(multiProvider, originDomainId) &&
isEvmChain(multiProvider, destinationDomainId);
// Banner color setter
useDynamicBannerColor(isFetching, status, isMessageFound, isError || isPiError);
const originChainName = multiProvider.getChainName(originDomainId);
const destinationChainName = multiProvider.getChainName(destinationDomainId);
return (
<>
<Card className="flex items-center justify-between rounded-full px-1">
@ -104,7 +98,7 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
isIcaMsg ? 'ICA ' : ''
} Message ${trimToLength(msgId, 6)} to ${getChainDisplayName(
multiProvider,
destinationChainId,
destinationChainName,
)}`}</h2>
<StatusHeader
messageStatus={status}
@ -115,13 +109,13 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro
</Card>
<div className="mt-3 flex flex-wrap items-stretch justify-between gap-3 md:mt-4 md:gap-4">
<OriginTransactionCard
chainId={originChainId}
chainName={originChainName}
domainId={originDomainId}
transaction={origin}
blur={blur}
/>
<DestinationTransactionCard
chainId={destinationChainId}
chainName={destinationChainName}
domainId={destinationDomainId}
status={status}
transaction={destination}

@ -53,7 +53,7 @@ export function MessageTable({
}
export function MessageSummaryRow({ message, mp }: { message: MessageStub; mp: MultiProvider }) {
const { msgId, status, sender, recipient, originChainId, destinationChainId, origin } = message;
const { msgId, status, sender, recipient, originDomainId, destinationDomainId, origin } = message;
let statusIcon = undefined;
let statusTitle = '';
@ -67,15 +67,20 @@ export function MessageSummaryRow({ message, mp }: { message: MessageStub; mp: M
const base64 = message.isPiMsg ? serializeMessage(message) : undefined;
const originChainName = mp.getChainName(originDomainId);
const destinationChainName = mp.getChainName(destinationDomainId);
return (
<>
<LinkCell id={msgId} base64={base64} aClasses="flex items-center py-3.5 pl-3 sm:pl-5">
<ChainLogo chainId={originChainId} size={20} />
<div className={styles.chainName}>{getChainDisplayName(mp, originChainId, true)}</div>
<ChainLogo chainName={originChainName} size={20} />
<div className={styles.chainName}>{getChainDisplayName(mp, originChainName, true)}</div>
</LinkCell>
<LinkCell id={msgId} base64={base64} aClasses="flex items-center py-3.5 ">
<ChainLogo chainId={destinationChainId} size={20} />
<div className={styles.chainName}>{getChainDisplayName(mp, destinationChainId, true)}</div>
<ChainLogo chainName={destinationChainName} size={20} />
<div className={styles.chainName}>
{getChainDisplayName(mp, destinationChainName, true)}
</div>
</LinkCell>
<LinkCell id={msgId} base64={base64} tdClasses="hidden sm:table-cell" aClasses={styles.value}>
{shortenAddress(sender) || 'Invalid Address'}

@ -27,7 +27,7 @@ interface Props {
export function GasDetailsCard({ message, blur, igpPayments = {} }: Props) {
const multiProvider = useMultiProvider();
const unitOptions = useMemo(() => {
const originMetadata = multiProvider.tryGetChainMetadata(message.originChainId);
const originMetadata = multiProvider.tryGetChainMetadata(message.originDomainId);
const nativeCurrencyName = originMetadata?.nativeToken?.symbol || 'Eth';
return [
{ value: 18, display: toTitleCase(nativeCurrencyName) },

@ -21,20 +21,20 @@ import { LabelAndCodeBlock } from './CodeBlock';
import { KeyValueRow } from './KeyValueRow';
export function OriginTransactionCard({
chainId,
chainName,
domainId,
transaction,
blur,
}: {
chainId: ChainId;
chainName: string;
domainId: DomainId;
transaction: MessageTx;
blur: boolean;
}) {
return (
<TransactionCard chainId={chainId} title="Origin Transaction" helpText={helpText.origin}>
<TransactionCard chainName={chainName} title="Origin Transaction" helpText={helpText.origin}>
<TransactionDetails
chainId={chainId}
chainName={chainName}
domainId={domainId}
transaction={transaction}
blur={blur}
@ -44,7 +44,7 @@ export function OriginTransactionCard({
}
export function DestinationTransactionCard({
chainId,
chainName,
domainId,
status,
transaction,
@ -54,7 +54,7 @@ export function DestinationTransactionCard({
isPiMsg,
blur,
}: {
chainId: ChainId;
chainName: string;
domainId: DomainId;
status: MessageStatus;
transaction?: MessageTx;
@ -65,9 +65,9 @@ export function DestinationTransactionCard({
blur: boolean;
}) {
const multiProvider = useMultiProvider();
const hasChainConfig = !!multiProvider.tryGetChainMetadata(chainId);
const hasChainConfig = !!multiProvider.tryGetChainMetadata(domainId);
const isDestinationEvmChain = isEvmChain(multiProvider, chainId);
const isDestinationEvmChain = isEvmChain(multiProvider, domainId);
const { isOpen, open, close } = useModal();
@ -75,9 +75,9 @@ export function DestinationTransactionCard({
if (transaction) {
content = (
<TransactionDetails
transaction={transaction}
chainId={chainId}
chainName={chainName}
domainId={domainId}
transaction={transaction}
duration={duration}
blur={blur}
/>
@ -156,7 +156,7 @@ export function DestinationTransactionCard({
return (
<TransactionCard
chainId={chainId}
chainName={chainName}
title="Destination Transaction"
helpText={helpText.destination}
>
@ -166,16 +166,16 @@ export function DestinationTransactionCard({
}
function TransactionCard({
chainId,
chainName,
title,
helpText,
children,
}: PropsWithChildren<{ chainId: ChainId; title: string; helpText: string }>) {
}: PropsWithChildren<{ chainName: string; title: string; helpText: string }>) {
return (
<Card className="flex min-w-fit flex-1 flex-col space-y-3">
<div className="flex items-center justify-between">
<div className="relative -left-0.5 -top-px">
<ChainLogo chainId={chainId} />
<ChainLogo chainName={chainName} />
</div>
<div className="flex items-center pb-1">
<h3 className="mr-2 text-md font-medium text-blue-500">{title}</h3>
@ -194,13 +194,13 @@ function TransactionCard({
}
function TransactionDetails({
chainId,
chainName,
domainId,
transaction,
duration,
blur,
}: {
chainId: ChainId;
chainName: string;
domainId: DomainId;
transaction: MessageTx;
duration?: string;
@ -214,13 +214,13 @@ function TransactionDetails({
const txExplorerLink =
hash && !new BigNumber(hash).isZero()
? multiProvider.tryGetExplorerTxUrl(chainId, { hash: formattedHash })
? multiProvider.tryGetExplorerTxUrl(chainName, { hash: formattedHash })
: null;
return (
<>
<ChainDescriptionRow
chainId={chainId}
chainName={chainName}
domainId={domainId}
multiProvider={multiProvider}
blur={blur}
@ -337,20 +337,23 @@ function CallDataModal({ debugResult }: { debugResult?: MessageDebugResult }) {
}
function ChainDescriptionRow({
chainId,
chainName,
domainId,
multiProvider,
blur,
}: {
chainId: ChainId;
chainName: string;
domainId: DomainId;
multiProvider: MultiProvider;
blur: boolean;
}) {
const idString = chainId && chainId !== domainId ? `${chainId} / ${domainId}` : `${domainId}`;
const idString =
chainName && chainName !== multiProvider.tryGetChainName(domainId)
? `${chainName} / ${domainId}`
: `${domainId}`;
const chainDescription = `${getChainDisplayName(
multiProvider,
domainId,
chainName,
false,
false,
)} (${idString})`;

@ -36,7 +36,7 @@ export enum PiQueryType {
MsgId = 'msgId',
}
/* Pseudo-code for the fetch algo below:
/* Pseudo-code for the fetch algo below:
========================================
searchForMessages(input):
for chain of piChains:
@ -53,7 +53,7 @@ searchForMessages(input):
if tx is found:
logs = tx.logs where topic0 is Dispatch or Process
if logs are found return logs.map( l => l.message )
else tx is not found:
else tx is not found:
// input may be a message ID
logs = dataSource.getLogs() where:
contract is mailbox
@ -112,10 +112,10 @@ async function fetchLogsForAddress(
multiProvider: MultiProvider,
registry: IRegistry,
): Promise<ExtendedLog[]> {
const { chainId } = chainMetadata;
const { name, domainId } = chainMetadata;
const address = query.input;
logger.debug(`Fetching logs for address ${address} on chain ${chainId}`);
const mailbox = await resolveMailbox(chainMetadata, multiProvider, registry);
logger.debug(`Fetching logs for address ${address} on chain ${name} (${domainId})`);
const mailbox = await resolveMailbox(chainMetadata, registry);
if (!mailbox) return [];
const dispatchTopic = addressToBytes32(address);
@ -127,23 +127,23 @@ async function fetchLogsForAddress(
// [processTopic0, null, null, dispatchTopic],
],
mailbox,
chainId,
domainId,
query,
multiProvider,
);
}
async function fetchLogsForTxHash(
{ chainId }: ChainMetadata,
{ name, domainId }: ChainMetadata,
query: PiMessageQuery,
multiProvider: MultiProvider,
): Promise<ExtendedLog[]> {
const txHash = query.input;
logger.debug(`Fetching logs for txHash ${txHash} on chain ${chainId}`);
const provider = multiProvider.getProvider(chainId);
logger.debug(`Fetching logs for txHash ${txHash} on chain ${name} (${domainId})`);
const provider = multiProvider.getProvider(domainId);
const txReceipt = await provider.getTransactionReceipt(txHash);
if (txReceipt) {
logger.debug(`Tx receipt found from provider for chain ${chainId}`);
logger.debug(`Tx receipt found from provider for chain ${name} (${domainId})`);
const block = await tryFetchBlockFromProvider(provider, txReceipt.blockNumber);
return txReceipt.logs.map((l) => ({
...l,
@ -152,7 +152,7 @@ async function fetchLogsForTxHash(
to: txReceipt.to,
}));
} else {
logger.debug(`Tx hash not found from provider for chain ${chainId}`);
logger.debug(`Tx hash not found from provider for chain ${name} (${domainId})`);
return [];
}
}
@ -163,10 +163,10 @@ async function fetchLogsForMsgId(
multiProvider: MultiProvider,
registry: IRegistry,
): Promise<ExtendedLog[]> {
const { chainId } = chainMetadata;
const { name, domainId } = chainMetadata;
const msgId = query.input;
logger.debug(`Fetching logs for msgId ${msgId} on chain ${chainId}`);
const mailbox = await resolveMailbox(chainMetadata, multiProvider, registry);
logger.debug(`Fetching logs for msgId ${msgId} on chain ${name} (${domainId})`);
const mailbox = await resolveMailbox(chainMetadata, registry);
if (!mailbox) return [];
const topic1 = msgId;
const logs: ExtendedLog[] = await fetchLogsFromProvider(
@ -175,7 +175,7 @@ async function fetchLogsForMsgId(
// [processIdTopic0, topic1],
],
mailbox,
chainId,
domainId,
query,
multiProvider,
);
@ -194,11 +194,11 @@ async function fetchLogsForMsgId(
async function fetchLogsFromProvider(
topics: Array<Array<string | null>>,
contractAddr: Address,
chainId: ChainId,
domainId: DomainId,
query: PiMessageQuery,
multiProvider: MultiProvider,
): Promise<ExtendedLog[]> {
const provider = multiProvider.getProvider(chainId);
const provider = multiProvider.getProvider(domainId);
let { fromBlock, toBlock } = query;
fromBlock ||= (await provider.getBlockNumber()) - PI_MESSAGE_LOG_CHECK_BLOCK_RANGE;
@ -316,15 +316,15 @@ async function tryFetchIgpGasPayments(
chainMetadata: ChainMetadata<{ interchainGasPaymaster?: Address }>,
multiProvider: MultiProvider,
): Promise<Message> {
const { chainId, interchainGasPaymaster } = chainMetadata;
const { name, domainId, interchainGasPaymaster } = chainMetadata;
if (!interchainGasPaymaster || !isValidAddress(interchainGasPaymaster)) {
logger.warn('No IGP address found for chain:', chainId);
logger.warn(`No IGP address found for chain ${name} (${domainId})`);
return message;
}
const igp = IInterchainGasPaymaster__factory.connect(
interchainGasPaymaster,
multiProvider.getProvider(chainId),
multiProvider.getProvider(domainId),
);
const filter = igp.filters.GasPayment(message.msgId);
const matchedEvents = (await igp.queryFilter(filter)) || [];
@ -346,11 +346,10 @@ async function tryFetchIgpGasPayments(
async function resolveMailbox(
chainMetadata: ChainMetadata<{ mailbox?: Address }>,
multiProvider: MultiProvider,
registry: IRegistry,
) {
if (chainMetadata.mailbox) return chainMetadata.mailbox;
const chainName = multiProvider.getChainName(chainMetadata.chainId);
const chainName = chainMetadata.name;
const chainAddresses = await registry.getChainAddresses(chainName);
const mailbox = chainAddresses?.mailbox;
if (!mailbox) logger.debug(`No mailbox address found for chain ${chainName}`);

@ -54,8 +54,9 @@ export function usePiChainMessageSearchQuery({
const allChains = Object.values(multiProvider.metadata);
const piChains = allChains.filter(
(c) =>
isEvmChain(multiProvider, c.chainId) &&
isPiChain(multiProvider, scrapedChains, c.chainId),
c.domainId !== undefined &&
isEvmChain(multiProvider, c.domainId) &&
isPiChain(multiProvider, scrapedChains, c.domainId),
);
try {
const results = await Promise.allSettled(

@ -61,16 +61,10 @@ function parseMessageStub(
try {
const originMetadata = multiProvider.tryGetChainMetadata(m.origin_domain_id);
const destinationMetadata = multiProvider.tryGetChainMetadata(m.destination_domain_id);
let destinationChainId = m.destination_chain_id || destinationMetadata?.chainId;
if (!destinationChainId) {
logger.debug(
`No chainId known for domain ${m.destination_domain_id}. Using domain as chainId`,
);
destinationChainId = m.destination_domain_id;
}
const isPiMsg =
isPiChain(multiProvider, scrapedChains, m.origin_chain_id) ||
isPiChain(multiProvider, scrapedChains, destinationChainId);
isPiChain(multiProvider, scrapedChains, m.origin_domain_id) ||
isPiChain(multiProvider, scrapedChains, m.destination_domain_id);
return {
status: getMessageStatus(m),
@ -81,7 +75,7 @@ function parseMessageStub(
recipient: postgresByteaToAddress(m.recipient, destinationMetadata),
originChainId: m.origin_chain_id,
originDomainId: m.origin_domain_id,
destinationChainId,
destinationChainId: m.destination_chain_id,
destinationDomainId: m.destination_domain_id,
origin: {
timestamp: parseTimestampString(m.send_occurred_at),

@ -22,12 +22,12 @@ export interface ExplorerQueryResponse<R> {
async function queryExplorer<P>(
multiProvider: MultiProvider,
chainId: ChainId,
chainName: string,
params: URLSearchParams,
useKey = false,
) {
const baseUrl = multiProvider.tryGetExplorerApiUrl(chainId);
if (!baseUrl) throw new Error(`No valid URL found for explorer for chain ${chainId}`);
const baseUrl = multiProvider.tryGetExplorerApiUrl(chainName);
if (!baseUrl) throw new Error(`No valid URL found for explorer for chain ${chainName}`);
const url = new URL(baseUrl);
for (const [key, val] of params.entries()) {
@ -35,8 +35,8 @@ async function queryExplorer<P>(
}
if (useKey) {
const apiKey = config.explorerApiKeys[chainId];
if (!apiKey) throw new Error(`No API key for explorer for chain ${chainId}`);
const apiKey = config.explorerApiKeys[chainName];
if (!apiKey) throw new Error(`No API key for explorer for chain ${chainName}`);
url.searchParams.set('apikey', apiKey);
}
@ -85,13 +85,13 @@ export interface ExplorerLogEntry {
export async function queryExplorerForLogs(
multiProvider: MultiProvider,
chainId: ChainId,
chainName: string,
params: string,
useKey = false,
): Promise<ExplorerLogEntry[]> {
const logs = await queryExplorer<ExplorerLogEntry[]>(
multiProvider,
chainId,
chainName,
new URLSearchParams(params),
useKey,
);
@ -127,7 +127,7 @@ export function toProviderLog(log: ExplorerLogEntry): ExtendedLog {
export async function queryExplorerForTx(
multiProvider: MultiProvider,
chainId: ChainId,
chainName: string,
txHash: string,
useKey = false,
) {
@ -138,7 +138,7 @@ export async function queryExplorerForTx(
});
const tx = await queryExplorer<providers.TransactionResponse>(
multiProvider,
chainId,
chainName,
params,
useKey,
);
@ -152,7 +152,7 @@ export async function queryExplorerForTx(
export async function queryExplorerForTxReceipt(
multiProvider: MultiProvider,
chainId: ChainId,
chainName: string,
txHash: string,
useKey = false,
) {
@ -163,7 +163,7 @@ export async function queryExplorerForTxReceipt(
});
const tx = await queryExplorer<providers.TransactionReceipt>(
multiProvider,
chainId,
chainName,
params,
useKey,
);
@ -177,7 +177,7 @@ export async function queryExplorerForTxReceipt(
export async function queryExplorerForBlock(
multiProvider: MultiProvider,
chainId: ChainId,
chainName: string,
blockNumber?: number | string,
useKey = false,
) {
@ -187,7 +187,7 @@ export async function queryExplorerForBlock(
tag: blockNumber?.toString() || 'latest',
boolean: 'false',
});
const block = await queryExplorer<providers.Block>(multiProvider, chainId, params, useKey);
const block = await queryExplorer<providers.Block>(multiProvider, chainName, params, useKey);
if (!block || BigNumber.from(block.number).lte(0)) {
const msg = 'Invalid block result';
logger.error(msg, JSON.stringify(block), params);

@ -2120,13 +2120,13 @@ __metadata:
languageName: node
linkType: hard
"@hyperlane-xyz/core@npm:5.7.0":
version: 5.7.0
resolution: "@hyperlane-xyz/core@npm:5.7.0"
"@hyperlane-xyz/core@npm:5.7.1":
version: 5.7.1
resolution: "@hyperlane-xyz/core@npm:5.7.1"
dependencies:
"@arbitrum/nitro-contracts": "npm:^1.2.1"
"@eth-optimism/contracts": "npm:^0.6.0"
"@hyperlane-xyz/utils": "npm:5.7.0"
"@hyperlane-xyz/utils": "npm:6.0.0"
"@layerzerolabs/lz-evm-oapp-v2": "npm:2.0.2"
"@openzeppelin/contracts": "npm:^4.9.3"
"@openzeppelin/contracts-upgradeable": "npm:^v4.9.3"
@ -2135,7 +2135,7 @@ __metadata:
"@ethersproject/abi": "*"
"@ethersproject/providers": "*"
"@types/sinon-chai": "*"
checksum: 10/7ca52943789378dc631cce932ab46ff68f2efe892e2e53f59e704e52a625962b1dd4c0f3bf4ee7eff6e08e17886a44a8d4ca72a98509cf54de272bdb7d96af4e
checksum: 10/53fa047cb0d417b8453cbe422a385e804d9c84758dba10f3e1408a76b88ac57024be3aa0f942f404702e6e680da1e41aaf540155b5ce9cfca2896d244e2ef6d1
languageName: node
linkType: hard
@ -2145,9 +2145,9 @@ __metadata:
dependencies:
"@headlessui/react": "npm:^2.1.8"
"@hyperlane-xyz/registry": "npm:5.1.0"
"@hyperlane-xyz/sdk": "npm:5.7.0"
"@hyperlane-xyz/utils": "npm:5.7.0"
"@hyperlane-xyz/widgets": "npm:5.7.0"
"@hyperlane-xyz/sdk": "npm:6.0.0"
"@hyperlane-xyz/utils": "npm:6.0.0"
"@hyperlane-xyz/widgets": "npm:6.0.0"
"@tanstack/eslint-plugin-query": "npm:^5.28.6"
"@tanstack/react-query": "npm:^5.35.5"
"@types/jest": "npm:^29.5.3"
@ -2197,25 +2197,24 @@ __metadata:
languageName: node
linkType: hard
"@hyperlane-xyz/sdk@npm:5.7.0":
version: 5.7.0
resolution: "@hyperlane-xyz/sdk@npm:5.7.0"
"@hyperlane-xyz/sdk@npm:6.0.0":
version: 6.0.0
resolution: "@hyperlane-xyz/sdk@npm:6.0.0"
dependencies:
"@arbitrum/sdk": "npm:^4.0.0"
"@aws-sdk/client-s3": "npm:^3.74.0"
"@cosmjs/cosmwasm-stargate": "npm:^0.32.4"
"@cosmjs/stargate": "npm:^0.32.4"
"@hyperlane-xyz/core": "npm:5.7.0"
"@hyperlane-xyz/utils": "npm:5.7.0"
"@hyperlane-xyz/core": "npm:5.7.1"
"@hyperlane-xyz/utils": "npm:6.0.0"
"@safe-global/api-kit": "npm:1.3.0"
"@safe-global/protocol-kit": "npm:1.3.0"
"@safe-global/safe-deployments": "npm:1.37.8"
"@solana/spl-token": "npm:^0.3.8"
"@solana/web3.js": "npm:^1.78.0"
"@types/coingecko-api": "npm:^1.0.10"
"@wagmi/chains": "npm:^1.8.0"
bignumber.js: "npm:^9.1.1"
coingecko-api: "npm:^1.0.10"
coingecko-api-v3: "npm:^0.0.29"
cosmjs-types: "npm:^0.9.0"
cross-fetch: "npm:^3.1.5"
ethers: "npm:^5.7.2"
@ -2225,13 +2224,13 @@ __metadata:
peerDependencies:
"@ethersproject/abi": "*"
"@ethersproject/providers": "*"
checksum: 10/c604cf4e1fbbc41d16d9236418bd15eee4034c6145362d8746ae5ac51a67f4932b6f5cde08166de9e20c427c689fc91aacc6edbd9d52778dc8170c42a3af3db7
checksum: 10/5d8ca83c7c52cd6ada1a3b4684ff5770ec9568e281c9b8d306b46ab61d188d88a1d22ec04e4024ef32fb92df158951201b3e900bb29955d416417415f53c035c
languageName: node
linkType: hard
"@hyperlane-xyz/utils@npm:5.7.0":
version: 5.7.0
resolution: "@hyperlane-xyz/utils@npm:5.7.0"
"@hyperlane-xyz/utils@npm:6.0.0":
version: 6.0.0
resolution: "@hyperlane-xyz/utils@npm:6.0.0"
dependencies:
"@cosmjs/encoding": "npm:^0.32.4"
"@solana/web3.js": "npm:^1.78.0"
@ -2240,23 +2239,23 @@ __metadata:
lodash-es: "npm:^4.17.21"
pino: "npm:^8.19.0"
yaml: "npm:2.4.5"
checksum: 10/62d7c0c3513df50208c1819dad78911524e894cfd4681b65cba3e15d1e3837dcb28ff4b49ee6b9a5c522b4b27943eb2554d227b26c3399468dfaca6c2e80b5cb
checksum: 10/bc75da2dfdec1ee26d7fb29db211d457b3ec07226059c9d2ea91602297547fecb0e369d0301fa0545bb2b89c77ca63d11434e8fb6b498fa1906082c4fcd8b3ba
languageName: node
linkType: hard
"@hyperlane-xyz/widgets@npm:5.7.0":
version: 5.7.0
resolution: "@hyperlane-xyz/widgets@npm:5.7.0"
"@hyperlane-xyz/widgets@npm:6.0.0":
version: 6.0.0
resolution: "@hyperlane-xyz/widgets@npm:6.0.0"
dependencies:
"@headlessui/react": "npm:^2.1.8"
"@hyperlane-xyz/sdk": "npm:5.7.0"
"@hyperlane-xyz/utils": "npm:5.7.0"
"@hyperlane-xyz/sdk": "npm:6.0.0"
"@hyperlane-xyz/utils": "npm:6.0.0"
clsx: "npm:^2.1.1"
react-tooltip: "npm:^5.28.0"
peerDependencies:
react: ^18
react-dom: ^18
checksum: 10/d3dd5e657d67c061f842f9fc4beb319b97f694ffa0bc30bcd796826cfa911962f655722d249c35fce4c91833b3e4efaa5a37893cb2f6cd365fef29978dee920a
checksum: 10/52f2170820f3ffbaa3c64fa44b84a1bfbef53101ed8877a04561711e2b1eb8bfd9685fb59a31fce51d7dba12181681e33e85d360205e0f1725b1e1ff86b72316
languageName: node
linkType: hard
@ -4110,13 +4109,6 @@ __metadata:
languageName: node
linkType: hard
"@types/coingecko-api@npm:^1.0.10":
version: 1.0.10
resolution: "@types/coingecko-api@npm:1.0.10"
checksum: 10/2523f946e6d293c2ee94a0abee624f53c34b4643f8df685d0164509aba66e8234276e5d8c202c514551024757f0987f7062daa7428ccaf6673bad9a5c55779a2
languageName: node
linkType: hard
"@types/connect@npm:^3.4.33":
version: 3.4.35
resolution: "@types/connect@npm:3.4.35"
@ -5738,10 +5730,12 @@ __metadata:
languageName: node
linkType: hard
"coingecko-api@npm:^1.0.10":
version: 1.0.10
resolution: "coingecko-api@npm:1.0.10"
checksum: 10/e0000df5aebbeee508f25824485fe8e4be57cd07825b3cfbf2dc3c51b646200eefd336c833e81747d4a209bf10c32019baef1070fb2bfbcdbae099420954d1fa
"coingecko-api-v3@npm:^0.0.29":
version: 0.0.29
resolution: "coingecko-api-v3@npm:0.0.29"
dependencies:
https: "npm:^1.0.0"
checksum: 10/e60a0996472419232a144ec77028c060bd9c289f799dd40d46dbb7229cff3d868a3e35bf88724059dc25767b8136d794789e4dd31711592fa73a7be1ca2fcbc7
languageName: node
linkType: hard
@ -8139,6 +8133,13 @@ __metadata:
languageName: node
linkType: hard
"https@npm:^1.0.0":
version: 1.0.0
resolution: "https@npm:1.0.0"
checksum: 10/ccea8a8363a018d4b241db7748cff3a85c9f5b71bf80639e9c37dc6823f590f35dda098b80b726930e9f945387c8bfd6b1461df25cab5bf65a31903d81875b5d
languageName: node
linkType: hard
"human-signals@npm:^2.1.0":
version: 2.1.0
resolution: "human-signals@npm:2.1.0"

Loading…
Cancel
Save