diff --git a/explorer/src/components/ExplorerQuery/ExplorerQuery.tsx b/explorer/src/components/ExplorerQuery/ExplorerQuery.tsx index bde8c576d..ebd217ac1 100644 --- a/explorer/src/components/ExplorerQuery/ExplorerQuery.tsx +++ b/explorer/src/components/ExplorerQuery/ExplorerQuery.tsx @@ -24,6 +24,23 @@ export interface VAA { EmitterAddress: string, Payload: string // base64 encoded byte array } +export interface TokenTransferPayload { + Amount: string + OriginAddress: string + OriginChain: string, + TargetAddress: string, + TargetChain: string, +} +export interface TransferDetails { + Amount: string, // "1530.000000", + Decimals: string, // "6", + NotionalUSDStr: string, // "1538.495460", + TokenPriceUSDStr: string, // "1.005553", + TransferTimestamp: string, // "2021-11-21 16:55:15 +0000 UTC", + OriginSymbol: string, + OriginName: string, + OriginTokenAddress: string, +} export interface BigTableMessage { InitiatingTxID?: string SignedVAABytes?: string // base64 encoded byte array @@ -32,6 +49,8 @@ export interface BigTableMessage { EmitterChain: keyof ChainIDs EmitterAddress: string Sequence: string + TokenTransferPayload?: TokenTransferPayload + TransferDetails?: TransferDetails } interface ExplorerQuery { diff --git a/explorer/src/components/ExplorerStats/utils.ts b/explorer/src/components/ExplorerStats/utils.ts index f45b23812..ae119d084 100644 --- a/explorer/src/components/ExplorerStats/utils.ts +++ b/explorer/src/components/ExplorerStats/utils.ts @@ -1,5 +1,6 @@ import { useContext } from 'react' import { Bech32, fromHex } from "@cosmjs/encoding" +import { PublicKey } from '@solana/web3.js'; import { chainEnums, ChainID, chainIDs } from '~/utils/misc/constants'; import { ActiveNetwork, NetworkContext } from "~/components/NetworkSelect"; @@ -44,13 +45,17 @@ const getNativeAddress = (chainId: number, emitterAddress: string, activeNetwork } const chainName = chainEnums[chainId].toLowerCase() - // not sure how to do this programattically, so use the "chains" map + // use the "chains" map of hex: nativeAdress first if (emitterAddress in activeNetwork.chains[chainName]) { let desc = activeNetwork.chains[chainName][emitterAddress] if (desc in activeNetwork.chains[chainName]) { // lookup the contract address nativeAddress = activeNetwork.chains[chainName][desc] } + } else { + let hex = fromHex(emitterAddress) + let pubKey = new PublicKey(hex) + nativeAddress = pubKey.toString() } } return nativeAddress @@ -136,4 +141,4 @@ const chainColors: { [chain: string]: string } = { "5": "hsl(271, 100%, 61%)", } -export { makeDate, makeGroupName, chainColors, truncateAddress, contractNameFormatter, nativeExplorerContractUri, nativeExplorerTxUri } +export { makeDate, makeGroupName, chainColors, truncateAddress, contractNameFormatter, nativeExplorerContractUri, nativeExplorerTxUri, getNativeAddress } diff --git a/explorer/src/components/ExplorerSummary/ExplorerSummary.tsx b/explorer/src/components/ExplorerSummary/ExplorerSummary.tsx index dfa78e83d..51e19ee99 100644 --- a/explorer/src/components/ExplorerSummary/ExplorerSummary.tsx +++ b/explorer/src/components/ExplorerSummary/ExplorerSummary.tsx @@ -8,9 +8,9 @@ import ReactTimeAgo from 'react-time-ago' import { titleStyles } from '~/styles'; import { CloseOutlined, ReloadOutlined } from '@ant-design/icons'; import { Link } from 'gatsby'; -import { contractNameFormatter, nativeExplorerContractUri, nativeExplorerTxUri } from '../ExplorerStats/utils'; +import { contractNameFormatter, getNativeAddress, nativeExplorerContractUri, nativeExplorerTxUri, truncateAddress } from '../ExplorerStats/utils'; import { OutboundLink } from 'gatsby-plugin-google-gtag'; -import { chainIDs } from '~/utils/misc/constants'; +import { ChainID, chainIDs } from '~/utils/misc/constants'; import { hexToNativeString } from '@certusone/wormhole-sdk'; interface SummaryProps { @@ -23,13 +23,14 @@ interface SummaryProps { lastFetched?: number refetch: () => void } +const textStyles = { fontSize: 16, margin: '6px 0' } const Summary = (props: SummaryProps) => { const intl = useIntl() const { SignedVAA, ...message } = props.message - const { EmitterChain, EmitterAddress, InitiatingTxID } = message + const { EmitterChain, EmitterAddress, InitiatingTxID, TokenTransferPayload, TransferDetails } = message // get chainId from chain name let chainId = chainIDs[EmitterChain] @@ -66,6 +67,59 @@ const Summary = (props: SummaryProps) => { )} +
+ {EmitterChain && EmitterAddress && nativeExplorerContractUri(chainId, EmitterAddress) ? +
+ This message was sent to the {ChainID[chainId]} + + {contractNameFormatter(EmitterAddress, chainId)} + + contract + {transactionId && + <> + , transaction + + {truncateAddress(transactionId)} + + + } . +
: null} + {TokenTransferPayload && + TokenTransferPayload.TargetAddress && + TransferDetails && + nativeExplorerContractUri(Number(TokenTransferPayload.TargetChain), TokenTransferPayload.TargetAddress) ? +
+ This message is a token transfer, moving {Math.round(Number(TransferDetails.Amount) * 100) / 100}{` `} + {!["UST", "LUNA"].includes(TransferDetails.OriginSymbol) ? + {TransferDetails.OriginSymbol} + : TransferDetails.OriginSymbol} + {` `}from {ChainID[chainId]}, to {ChainID[Number(TokenTransferPayload.TargetChain)]}, to address + + {truncateAddress(getNativeAddress(Number(TokenTransferPayload.TargetChain), TokenTransferPayload.TargetAddress))} + +
: null} +
+ Raw message data:
 {
 
                 ) : null}
             
-
- {EmitterChain && EmitterAddress && nativeExplorerContractUri(chainId, EmitterAddress) ? - - {'View "'}{contractNameFormatter(EmitterAddress, chainId)}{'" contract on native explorer'} - :
} - {transactionId && EmitterChain ? - - {'View transaction "'}{transactionId}{'" on native explorer'} - :
} -
) }