From 8550b3753ae2592f124769952bbdf005d2d99aac Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 29 Jan 2025 18:20:00 -0400 Subject: [PATCH 01/14] WIP: decoding message --- src/features/messages/MessageDetails.tsx | 29 +++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/features/messages/MessageDetails.tsx b/src/features/messages/MessageDetails.tsx index 90823c7..76efbd9 100644 --- a/src/features/messages/MessageDetails.tsx +++ b/src/features/messages/MessageDetails.tsx @@ -2,7 +2,14 @@ import Image from 'next/image'; import { useEffect } from 'react'; import { toast } from 'react-toastify'; -import { toTitleCase, trimToLength } from '@hyperlane-xyz/utils'; +import { + bytesToProtocolAddress, + fromHexString, + parseWarpRouteMessage, + ProtocolType, + toTitleCase, + trimToLength, +} from '@hyperlane-xyz/utils'; import { Card } from '../../components/layout/Card'; import CheckmarkIcon from '../../images/icons/checkmark-circle.svg'; @@ -91,6 +98,26 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro const originChainName = multiProvider.tryGetChainName(originDomainId) || 'Unknown'; const destinationChainName = multiProvider.tryGetChainName(destinationDomainId) || 'Unknown'; + // test + // const originP = multiProvider.getProtocol(originChainName); + // const destinationP = multiProvider.getProtocol(destinationChainName); + + // console.log('originP', originP); + // console.log('destinationP', destinationP); + + const p = parseWarpRouteMessage(message.body); + console.log('message', message); + + console.log('decodedBody', message.decodedBody); + + console.log('p', p); + + const address = fromHexString( + '0x66911d2f076377987f1156c8c036306926433a99f6b63a457c229b005b913f8a', + ); + const bye = bytesToProtocolAddress(address, ProtocolType.Sealevel); + console.log('normalized address', bye); + return ( <> From 6d80576ff7fa59071548e82ea58af194a84fa785 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 29 Jan 2025 18:20:07 -0400 Subject: [PATCH 02/14] WIP: decoding message --- src/features/messages/MessageDetails.tsx | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/features/messages/MessageDetails.tsx b/src/features/messages/MessageDetails.tsx index 76efbd9..825a7c3 100644 --- a/src/features/messages/MessageDetails.tsx +++ b/src/features/messages/MessageDetails.tsx @@ -105,18 +105,12 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro // console.log('originP', originP); // console.log('destinationP', destinationP); - const p = parseWarpRouteMessage(message.body); + const parsed = parseWarpRouteMessage(message.body); console.log('message', message); - console.log('decodedBody', message.decodedBody); - - console.log('p', p); - - const address = fromHexString( - '0x66911d2f076377987f1156c8c036306926433a99f6b63a457c229b005b913f8a', - ); - const bye = bytesToProtocolAddress(address, ProtocolType.Sealevel); - console.log('normalized address', bye); + console.log('p', parsed); + const address = fromHexString(''); + const bytes = bytesToProtocolAddress(address, ProtocolType.Sealevel); return ( <> From 96a19d6383cf91075aee23a2801128cde2e92fde Mon Sep 17 00:00:00 2001 From: Xaroz Date: Tue, 4 Feb 2025 18:30:30 -0400 Subject: [PATCH 03/14] feat: decode warp route --- src/features/messages/MessageDetails.tsx | 25 +---- .../messages/cards/WarpTransferDetailCard.tsx | 95 +++++++++++++++++++ src/features/messages/queries/parse.ts | 80 +++++++++++++++- src/images/icons/send-money.svg | 1 + src/images/icons/token.svg | 1 + src/store.ts | 27 ++++++ src/types.ts | 15 +++ 7 files changed, 219 insertions(+), 25 deletions(-) create mode 100644 src/features/messages/cards/WarpTransferDetailCard.tsx create mode 100644 src/images/icons/send-money.svg create mode 100644 src/images/icons/token.svg diff --git a/src/features/messages/MessageDetails.tsx b/src/features/messages/MessageDetails.tsx index 825a7c3..3f29459 100644 --- a/src/features/messages/MessageDetails.tsx +++ b/src/features/messages/MessageDetails.tsx @@ -2,14 +2,7 @@ import Image from 'next/image'; import { useEffect } from 'react'; import { toast } from 'react-toastify'; -import { - bytesToProtocolAddress, - fromHexString, - parseWarpRouteMessage, - ProtocolType, - toTitleCase, - trimToLength, -} from '@hyperlane-xyz/utils'; +import { toTitleCase, trimToLength } from '@hyperlane-xyz/utils'; import { Card } from '../../components/layout/Card'; import CheckmarkIcon from '../../images/icons/checkmark-circle.svg'; @@ -27,6 +20,7 @@ import { IcaDetailsCard } from './cards/IcaDetailsCard'; import { IsmDetailsCard } from './cards/IsmDetailsCard'; import { TimelineCard } from './cards/TimelineCard'; import { DestinationTransactionCard, OriginTransactionCard } from './cards/TransactionCard'; +import { WarpTransferDetailCard } from './cards/WarpTransferDetailCard'; import { useIsIcaMessage } from './ica'; import { usePiChainMessageQuery } from './pi-queries/usePiChainMessageQuery'; import { PLACEHOLDER_MESSAGE } from './placeholderMessages'; @@ -98,20 +92,6 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro const originChainName = multiProvider.tryGetChainName(originDomainId) || 'Unknown'; const destinationChainName = multiProvider.tryGetChainName(destinationDomainId) || 'Unknown'; - // test - // const originP = multiProvider.getProtocol(originChainName); - // const destinationP = multiProvider.getProtocol(destinationChainName); - - // console.log('originP', originP); - // console.log('destinationP', destinationP); - - const parsed = parseWarpRouteMessage(message.body); - console.log('message', message); - - console.log('p', parsed); - const address = fromHexString(''); - const bytes = bytesToProtocolAddress(address, ProtocolType.Sealevel); - return ( <> @@ -148,6 +128,7 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro /> {showTimeline && } + ({ + warpRouteMap: s.warpRouteMap, + })); + const warpRouteDetails = parseWarpRouteDetails(message, warpRouteMap); + + if (!warpRouteDetails) return null; + + return ( + +
+ +
+

Warp Transfer Details

+ +
+
+
+ + + + + + + +
+
+ ); +} diff --git a/src/features/messages/queries/parse.ts b/src/features/messages/queries/parse.ts index 4cc9e40..5748b85 100644 --- a/src/features/messages/queries/parse.ts +++ b/src/features/messages/queries/parse.ts @@ -1,17 +1,24 @@ -import { MultiProvider } from '@hyperlane-xyz/sdk'; +import { ChainMetadata, MultiProvider } from '@hyperlane-xyz/sdk'; -import { Message, MessageStatus, MessageStub } from '../../../types'; +import { + Message, + MessageStatus, + MessageStub, + WarpRouteDetails, + WarpRouteMap, +} from '../../../types'; import { logger } from '../../../utils/logger'; import { tryUtf8DecodeBytes } from '../../../utils/string'; import { DomainsEntry } from '../../chains/queries/fragments'; import { isPiChain } from '../../chains/utils'; +import { fromWei, objKeys, parseWarpRouteMessage } from '@hyperlane-xyz/utils'; import { postgresByteaToAddress, postgresByteaToString, postgresByteaToTxHash } from './encoding'; import { MessageEntry, - MessageStubEntry, MessagesQueryResult, MessagesStubQueryResult, + MessageStubEntry, } from './fragments'; /** @@ -37,6 +44,69 @@ export function parseMessageQueryResult( return queryResult(multiProvider, scrapedChains, data, parseMessage); } +function getTokenSymbolFromWarpRouteMap( + chainMetadata: ChainMetadata, + address: Address, + warpRouteMap: WarpRouteMap, +) { + const { name } = chainMetadata; + + if (objKeys(warpRouteMap).includes(name)) { + const chain = warpRouteMap[name]; + if (objKeys(chain).includes(address)) { + return chain[address]; + } + } + + return undefined; +} + +export function parseWarpRouteDetails( + message: Message, + warpRouteMap: WarpRouteMap, +): WarpRouteDetails | undefined { + try { + const { + body, + origin: { to }, + totalPayment, + originMetadata, + destinationMetadata, + sender, + recipient, + } = message; + + if (!body || !originMetadata || !destinationMetadata) return undefined; + + const originTokenSymbol = getTokenSymbolFromWarpRouteMap(originMetadata, sender, warpRouteMap); + const destinationTokenSymbol = getTokenSymbolFromWarpRouteMap( + destinationMetadata, + recipient, + warpRouteMap, + ); + + if (!originTokenSymbol || !destinationTokenSymbol) return undefined; + + const parsedMessage = parseWarpRouteMessage(body); + const address = postgresByteaToAddress(parsedMessage.recipient, destinationMetadata); + + return { + amount: fromWei(parsedMessage.amount.toString(), originMetadata.nativeToken?.decimals || 18), + totalPayment: totalPayment + ? fromWei(totalPayment, originMetadata.nativeToken?.decimals || 18) + : 'Unknown', + endRecipient: address, + originTokenAddress: to, + originTokenSymbol: originTokenSymbol, + destinationTokenAddress: recipient, + destinationTokenSymbol: destinationTokenSymbol, + }; + } catch (err) { + logger.error('Error parsing warp route details:', err); + return undefined; + } +} + function queryResult( multiProvider: MultiProvider, scrapedChains: DomainsEntry[], @@ -90,6 +160,8 @@ function parseMessageStub( } : undefined, isPiMsg, + originMetadata, + destinationMetadata, }; } catch (error) { logger.error('Error parsing message stub', error); @@ -151,6 +223,8 @@ function parseMessage( totalGasAmount: m.total_gas_amount.toString(), totalPayment: m.total_payment.toString(), numPayments: m.num_payments, + originMetadata, + destinationMetadata, }; } catch (error) { logger.error('Error parsing message', error); diff --git a/src/images/icons/send-money.svg b/src/images/icons/send-money.svg new file mode 100644 index 0000000..5ea890c --- /dev/null +++ b/src/images/icons/send-money.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/images/icons/token.svg b/src/images/icons/token.svg new file mode 100644 index 0000000..d56c5bc --- /dev/null +++ b/src/images/icons/token.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/store.ts b/src/store.ts index d693566..bc891a6 100644 --- a/src/store.ts +++ b/src/store.ts @@ -7,6 +7,7 @@ import { objFilter, objMap, promiseObjAll } from '@hyperlane-xyz/utils'; import { config } from './consts/config'; import { DomainsEntry } from './features/chains/queries/fragments'; +import { WarpRouteMap } from './types'; import { logger } from './utils/logger'; // Increment this when persist state has breaking changes @@ -27,6 +28,8 @@ interface AppState { setRegistry: (registry: IRegistry) => void; bannerClassName: string; setBanner: (className: string) => void; + warpRouteMap: WarpRouteMap; + setWarpRouteMap: (warpRouteMap: WarpRouteMap) => void; } export const useStore = create()( @@ -56,6 +59,10 @@ export const useStore = create()( }, bannerClassName: '', setBanner: (className: string) => set({ bannerClassName: className }), + warpRouteMap: {}, + setWarpRouteMap: (warpRouteMap: WarpRouteMap) => { + set({ warpRouteMap }); + }, }), { name: 'hyperlane', // name in storage @@ -75,6 +82,9 @@ export const useStore = create()( logger.debug('Rehydration complete'); }) .catch((e) => logger.error('Error building MultiProvider', e)); + buildWarpRouteMap(state.registry).then((warpRouteMap) => { + state.setWarpRouteMap(warpRouteMap); + }); }; }, }, @@ -118,3 +128,20 @@ async function buildMultiProvider( const mergedMetadata = mergeChainMetadataMap(metadataWithLogos, overrideChainMetadata); return { metadata: metadataWithLogos, multiProvider: new MultiProvider(mergedMetadata) }; } + +export async function buildWarpRouteMap(registry: IRegistry): Promise { + try { + const warpRoutes = await registry.getWarpRoutes(); + return Object.values(warpRoutes).reduce((acc, { tokens }) => { + tokens.forEach(({ chainName, addressOrDenom, symbol }) => { + if (!acc[chainName]) { + acc[chainName] = {}; + } + acc[chainName][addressOrDenom] = symbol; + }); + return acc; + }, {}); + } catch { + return {}; + } +} diff --git a/src/types.ts b/src/types.ts index 78c4605..986055b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,4 @@ +import { ChainMetadata, ChainName } from '@hyperlane-xyz/sdk'; import type { providers } from 'ethers'; // TODO consider reconciling with SDK's MessageStatus @@ -43,6 +44,8 @@ export interface MessageStub { origin: MessageTxStub; destination?: MessageTxStub; isPiMsg?: boolean; + originMetadata: ChainMetadata | null; + destinationMetadata: ChainMetadata | null; } export interface Message extends MessageStub { @@ -60,3 +63,15 @@ export interface ExtendedLog extends providers.Log { from?: Address; to?: Address; } + +export interface WarpRouteDetails { + amount: string; + totalPayment: string; + endRecipient: string; + originTokenAddress: string; + originTokenSymbol: string; + destinationTokenAddress: string; + destinationTokenSymbol: string; +} + +export type WarpRouteMap = Record>; From b6bd898014e24cb86bd33da434ebcaf8f1867646 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Tue, 4 Feb 2025 18:30:59 -0400 Subject: [PATCH 04/14] chore: clean up --- src/images/icons/token.svg | 1 - 1 file changed, 1 deletion(-) delete mode 100644 src/images/icons/token.svg diff --git a/src/images/icons/token.svg b/src/images/icons/token.svg deleted file mode 100644 index d56c5bc..0000000 --- a/src/images/icons/token.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file From c6e3bf5cade7ee067fbb35f95171e48e80e4dff1 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Tue, 4 Feb 2025 18:50:17 -0400 Subject: [PATCH 05/14] chore: comments and style fixing --- src/features/messages/cards/WarpTransferDetailCard.tsx | 6 +++--- src/features/messages/queries/parse.ts | 8 +++----- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/features/messages/cards/WarpTransferDetailCard.tsx b/src/features/messages/cards/WarpTransferDetailCard.tsx index 5e36881..1d5725a 100644 --- a/src/features/messages/cards/WarpTransferDetailCard.tsx +++ b/src/features/messages/cards/WarpTransferDetailCard.tsx @@ -48,7 +48,7 @@ export function WarpTransferDetailCard({ message, blur }: Props) { label="Symbol:" labelWidth="w-20" display={warpRouteDetails.originTokenSymbol} - displayWidth="w-64 sm:w-40" + displayWidth="w-64 sm:w-48" blurValue={blur} /> Date: Tue, 4 Feb 2025 19:07:01 -0400 Subject: [PATCH 06/14] chore: update types --- src/types.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types.ts b/src/types.ts index 986055b..8478260 100644 --- a/src/types.ts +++ b/src/types.ts @@ -44,8 +44,8 @@ export interface MessageStub { origin: MessageTxStub; destination?: MessageTxStub; isPiMsg?: boolean; - originMetadata: ChainMetadata | null; - destinationMetadata: ChainMetadata | null; + originMetadata?: ChainMetadata | null; + destinationMetadata?: ChainMetadata | null; } export interface Message extends MessageStub { From ead5c70ac75238db92f231b6d722735b7ffafb92 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Tue, 4 Feb 2025 19:20:47 -0400 Subject: [PATCH 07/14] chore: better naming --- .../messages/cards/WarpTransferDetailCard.tsx | 6 ++--- src/features/messages/queries/parse.ts | 23 +++++++++++-------- src/store.ts | 20 ++++++++-------- src/types.ts | 4 ++-- 4 files changed, 29 insertions(+), 24 deletions(-) diff --git a/src/features/messages/cards/WarpTransferDetailCard.tsx b/src/features/messages/cards/WarpTransferDetailCard.tsx index 1d5725a..39e7924 100644 --- a/src/features/messages/cards/WarpTransferDetailCard.tsx +++ b/src/features/messages/cards/WarpTransferDetailCard.tsx @@ -16,10 +16,10 @@ interface Props { } export function WarpTransferDetailCard({ message, blur }: Props) { - const { warpRouteMap } = useStore((s) => ({ - warpRouteMap: s.warpRouteMap, + const { warpRouteChainAddressMap } = useStore((s) => ({ + warpRouteChainAddressMap: s.warpRouteChainAddressMap, })); - const warpRouteDetails = parseWarpRouteDetails(message, warpRouteMap); + const warpRouteDetails = parseWarpRouteDetails(message, warpRouteChainAddressMap); if (!warpRouteDetails) return null; diff --git a/src/features/messages/queries/parse.ts b/src/features/messages/queries/parse.ts index c372b80..af981a9 100644 --- a/src/features/messages/queries/parse.ts +++ b/src/features/messages/queries/parse.ts @@ -4,8 +4,8 @@ import { Message, MessageStatus, MessageStub, + WarpRouteChainAddressMap, WarpRouteDetails, - WarpRouteMap, } from '../../../types'; import { logger } from '../../../utils/logger'; import { tryUtf8DecodeBytes } from '../../../utils/string'; @@ -44,15 +44,14 @@ export function parseMessageQueryResult( return queryResult(multiProvider, scrapedChains, data, parseMessage); } -function getTokenSymbolFromWarpRouteMap( +function getTokenSymbolFromWarpRouteChainAddressMap( chainMetadata: ChainMetadata, address: Address, - warpRouteMap: WarpRouteMap, + warpRouteChainAddressMap: WarpRouteChainAddressMap, ) { const { name } = chainMetadata; - - if (objKeys(warpRouteMap).includes(name)) { - const chain = warpRouteMap[name]; + if (objKeys(warpRouteChainAddressMap).includes(name)) { + const chain = warpRouteChainAddressMap[name]; if (objKeys(chain).includes(address)) { return chain[address]; } @@ -63,7 +62,7 @@ function getTokenSymbolFromWarpRouteMap( export function parseWarpRouteDetails( message: Message, - warpRouteMap: WarpRouteMap, + warpRouteChainAddressMap: WarpRouteChainAddressMap, ): WarpRouteDetails | undefined { try { const { @@ -77,11 +76,15 @@ export function parseWarpRouteDetails( if (!body || !originMetadata || !destinationMetadata) return undefined; - const originTokenSymbol = getTokenSymbolFromWarpRouteMap(originMetadata, to, warpRouteMap); - const destinationTokenSymbol = getTokenSymbolFromWarpRouteMap( + const originTokenSymbol = getTokenSymbolFromWarpRouteChainAddressMap( + originMetadata, + to, + warpRouteChainAddressMap, + ); + const destinationTokenSymbol = getTokenSymbolFromWarpRouteChainAddressMap( destinationMetadata, recipient, - warpRouteMap, + warpRouteChainAddressMap, ); // If token symbols are not found with the addresses, it means the message is not a warp route transfer diff --git a/src/store.ts b/src/store.ts index bc891a6..4617339 100644 --- a/src/store.ts +++ b/src/store.ts @@ -7,7 +7,7 @@ import { objFilter, objMap, promiseObjAll } from '@hyperlane-xyz/utils'; import { config } from './consts/config'; import { DomainsEntry } from './features/chains/queries/fragments'; -import { WarpRouteMap } from './types'; +import { WarpRouteChainAddressMap } from './types'; import { logger } from './utils/logger'; // Increment this when persist state has breaking changes @@ -28,8 +28,8 @@ interface AppState { setRegistry: (registry: IRegistry) => void; bannerClassName: string; setBanner: (className: string) => void; - warpRouteMap: WarpRouteMap; - setWarpRouteMap: (warpRouteMap: WarpRouteMap) => void; + warpRouteChainAddressMap: WarpRouteChainAddressMap; + setWarpRoutChainAddresseMap: (warpRouteChainAddressMap: WarpRouteChainAddressMap) => void; } export const useStore = create()( @@ -59,9 +59,9 @@ export const useStore = create()( }, bannerClassName: '', setBanner: (className: string) => set({ bannerClassName: className }), - warpRouteMap: {}, - setWarpRouteMap: (warpRouteMap: WarpRouteMap) => { - set({ warpRouteMap }); + warpRouteChainAddressMap: {}, + setWarpRoutChainAddresseMap: (warpRouteChainAddressMap: WarpRouteChainAddressMapMap) => { + set({ warpRouteChainAddressMap }); }, }), { @@ -82,8 +82,8 @@ export const useStore = create()( logger.debug('Rehydration complete'); }) .catch((e) => logger.error('Error building MultiProvider', e)); - buildWarpRouteMap(state.registry).then((warpRouteMap) => { - state.setWarpRouteMap(warpRouteMap); + buildWarpRouteChainAddressMap(state.registry).then((warpRouteChainAddressMap) => { + state.setWarpRoutChainAddresseMap(warpRouteChainAddressMap); }); }; }, @@ -129,7 +129,9 @@ async function buildMultiProvider( return { metadata: metadataWithLogos, multiProvider: new MultiProvider(mergedMetadata) }; } -export async function buildWarpRouteMap(registry: IRegistry): Promise { +export async function buildWarpRouteChainAddressMap( + registry: IRegistry, +): Promise { try { const warpRoutes = await registry.getWarpRoutes(); return Object.values(warpRoutes).reduce((acc, { tokens }) => { diff --git a/src/types.ts b/src/types.ts index 8478260..f4881ad 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { ChainMetadata, ChainName } from '@hyperlane-xyz/sdk'; +import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk'; import type { providers } from 'ethers'; // TODO consider reconciling with SDK's MessageStatus @@ -74,4 +74,4 @@ export interface WarpRouteDetails { destinationTokenSymbol: string; } -export type WarpRouteMap = Record>; +export type WarpRouteChainAddressMap = ChainMap>; From 9134d523144e3b8f04f23489115012b365d922f1 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Tue, 4 Feb 2025 19:21:15 -0400 Subject: [PATCH 08/14] chore: build fix --- src/store.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/store.ts b/src/store.ts index 4617339..14dc547 100644 --- a/src/store.ts +++ b/src/store.ts @@ -60,7 +60,7 @@ export const useStore = create()( bannerClassName: '', setBanner: (className: string) => set({ bannerClassName: className }), warpRouteChainAddressMap: {}, - setWarpRoutChainAddresseMap: (warpRouteChainAddressMap: WarpRouteChainAddressMapMap) => { + setWarpRoutChainAddresseMap: (warpRouteChainAddressMap: WarpRouteChainAddressMap) => { set({ warpRouteChainAddressMap }); }, }), From 2b551a6beba8ccf37baf8974f7723c7f02a73db5 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 5 Feb 2025 11:58:32 -0400 Subject: [PATCH 09/14] chore: remove cards import spacing for sort order --- src/features/messages/cards/ContentDetailsCard.tsx | 7 ++----- src/features/messages/cards/GasDetailsCard.tsx | 6 ++---- src/features/messages/cards/IcaDetailsCard.tsx | 4 +--- src/features/messages/cards/IsmDetailsCard.tsx | 4 +--- src/features/messages/cards/TimelineCard.tsx | 1 - src/features/messages/cards/TransactionCard.tsx | 7 ++----- src/features/messages/cards/WarpTransferDetailCard.tsx | 7 ++----- 7 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/features/messages/cards/ContentDetailsCard.tsx b/src/features/messages/cards/ContentDetailsCard.tsx index eeae51f..f651ed8 100644 --- a/src/features/messages/cards/ContentDetailsCard.tsx +++ b/src/features/messages/cards/ContentDetailsCard.tsx @@ -1,16 +1,13 @@ -import Image from 'next/image'; -import { useEffect, useMemo, useState } from 'react'; - import { MAILBOX_VERSION } from '@hyperlane-xyz/sdk'; import { formatMessage } from '@hyperlane-xyz/utils'; import { SelectField, Tooltip } from '@hyperlane-xyz/widgets'; - +import Image from 'next/image'; +import { useEffect, useMemo, useState } from 'react'; import { Card } from '../../../components/layout/Card'; import EnvelopeInfo from '../../../images/icons/envelope-info.svg'; import { Message } from '../../../types'; import { logger } from '../../../utils/logger'; import { tryUtf8DecodeBytes } from '../../../utils/string'; - import { CodeBlock, LabelAndCodeBlock } from './CodeBlock'; import { KeyValueRow } from './KeyValueRow'; diff --git a/src/features/messages/cards/GasDetailsCard.tsx b/src/features/messages/cards/GasDetailsCard.tsx index 54b5691..c59c2c6 100644 --- a/src/features/messages/cards/GasDetailsCard.tsx +++ b/src/features/messages/cards/GasDetailsCard.tsx @@ -1,11 +1,9 @@ +import { BigNumberMax, fromWei, toTitleCase } from '@hyperlane-xyz/utils'; +import { Tooltip } from '@hyperlane-xyz/widgets'; import BigNumber from 'bignumber.js'; import { utils } from 'ethers'; import Image from 'next/image'; import { useMemo, useState } from 'react'; - -import { BigNumberMax, fromWei, toTitleCase } from '@hyperlane-xyz/utils'; -import { Tooltip } from '@hyperlane-xyz/widgets'; - import { RadioButtons } from '../../../components/buttons/RadioButtons'; import { Card } from '../../../components/layout/Card'; import { docLinks } from '../../../consts/links'; diff --git a/src/features/messages/cards/IcaDetailsCard.tsx b/src/features/messages/cards/IcaDetailsCard.tsx index cb6b8c2..5839b97 100644 --- a/src/features/messages/cards/IcaDetailsCard.tsx +++ b/src/features/messages/cards/IcaDetailsCard.tsx @@ -1,8 +1,6 @@ +import { Tooltip } from '@hyperlane-xyz/widgets'; import Image from 'next/image'; import { useMemo } from 'react'; - -import { Tooltip } from '@hyperlane-xyz/widgets'; - import { Card } from '../../../components/layout/Card'; import AccountStar from '../../../images/icons/account-star.svg'; import { Message } from '../../../types'; diff --git a/src/features/messages/cards/IsmDetailsCard.tsx b/src/features/messages/cards/IsmDetailsCard.tsx index 29c1461..cc18edb 100644 --- a/src/features/messages/cards/IsmDetailsCard.tsx +++ b/src/features/messages/cards/IsmDetailsCard.tsx @@ -1,8 +1,6 @@ -import Image from 'next/image'; - import { isNullish } from '@hyperlane-xyz/utils'; import { Tooltip } from '@hyperlane-xyz/widgets'; - +import Image from 'next/image'; import { Card } from '../../../components/layout/Card'; import { docLinks } from '../../../consts/links'; import ShieldLock from '../../../images/icons/shield-lock.svg'; diff --git a/src/features/messages/cards/TimelineCard.tsx b/src/features/messages/cards/TimelineCard.tsx index feafc4e..ac42466 100644 --- a/src/features/messages/cards/TimelineCard.tsx +++ b/src/features/messages/cards/TimelineCard.tsx @@ -1,5 +1,4 @@ import { MessageTimeline, useMessageStage } from '@hyperlane-xyz/widgets'; - import { Card } from '../../../components/layout/Card'; import { Message } from '../../../types'; diff --git a/src/features/messages/cards/TransactionCard.tsx b/src/features/messages/cards/TransactionCard.tsx index 628f62f..7f3d075 100644 --- a/src/features/messages/cards/TransactionCard.tsx +++ b/src/features/messages/cards/TransactionCard.tsx @@ -1,10 +1,8 @@ -import BigNumber from 'bignumber.js'; -import { PropsWithChildren, ReactNode, useState } from 'react'; - import { MultiProvider } from '@hyperlane-xyz/sdk'; import { ProtocolType, isAddress, isZeroish, strip0x } from '@hyperlane-xyz/utils'; import { Modal, SpinnerIcon, Tooltip, useModal } from '@hyperlane-xyz/widgets'; - +import BigNumber from 'bignumber.js'; +import { PropsWithChildren, ReactNode, useState } from 'react'; import { ChainLogo } from '../../../components/icons/ChainLogo'; import { Card } from '../../../components/layout/Card'; import { links } from '../../../consts/links'; @@ -15,7 +13,6 @@ import { ChainSearchModal } from '../../chains/ChainSearchModal'; import { getChainDisplayName, isEvmChain } from '../../chains/utils'; import { debugStatusToDesc } from '../../debugger/strings'; import { MessageDebugResult } from '../../debugger/types'; - import { LabelAndCodeBlock } from './CodeBlock'; import { KeyValueRow } from './KeyValueRow'; diff --git a/src/features/messages/cards/WarpTransferDetailCard.tsx b/src/features/messages/cards/WarpTransferDetailCard.tsx index 39e7924..d9078ee 100644 --- a/src/features/messages/cards/WarpTransferDetailCard.tsx +++ b/src/features/messages/cards/WarpTransferDetailCard.tsx @@ -1,12 +1,9 @@ -import Image from 'next/image'; - import { Tooltip } from '@hyperlane-xyz/widgets'; - +import Image from 'next/image'; import { Card } from '../../../components/layout/Card'; import SendMoney from '../../../images/icons/send-money.svg'; -import { Message } from '../../../types'; - import { useStore } from '../../../store'; +import { Message } from '../../../types'; import { parseWarpRouteDetails } from '../queries/parse'; import { KeyValueRow } from './KeyValueRow'; From 54adc5552098692ba1b86eff93b502750751a6df Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 5 Feb 2025 12:37:37 -0400 Subject: [PATCH 10/14] chore: refactor and move functions --- .../messages/cards/WarpTransferDetailCard.tsx | 124 ++++++++++++------ src/features/messages/queries/parse.ts | 81 +----------- src/types.ts | 5 +- src/utils/token.ts | 19 +++ 4 files changed, 108 insertions(+), 121 deletions(-) create mode 100644 src/utils/token.ts diff --git a/src/features/messages/cards/WarpTransferDetailCard.tsx b/src/features/messages/cards/WarpTransferDetailCard.tsx index d9078ee..ab492e7 100644 --- a/src/features/messages/cards/WarpTransferDetailCard.tsx +++ b/src/features/messages/cards/WarpTransferDetailCard.tsx @@ -1,10 +1,18 @@ +import { MultiProvider } from '@hyperlane-xyz/sdk'; +import { + bytesToProtocolAddress, + fromHexString, + fromWei, + parseWarpRouteMessage, +} from '@hyperlane-xyz/utils'; import { Tooltip } from '@hyperlane-xyz/widgets'; import Image from 'next/image'; import { Card } from '../../../components/layout/Card'; import SendMoney from '../../../images/icons/send-money.svg'; import { useStore } from '../../../store'; -import { Message } from '../../../types'; -import { parseWarpRouteDetails } from '../queries/parse'; +import { Message, WarpRouteChainAddressMap, WarpRouteDetails } from '../../../types'; +import { logger } from '../../../utils/logger'; +import { getTokenSymbolFromWarpRouteChainAddressMap } from '../../../utils/token'; import { KeyValueRow } from './KeyValueRow'; interface Props { @@ -13,13 +21,17 @@ interface Props { } export function WarpTransferDetailCard({ message, blur }: Props) { - const { warpRouteChainAddressMap } = useStore((s) => ({ + const { warpRouteChainAddressMap, multiProvider } = useStore((s) => ({ warpRouteChainAddressMap: s.warpRouteChainAddressMap, + multiProvider: s.multiProvider, })); - const warpRouteDetails = parseWarpRouteDetails(message, warpRouteChainAddressMap); + const warpRouteDetails = parseWarpRouteDetails(message, warpRouteChainAddressMap, multiProvider); if (!warpRouteDetails) return null; + const { amount, destinationTokenAddress, endRecipient, originTokenAddress, originTokenSymbol } = + warpRouteDetails; + return (
@@ -34,55 +46,35 @@ export function WarpTransferDetailCard({ message, blur }: Props) {
- - - + @@ -90,3 +82,59 @@ export function WarpTransferDetailCard({ message, blur }: Props) { ); } + +export function parseWarpRouteDetails( + message: Message, + warpRouteChainAddressMap: WarpRouteChainAddressMap, + multiProvider: MultiProvider, +): WarpRouteDetails | undefined { + try { + const { + body, + origin: { to }, + originDomainId, + destinationDomainId, + recipient, + } = message; + + const originMetadata = multiProvider.tryGetChainMetadata(originDomainId); + const destinationMetadata = multiProvider.tryGetChainMetadata(destinationDomainId); + + if (!body || !originMetadata || !destinationMetadata) return undefined; + + const originTokenSymbol = getTokenSymbolFromWarpRouteChainAddressMap( + originMetadata, + to, + warpRouteChainAddressMap, + ); + const destinationTokenSymbol = getTokenSymbolFromWarpRouteChainAddressMap( + destinationMetadata, + recipient, + warpRouteChainAddressMap, + ); + + // If token symbols are not found with the addresses, it means the message + // is not a warp transfer between tokens known to the registry + if (!originTokenSymbol || !destinationTokenSymbol) return undefined; + + const parsedMessage = parseWarpRouteMessage(body); + const bytes = fromHexString(parsedMessage.recipient); + const address = bytesToProtocolAddress( + bytes, + destinationMetadata.protocol, + destinationMetadata.bech32Prefix, + ); + + return { + amount: fromWei(parsedMessage.amount.toString(), originMetadata.nativeToken?.decimals || 18), + endRecipient: address, + originTokenAddress: to, + originTokenSymbol: originTokenSymbol, + destinationTokenAddress: recipient, + destinationTokenSymbol: destinationTokenSymbol, + }; + } catch (err) { + logger.error('Error parsing warp route details:', err); + return undefined; + } +} diff --git a/src/features/messages/queries/parse.ts b/src/features/messages/queries/parse.ts index af981a9..fbe0671 100644 --- a/src/features/messages/queries/parse.ts +++ b/src/features/messages/queries/parse.ts @@ -1,18 +1,9 @@ -import { ChainMetadata, MultiProvider } from '@hyperlane-xyz/sdk'; - -import { - Message, - MessageStatus, - MessageStub, - WarpRouteChainAddressMap, - WarpRouteDetails, -} from '../../../types'; +import { MultiProvider } from '@hyperlane-xyz/sdk'; +import { Message, MessageStatus, MessageStub } from '../../../types'; import { logger } from '../../../utils/logger'; import { tryUtf8DecodeBytes } from '../../../utils/string'; import { DomainsEntry } from '../../chains/queries/fragments'; import { isPiChain } from '../../chains/utils'; - -import { fromWei, objKeys, parseWarpRouteMessage } from '@hyperlane-xyz/utils'; import { postgresByteaToAddress, postgresByteaToString, postgresByteaToTxHash } from './encoding'; import { MessageEntry, @@ -44,70 +35,6 @@ export function parseMessageQueryResult( return queryResult(multiProvider, scrapedChains, data, parseMessage); } -function getTokenSymbolFromWarpRouteChainAddressMap( - chainMetadata: ChainMetadata, - address: Address, - warpRouteChainAddressMap: WarpRouteChainAddressMap, -) { - const { name } = chainMetadata; - if (objKeys(warpRouteChainAddressMap).includes(name)) { - const chain = warpRouteChainAddressMap[name]; - if (objKeys(chain).includes(address)) { - return chain[address]; - } - } - - return undefined; -} - -export function parseWarpRouteDetails( - message: Message, - warpRouteChainAddressMap: WarpRouteChainAddressMap, -): WarpRouteDetails | undefined { - try { - const { - body, - origin: { to }, - totalPayment, - originMetadata, - destinationMetadata, - recipient, - } = message; - - if (!body || !originMetadata || !destinationMetadata) return undefined; - - const originTokenSymbol = getTokenSymbolFromWarpRouteChainAddressMap( - originMetadata, - to, - warpRouteChainAddressMap, - ); - const destinationTokenSymbol = getTokenSymbolFromWarpRouteChainAddressMap( - destinationMetadata, - recipient, - warpRouteChainAddressMap, - ); - - // If token symbols are not found with the addresses, it means the message is not a warp route transfer - if (!originTokenSymbol || !destinationTokenSymbol) return undefined; - - const parsedMessage = parseWarpRouteMessage(body); - const address = postgresByteaToAddress(parsedMessage.recipient, destinationMetadata); - - return { - amount: fromWei(parsedMessage.amount.toString(), originMetadata.nativeToken?.decimals || 18), - totalPayment: fromWei(totalPayment, originMetadata.nativeToken?.decimals || 18), - endRecipient: address, - originTokenAddress: to, - originTokenSymbol: originTokenSymbol, - destinationTokenAddress: recipient, - destinationTokenSymbol: destinationTokenSymbol, - }; - } catch (err) { - logger.error('Error parsing warp route details:', err); - return undefined; - } -} - function queryResult( multiProvider: MultiProvider, scrapedChains: DomainsEntry[], @@ -161,8 +88,6 @@ function parseMessageStub( } : undefined, isPiMsg, - originMetadata, - destinationMetadata, }; } catch (error) { logger.error('Error parsing message stub', error); @@ -224,8 +149,6 @@ function parseMessage( totalGasAmount: m.total_gas_amount.toString(), totalPayment: m.total_payment.toString(), numPayments: m.num_payments, - originMetadata, - destinationMetadata, }; } catch (error) { logger.error('Error parsing message', error); diff --git a/src/types.ts b/src/types.ts index f4881ad..176424e 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { ChainMap, ChainMetadata } from '@hyperlane-xyz/sdk'; +import { ChainMap } from '@hyperlane-xyz/sdk'; import type { providers } from 'ethers'; // TODO consider reconciling with SDK's MessageStatus @@ -44,8 +44,6 @@ export interface MessageStub { origin: MessageTxStub; destination?: MessageTxStub; isPiMsg?: boolean; - originMetadata?: ChainMetadata | null; - destinationMetadata?: ChainMetadata | null; } export interface Message extends MessageStub { @@ -66,7 +64,6 @@ export interface ExtendedLog extends providers.Log { export interface WarpRouteDetails { amount: string; - totalPayment: string; endRecipient: string; originTokenAddress: string; originTokenSymbol: string; diff --git a/src/utils/token.ts b/src/utils/token.ts new file mode 100644 index 0000000..ff7cb89 --- /dev/null +++ b/src/utils/token.ts @@ -0,0 +1,19 @@ +import { ChainMetadata } from '@hyperlane-xyz/sdk'; +import { objKeys } from '@hyperlane-xyz/utils'; +import { WarpRouteChainAddressMap } from '../types'; + +export function getTokenSymbolFromWarpRouteChainAddressMap( + chainMetadata: ChainMetadata, + address: Address, + warpRouteChainAddressMap: WarpRouteChainAddressMap, +) { + const { name } = chainMetadata; + if (objKeys(warpRouteChainAddressMap).includes(name)) { + const chain = warpRouteChainAddressMap[name]; + if (objKeys(chain).includes(address)) { + return chain[address]; + } + } + + return undefined; +} From c2b9a8aae809e654109e0c8384227d9b8328f155 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 5 Feb 2025 12:57:19 -0400 Subject: [PATCH 11/14] chore: get warp routes from npm package --- src/features/messages/MessageDetails.tsx | 2 +- .../messages/cards/WarpTransferDetailCard.tsx | 38 +++++++++-------- src/store.ts | 41 ++++++++----------- src/types.ts | 6 +-- src/utils/token.ts | 2 +- 5 files changed, 42 insertions(+), 47 deletions(-) diff --git a/src/features/messages/MessageDetails.tsx b/src/features/messages/MessageDetails.tsx index 3f29459..e9404a2 100644 --- a/src/features/messages/MessageDetails.tsx +++ b/src/features/messages/MessageDetails.tsx @@ -127,8 +127,8 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro blur={blur} /> {showTimeline && } - + ({ + const multiProvider = useMultiProvider(); + const { warpRouteChainAddressMap } = useStore((s) => ({ warpRouteChainAddressMap: s.warpRouteChainAddressMap, - multiProvider: s.multiProvider, })); const warpRouteDetails = parseWarpRouteDetails(message, warpRouteChainAddressMap, multiProvider); if (!warpRouteDetails) return null; - const { amount, destinationTokenAddress, endRecipient, originTokenAddress, originTokenSymbol } = - warpRouteDetails; + const { + amount, + destinationTokenAddress, + transferRecipient, + originTokenAddress, + originTokenSymbol, + } = warpRouteDetails; return ( @@ -69,11 +74,10 @@ export function WarpTransferDetailCard({ message, blur }: Props) { showCopy={true} blurValue={blur} /> - ()( logger.debug('Rehydration complete'); }) .catch((e) => logger.error('Error building MultiProvider', e)); - buildWarpRouteChainAddressMap(state.registry).then((warpRouteChainAddressMap) => { - state.setWarpRoutChainAddresseMap(warpRouteChainAddressMap); - }); + state.setWarpRoutChainAddresseMap(buildWarpRouteChainAddressMap()); }; }, }, @@ -129,21 +125,16 @@ async function buildMultiProvider( return { metadata: metadataWithLogos, multiProvider: new MultiProvider(mergedMetadata) }; } -export async function buildWarpRouteChainAddressMap( - registry: IRegistry, -): Promise { - try { - const warpRoutes = await registry.getWarpRoutes(); - return Object.values(warpRoutes).reduce((acc, { tokens }) => { - tokens.forEach(({ chainName, addressOrDenom, symbol }) => { - if (!acc[chainName]) { - acc[chainName] = {}; - } - acc[chainName][addressOrDenom] = symbol; - }); - return acc; - }, {}); - } catch { - return {}; - } +// TODO: Get the most up to date data from the registry instead of using the warpRouteConfigs +export function buildWarpRouteChainAddressMap(): WarpRouteChainAddressMap { + return Object.values(warpRouteConfigs).reduce((acc, { tokens }) => { + tokens.forEach((token) => { + const { chainName, addressOrDenom } = token; + if (!acc[chainName]) { + acc[chainName] = {}; + } + acc[chainName][addressOrDenom] = token; + }); + return acc; + }, {}); } diff --git a/src/types.ts b/src/types.ts index 176424e..83e344b 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,4 +1,4 @@ -import { ChainMap } from '@hyperlane-xyz/sdk'; +import { ChainMap, TokenArgs } from '@hyperlane-xyz/sdk'; import type { providers } from 'ethers'; // TODO consider reconciling with SDK's MessageStatus @@ -64,11 +64,11 @@ export interface ExtendedLog extends providers.Log { export interface WarpRouteDetails { amount: string; - endRecipient: string; + transferRecipient: string; originTokenAddress: string; originTokenSymbol: string; destinationTokenAddress: string; destinationTokenSymbol: string; } -export type WarpRouteChainAddressMap = ChainMap>; +export type WarpRouteChainAddressMap = ChainMap>; diff --git a/src/utils/token.ts b/src/utils/token.ts index ff7cb89..d35eff1 100644 --- a/src/utils/token.ts +++ b/src/utils/token.ts @@ -2,7 +2,7 @@ import { ChainMetadata } from '@hyperlane-xyz/sdk'; import { objKeys } from '@hyperlane-xyz/utils'; import { WarpRouteChainAddressMap } from '../types'; -export function getTokenSymbolFromWarpRouteChainAddressMap( +export function getTokenFromWarpRouteChainAddressMap( chainMetadata: ChainMetadata, address: Address, warpRouteChainAddressMap: WarpRouteChainAddressMap, From 2118745aa2c3f76a3df2fb6492a5f75b9f13ee2d Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 5 Feb 2025 13:05:20 -0400 Subject: [PATCH 12/14] chore: upgrade hyperlane packages --- package.json | 8 ++++---- yarn.lock | 58 ++++++++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 629593d..0fb03c9 100644 --- a/package.json +++ b/package.json @@ -5,10 +5,10 @@ "author": "J M Rossy", "dependencies": { "@headlessui/react": "^2.2.0", - "@hyperlane-xyz/registry": "7.1.0", - "@hyperlane-xyz/sdk": "8.4.0", - "@hyperlane-xyz/utils": "8.4.0", - "@hyperlane-xyz/widgets": "8.4.0", + "@hyperlane-xyz/registry": "9.0.0", + "@hyperlane-xyz/sdk": "8.5.0", + "@hyperlane-xyz/utils": "8.5.0", + "@hyperlane-xyz/widgets": "8.5.0", "@tanstack/react-query": "^5.62.3", "bignumber.js": "^9.1.2", "buffer": "^6.0.3", diff --git a/yarn.lock b/yarn.lock index c1df87d..ef66033 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2365,13 +2365,13 @@ __metadata: languageName: node linkType: hard -"@hyperlane-xyz/core@npm:5.11.0": - version: 5.11.0 - resolution: "@hyperlane-xyz/core@npm:5.11.0" +"@hyperlane-xyz/core@npm:5.11.1": + version: 5.11.1 + resolution: "@hyperlane-xyz/core@npm:5.11.1" dependencies: "@arbitrum/nitro-contracts": "npm:^1.2.1" "@eth-optimism/contracts": "npm:^0.6.0" - "@hyperlane-xyz/utils": "npm:8.4.0" + "@hyperlane-xyz/utils": "npm:8.5.0" "@layerzerolabs/lz-evm-oapp-v2": "npm:2.0.2" "@openzeppelin/contracts": "npm:^4.9.3" "@openzeppelin/contracts-upgradeable": "npm:^4.9.3" @@ -2380,7 +2380,7 @@ __metadata: "@ethersproject/abi": "*" "@ethersproject/providers": "*" "@types/sinon-chai": "*" - checksum: 10/5aea5819922bddbea1a2cb94316aa7b8c1f8f8f54546bc897db1a59455d6d6390cfaea3ce7ec00c3e33efefa60a5781fed35a2dbade99693d76c684401d6645e + checksum: 10/9f495872e23d85d89e659119857e7fae529ee39e1df21ac1007c96c17556c965869cf8ce0969a7b8459ebad9addca7d78ebda895a87c0abe2321b46c9fb89f13 languageName: node linkType: hard @@ -2389,10 +2389,10 @@ __metadata: resolution: "@hyperlane-xyz/explorer@workspace:." dependencies: "@headlessui/react": "npm:^2.2.0" - "@hyperlane-xyz/registry": "npm:7.1.0" - "@hyperlane-xyz/sdk": "npm:8.4.0" - "@hyperlane-xyz/utils": "npm:8.4.0" - "@hyperlane-xyz/widgets": "npm:8.4.0" + "@hyperlane-xyz/registry": "npm:9.0.0" + "@hyperlane-xyz/sdk": "npm:8.5.0" + "@hyperlane-xyz/utils": "npm:8.5.0" + "@hyperlane-xyz/widgets": "npm:8.5.0" "@tanstack/eslint-plugin-query": "npm:^5.28.6" "@tanstack/react-query": "npm:^5.62.3" "@types/jest": "npm:^29.5.3" @@ -2432,27 +2432,27 @@ __metadata: languageName: unknown linkType: soft -"@hyperlane-xyz/registry@npm:7.1.0": - version: 7.1.0 - resolution: "@hyperlane-xyz/registry@npm:7.1.0" +"@hyperlane-xyz/registry@npm:9.0.0": + version: 9.0.0 + resolution: "@hyperlane-xyz/registry@npm:9.0.0" dependencies: yaml: "npm:2.4.5" zod: "npm:^3.21.2" - checksum: 10/94b594ecd5734bc564e1a9ad220f4e5c9f04a98cd768cd4472afbaffe91009ae0680b8c4ffb01c13dbe913030dd730b22d5a73d7bfc88d6405df1e9f842ef939 + checksum: 10/b58eddfcb8ff7b165f902811831a49137a778c262822437523bb95d1ce8d318ad3918b7c647fe89e7d9270c8533c6c8ad42866cbf0971b18950abf55367edcd9 languageName: node linkType: hard -"@hyperlane-xyz/sdk@npm:8.4.0": - version: 8.4.0 - resolution: "@hyperlane-xyz/sdk@npm:8.4.0" +"@hyperlane-xyz/sdk@npm:8.5.0": + version: 8.5.0 + resolution: "@hyperlane-xyz/sdk@npm:8.5.0" dependencies: "@arbitrum/sdk": "npm:^4.0.0" "@aws-sdk/client-s3": "npm:^3.577.0" "@chain-registry/types": "npm:^0.50.14" "@cosmjs/cosmwasm-stargate": "npm:^0.32.4" "@cosmjs/stargate": "npm:^0.32.4" - "@hyperlane-xyz/core": "npm:5.11.0" - "@hyperlane-xyz/utils": "npm:8.4.0" + "@hyperlane-xyz/core": "npm:5.11.1" + "@hyperlane-xyz/utils": "npm:8.5.0" "@safe-global/api-kit": "npm:1.3.0" "@safe-global/protocol-kit": "npm:1.3.0" "@safe-global/safe-deployments": "npm:1.37.23" @@ -2468,13 +2468,13 @@ __metadata: peerDependencies: "@ethersproject/abi": "*" "@ethersproject/providers": "*" - checksum: 10/34c787a620f8cd75f9ef8db11e0844ea48ef80f15eb3f3d8b39c4fcb41a1a3537f7976de07d11b798229132194a62cfabd415d415b67a4453b27e64d21e9a197 + checksum: 10/d704bc1078c3a349ffc621ab0174aa36b42f86bf224ba2c3b7e65ba1348ce66b587f371c0d9bb775626cfcec663dccf9128b16ce528349e26424ee8ee05117f0 languageName: node linkType: hard -"@hyperlane-xyz/utils@npm:8.4.0": - version: 8.4.0 - resolution: "@hyperlane-xyz/utils@npm:8.4.0" +"@hyperlane-xyz/utils@npm:8.5.0": + version: 8.5.0 + resolution: "@hyperlane-xyz/utils@npm:8.5.0" dependencies: "@cosmjs/encoding": "npm:^0.32.4" "@solana/web3.js": "npm:^1.95.4" @@ -2483,18 +2483,18 @@ __metadata: lodash-es: "npm:^4.17.21" pino: "npm:^8.19.0" yaml: "npm:2.4.5" - checksum: 10/9d1209336e68bd6e5d0b524310af9b8ab97903b1604bc00c481391f5a0de9b41fa266a04c8fe3ecc43f76e44548b538e6faca6ddc217de418f6f053c24d04f2d + checksum: 10/7f1711cdb5a695719a472d1215780685433ef0a8de37cddb78d5ffe255606bb85913097b594d2ad1db4210342eab9d4ad37842eeb2f90fe8f3c0c08cb52b391d languageName: node linkType: hard -"@hyperlane-xyz/widgets@npm:8.4.0": - version: 8.4.0 - resolution: "@hyperlane-xyz/widgets@npm:8.4.0" +"@hyperlane-xyz/widgets@npm:8.5.0": + version: 8.5.0 + resolution: "@hyperlane-xyz/widgets@npm:8.5.0" dependencies: "@cosmos-kit/react": "npm:^2.18.0" "@headlessui/react": "npm:^2.1.8" - "@hyperlane-xyz/sdk": "npm:8.4.0" - "@hyperlane-xyz/utils": "npm:8.4.0" + "@hyperlane-xyz/sdk": "npm:8.5.0" + "@hyperlane-xyz/utils": "npm:8.5.0" "@interchain-ui/react": "npm:^1.23.28" "@rainbow-me/rainbowkit": "npm:^2.2.0" "@solana/wallet-adapter-react": "npm:^0.15.32" @@ -2507,7 +2507,7 @@ __metadata: peerDependencies: react: ^18 react-dom: ^18 - checksum: 10/8c58c21e1fda6e372c2aa9d4add5e408bf8cc6ce944f1305cf29c4ac0804fce68871718ffdcb263f5bb4444a1cb0944f07a53f6acc77e12fb16c4bdc4212a397 + checksum: 10/2c52080dfb76e8f5158324e9f71bd4f11abaf0f52231a6c925fd92625345836ed0725c836a09a7e8ab2d903da87797ae4909e7d41ec2e151542de10da2ab87e1 languageName: node linkType: hard From 0284be093573839822f17db5dbf50f3601fe82df Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 5 Feb 2025 13:09:59 -0400 Subject: [PATCH 13/14] chore: refactor condition --- src/store.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/store.ts b/src/store.ts index a71125c..fd3634f 100644 --- a/src/store.ts +++ b/src/store.ts @@ -130,9 +130,7 @@ export function buildWarpRouteChainAddressMap(): WarpRouteChainAddressMap { return Object.values(warpRouteConfigs).reduce((acc, { tokens }) => { tokens.forEach((token) => { const { chainName, addressOrDenom } = token; - if (!acc[chainName]) { - acc[chainName] = {}; - } + acc[chainName] ||= {}; acc[chainName][addressOrDenom] = token; }); return acc; From 068150412dad0ae01e8025285af46816708c5fb5 Mon Sep 17 00:00:00 2001 From: Xaroz Date: Wed, 5 Feb 2025 13:13:10 -0400 Subject: [PATCH 14/14] chore: more clean up --- src/features/messages/MessageDetails.tsx | 11 ++++------- ...sferDetailCard.tsx => WarpTransferDetailsCard.tsx} | 2 +- 2 files changed, 5 insertions(+), 8 deletions(-) rename src/features/messages/cards/{WarpTransferDetailCard.tsx => WarpTransferDetailsCard.tsx} (98%) diff --git a/src/features/messages/MessageDetails.tsx b/src/features/messages/MessageDetails.tsx index e9404a2..688159e 100644 --- a/src/features/messages/MessageDetails.tsx +++ b/src/features/messages/MessageDetails.tsx @@ -1,9 +1,8 @@ +import { toTitleCase, trimToLength } from '@hyperlane-xyz/utils'; +import { SpinnerIcon } from '@hyperlane-xyz/widgets'; import Image from 'next/image'; import { useEffect } from 'react'; import { toast } from 'react-toastify'; - -import { toTitleCase, trimToLength } from '@hyperlane-xyz/utils'; - import { Card } from '../../components/layout/Card'; import CheckmarkIcon from '../../images/icons/checkmark-circle.svg'; import { useMultiProvider, useStore } from '../../store'; @@ -12,15 +11,13 @@ import { logger } from '../../utils/logger'; import { getHumanReadableDuration } from '../../utils/time'; import { getChainDisplayName, isEvmChain } from '../chains/utils'; import { useMessageDeliveryStatus } from '../deliveryStatus/useMessageDeliveryStatus'; - -import { SpinnerIcon } from '@hyperlane-xyz/widgets'; import { ContentDetailsCard } from './cards/ContentDetailsCard'; import { GasDetailsCard } from './cards/GasDetailsCard'; import { IcaDetailsCard } from './cards/IcaDetailsCard'; import { IsmDetailsCard } from './cards/IsmDetailsCard'; import { TimelineCard } from './cards/TimelineCard'; import { DestinationTransactionCard, OriginTransactionCard } from './cards/TransactionCard'; -import { WarpTransferDetailCard } from './cards/WarpTransferDetailCard'; +import { WarpTransferDetailsCard } from './cards/WarpTransferDetailsCard'; import { useIsIcaMessage } from './ica'; import { usePiChainMessageQuery } from './pi-queries/usePiChainMessageQuery'; import { PLACEHOLDER_MESSAGE } from './placeholderMessages'; @@ -127,7 +124,7 @@ export function MessageDetails({ messageId, message: messageFromUrlParams }: Pro blur={blur} /> {showTimeline && } - + ({ warpRouteChainAddressMap: s.warpRouteChainAddressMap,